From 2b2c3a79c495d876feab1ab3d0d0e9526f454e8a Mon Sep 17 00:00:00 2001 From: Will Chan Date: Tue, 30 Jan 2024 15:48:40 -0800 Subject: [PATCH 001/774] fixed summarize-syntax to actually work on Mac (FreeBSD) --- examples/summarize-syntax.gpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/summarize-syntax.gpt b/examples/summarize-syntax.gpt index 76d88e62..9f5fb5f2 100644 --- a/examples/summarize-syntax.gpt +++ b/examples/summarize-syntax.gpt @@ -8,7 +8,7 @@ description: list all gpt files #!/bin/bash -find -name '*.gpt' +find . -name '*.gpt' --- name: cat From 6887aebaacded39e1ad894dac03ff04e5467541a Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 30 Jan 2024 17:32:25 -0700 Subject: [PATCH 002/774] feat: Implement no-cache option and refactor display logic Introducing the ability to disable caching and overhauled the display logic for better status tracking during tool execution. Added a display module to better manage state and output during runs, and implemented a no-cache option to allow runs without utilizing the cache layer. Additionally, refactored context management within the execution engine to handle unique execution IDs. The go.mod changes include updating dependencies and adding the `golang.org/x/term` package for better terminal interaction. --- examples/git-commit.gpt | 17 ++++ go.mod | 4 +- go.sum | 4 +- pkg/cache/cache.go | 13 ++- pkg/cli/root.go | 10 +- pkg/engine/engine.go | 23 ++++- pkg/openai/client.go | 25 +++-- pkg/runner/display.go | 204 ++++++++++++++++++++++++++++++++++++++++ pkg/runner/runner.go | 172 +++++++++++++++++++-------------- pkg/types/completion.go | 23 +---- 10 files changed, 382 insertions(+), 113 deletions(-) create mode 100644 examples/git-commit.gpt create mode 100644 pkg/runner/display.go diff --git a/examples/git-commit.gpt b/examples/git-commit.gpt new file mode 100644 index 00000000..256c8afd --- /dev/null +++ b/examples/git-commit.gpt @@ -0,0 +1,17 @@ +tools: gitstatus + +Create well formed git commit message based of off the currently stated file +contents. The message should convey why something was changed and not what +changed. Use the well known format that has the prefix chore, fix, etc. + +Only include changed to *.go files and any change to the go.mod file. Exclude +the go.sum file. + +Do not use markdown format for the output. + +--- +name: gitstatus + +#!/bin/sh + +git diff --staged diff --git a/go.mod b/go.mod index 1bb8866b..239ae796 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/spf13/cobra v1.8.0 golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc golang.org/x/sync v0.5.0 + golang.org/x/term v0.16.0 ) require ( @@ -18,7 +19,7 @@ require ( atomicgo.dev/keyboard v0.2.9 // indirect atomicgo.dev/schedule v0.1.0 // indirect github.com/bombsimon/logrusr/v4 v4.0.0 // indirect - github.com/containerd/console v1.0.3 // indirect + github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/google/go-containerregistry v0.16.1 // indirect @@ -37,7 +38,6 @@ require ( github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.16.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 99298122..a700e895 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,9 @@ github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/bombsimon/logrusr/v4 v4.0.0 h1:Pm0InGphX0wMhPqC02t31onlq9OVyJ98eP/Vh63t1Oo= github.com/bombsimon/logrusr/v4 v4.0.0/go.mod h1:pjfHC5e59CvjTBIU3V3sGhFWFAnsnhOR03TRc6im0l8= -github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -159,6 +160,7 @@ golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 63ec43a2..40b97453 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -12,9 +12,16 @@ import ( ) type Client struct { - dir string + dir string + noop bool } +func NoCache() *Client { + return &Client{ + noop: true, + } + +} func New() (*Client, error) { dir := filepath.Join(xdg.CacheHome, version.ProgramName) if err := os.MkdirAll(dir, 0755); err != nil { @@ -26,14 +33,14 @@ func New() (*Client, error) { } func (c *Client) Store(ctx context.Context, key string, content []byte) error { - if c == nil { + if c == nil || c.noop { return nil } return os.WriteFile(filepath.Join(c.dir, key), content, 0644) } func (c *Client) Get(ctx context.Context, key string) ([]byte, bool, error) { - if c == nil { + if c == nil || c.noop { return nil, false, nil } data, err := os.ReadFile(filepath.Join(c.dir, key)) diff --git a/pkg/cli/root.go b/pkg/cli/root.go index 2b3db34f..f768159d 100644 --- a/pkg/cli/root.go +++ b/pkg/cli/root.go @@ -10,9 +10,11 @@ import ( "github.com/acorn-io/gptscript/pkg/runner" "github.com/acorn-io/gptscript/pkg/version" "github.com/spf13/cobra" + "golang.org/x/term" ) type Root struct { + runner.Options } func New() *cobra.Command { @@ -37,7 +39,13 @@ func (r *Root) Run(cmd *cobra.Command, args []string) error { return err } - runner, err := runner.New() + if !r.Quiet { + if !term.IsTerminal(int(os.Stdout.Fd())) { + r.Quiet = true + } + } + + runner, err := runner.New(r.Options) if err != nil { return err } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 553355bf..1fed075b 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -10,6 +10,7 @@ import ( "sort" "strings" "sync" + "sync/atomic" "github.com/acorn-io/gptscript/pkg/openai" "github.com/acorn-io/gptscript/pkg/types" @@ -54,10 +55,24 @@ type CallResult struct { } type Context struct { - Ctx context.Context - Parent *Context - Tool types.Tool - Tools []types.Tool + ID string `json:"id,omitempty"` + Ctx context.Context `json:"-"` + Parent *Context `json:"parent,omitempty"` + Tool types.Tool `json:"tool,omitempty"` + Tools map[string]types.Tool `json:"tools,omitempty"` +} + +var execID int32 + +func NewContext(ctx context.Context, parent *Context, tool types.Tool, tools map[string]types.Tool) Context { + callCtx := Context{ + ID: fmt.Sprint(atomic.AddInt32(&execID, 1)), + Ctx: ctx, + Parent: parent, + Tool: tool, + Tools: tools, + } + return callCtx } func (c *Context) getTool(name string) (types.Tool, error) { diff --git a/pkg/openai/client.go b/pkg/openai/client.go index c07d5d06..895624b7 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -311,6 +311,16 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, cacheKey := c.cacheKey(request) request.Stream = true + msg := "" + if len(request.Messages) > 0 { + msg = request.Messages[len(request.Messages)-1].Content + } + + partial <- types.CompletionMessage{ + Role: types.CompletionMessageRoleTypeAssistant, + Content: types.Text("Waiting for model response...\n" + msg), + } + slog.Debug("calling openai", "message", request.Messages) stream, err := c.c.CreateChatCompletionStream(ctx, request) if err != nil { @@ -318,6 +328,7 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, } defer stream.Close() + var partialMessage types.CompletionMessage for { response, err := stream.Recv() if err == io.EOF { @@ -325,14 +336,12 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, } else if err != nil { return nil, err } - if len(response.Choices) > 0 { - slog.Debug("stream", "content", response.Choices[0].Delta.Content) - if partial != nil { - partial <- types.CompletionMessage{ - Role: types.CompletionMessageRoleType(response.Choices[0].Delta.Role), - Content: types.Text(response.Choices[0].Delta.Content), - } - } + slog.Debug("stream", "content", response.Choices[0].Delta.Content) + if partial != nil { + partialMessage = appendMessage(partialMessage, response) + //d, _ := json.MarshalIndent(partialMessage, "", " ") + //fmt.Println(string(d)) + partial <- partialMessage } responses = append(responses, response) } diff --git a/pkg/runner/display.go b/pkg/runner/display.go new file mode 100644 index 00000000..65a7ac9c --- /dev/null +++ b/pkg/runner/display.go @@ -0,0 +1,204 @@ +package runner + +import ( + "context" + "encoding/json" + "io" + "os" + "strings" + "time" + + "github.com/acorn-io/gptscript/pkg/engine" + "github.com/pterm/pterm" +) + +type display struct { + progress chan Event + states []state + done chan struct{} + area *pterm.AreaPrinter + quiet bool +} + +func newDisplay(quiet bool) *display { + return &display{ + quiet: quiet, + } +} + +func (d *display) Start(ctx context.Context) (err error) { + if !d.quiet { + d.area, err = pterm.DefaultArea. + //WithFullscreen(true). + WithRemoveWhenDone(true). + Start("Starting...") + if err != nil { + return err + } + } + + d.progress = make(chan Event) + d.done = make(chan struct{}) + go func() { + t := time.NewTicker(time.Second) + defer t.Stop() + for { + select { + case <-t.C: + d.print() + case <-d.done: + return + } + } + }() + go func() { + for msg := range d.progress { + d.addEvent(msg) + } + close(d.done) + }() + return nil +} + +func (d *display) Dump(out io.Writer) error { + enc := json.NewEncoder(out) + enc.SetIndent("", " ") + return enc.Encode(struct { + State []state `json:"state,omitempty"` + }{ + State: d.states, + }) +} + +func (d *display) Stop() error { + close(d.progress) + <-d.done + if d.area != nil { + if err := d.area.Stop(); err != nil { + return err + } + } + + return nil +} + +func splitCount(line string, length int) (head, tail string) { + if len(line) < length { + return line, "" + } + return line[:length], line[length:] +} + +func multiLineWrite(out io.StringWriter, prefix, lines string) { + if lines == "" { + _, _ = out.WriteString("\n") + } + width := pterm.GetTerminalWidth() + for _, line := range strings.Split(lines, "\n") { + line = prefix + line + for { + head, tail := splitCount(line, width) + _, _ = out.WriteString(head) + _, _ = out.WriteString("\n") + + if tail == "" { + break + } + line = prefix + tail + } + } +} + +func (d *display) printState(s state, depth int) string { + if !s.Running { + return "" + } + + buf := &strings.Builder{} + prefix := strings.Repeat(" ", depth) + inPrefix := prefix + " |<- " + outPrefix := prefix + " |-> " + + buf.WriteString(prefix) + name := s.Context.Tool.Name + if name == "" { + name = "main" + } + buf.WriteString("(running ") + buf.WriteString(name) + buf.WriteString(")\n") + if s.Input != "" { + multiLineWrite(buf, inPrefix, "args: "+s.Input) + } + + for _, state := range d.states { + if state.Context != nil && state.Context.Parent != nil && state.Context.Parent.ID == s.Context.ID { + buf.WriteString(d.printState(state, depth+1)) + } + } + + if len(s.Input) > 0 && len(s.Output) > 0 { + multiLineWrite(buf, outPrefix, "---") + } + + multiLineWrite(buf, outPrefix, s.Output) + + return buf.String() +} + +func (d *display) print() { + if d.quiet { + return + } + d.area.Update(d.String() + "\n") +} + +func (d *display) String() string { + buf := strings.Builder{} + if len(d.states) > 0 { + buf.WriteString(d.printState(d.states[0], 0)) + } + + return buf.String() +} + +func (d *display) addEvent(msg Event) { + found := false + for i, state := range d.states { + if state.Context.ID != msg.Context.ID { + continue + } + found = true + switch msg.Type { + case EventTypeUpdate: + state.Output = msg.Content + case EventTypeStop: + state.Running = false + state.Output = msg.Content + state.End = msg.Time + } + d.states[i] = state + } + if !found && msg.Type == EventTypeStart { + d.states = append(d.states, state{ + Context: msg.Context, + Running: true, + Start: msg.Time, + Input: msg.Content, + }) + } else if !found { + enc := json.NewEncoder(os.Stderr) + enc.SetIndent("", " ") + enc.Encode(msg) + panic("why?") + } +} + +type state struct { + Context *engine.Context `json:"context,omitempty"` + Running bool `json:"running,omitempty"` + Start time.Time `json:"start,omitempty"` + End time.Time `json:"end,omitempty"` + Input string `json:"input,omitempty"` + Output string `json:"output,omitempty"` +} diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 30062ddd..bc5ef88b 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -2,115 +2,135 @@ package runner import ( "context" - "fmt" - "strings" + "os" "sync" + "time" "github.com/acorn-io/gptscript/pkg/cache" "github.com/acorn-io/gptscript/pkg/engine" "github.com/acorn-io/gptscript/pkg/openai" "github.com/acorn-io/gptscript/pkg/types" - "github.com/pterm/pterm" "golang.org/x/sync/errgroup" ) +type Options struct { + Quiet bool `usage:"Do not print status" short:"q"` + DumpState string `usage:"Dump the internal execution state to a file"` + Cache *bool `usage:"Disable caching" default:"true"` +} + +func complete(opts ...Options) (result Options) { + for _, opt := range opts { + if opt.DumpState != "" { + result.DumpState = opt.DumpState + } + if opt.Quiet { + result.Quiet = true + } + if opt.Cache != nil { + result.Cache = opt.Cache + } + } + if result.Cache == nil { + result.Cache = &[]bool{true}[0] + } + return +} + type Runner struct { - Quiet bool - c *openai.Client - mw pterm.MultiPrinter + Quiet bool + c *openai.Client + display *display + dumpState string } -func New() (*Runner, error) { - cache, err := cache.New() - if err != nil { - return nil, err +func New(opts ...Options) (*Runner, error) { + opt := complete(opts...) + + cacheBackend := cache.NoCache() + if *opt.Cache { + var err error + cacheBackend, err = cache.New() + if err != nil { + return nil, err + } } - c, err := openai.NewClient(cache) + + c, err := openai.NewClient(cacheBackend) if err != nil { return nil, err } return &Runner{ - c: c, - mw: pterm.DefaultMultiPrinter, + c: c, + display: newDisplay(opt.Quiet), + dumpState: opt.DumpState, }, nil } func (r *Runner) Run(ctx context.Context, tool types.Tool, toolSet types.ToolSet, input string) (string, error) { - progress := make(chan types.CompletionMessage) - go func() { - for next := range progress { - fmt.Print(next.String()) + if err := r.display.Start(ctx); err != nil { + return "", err + } + + defer func() { + _ = r.display.Stop() + if r.dumpState != "" { + f, err := os.Create(r.dumpState) + if err == nil { + r.display.Dump(f) + f.Close() + } } - fmt.Println() }() - if !r.Quiet { - r.mw.Start() - defer func() { - r.mw.Stop() - fmt.Println() - }() - } - - return r.call(ctx, nil, tool, toolSet, input) + callCtx := engine.NewContext(ctx, nil, tool, toolSet) + return r.call(callCtx, input) } -func prefix(parent *engine.Context) string { - if parent == nil { - return "" - } - return ".." + prefix(parent.Parent) +type Event struct { + Time time.Time + Context *engine.Context + Type EventType + Content string } -func infoMsg(prefix string, tool types.Tool, input, output string) string { - if len(input) > 20 { - input = input[:20] - } - prefix = fmt.Sprintf("%sCall (%s): %s -> ", prefix, tool.Name, input) - maxLen := pterm.GetTerminalWidth() - len(prefix) - 8 - str := fmt.Sprintf("%s", output) - if len(str) > maxLen && maxLen > 0 { - str = str[len(str)-maxLen:] - } +type EventType string - return strings.ReplaceAll(prefix+str, "\n", " ") -} +var ( + EventTypeStart = EventType("start") + EventTypeUpdate = EventType("progress") + EventTypeStop = EventType("stop") +) -func (r *Runner) call(ctx context.Context, parent *engine.Context, tool types.Tool, toolSet types.ToolSet, input string) (string, error) { - prefix := prefix(parent) - spinner, err := pterm.DefaultSpinner.WithWriter(r.mw.NewWriter()).Start(fmt.Sprintf("%sCall (%s): %s", prefix, tool.Name, input)) - if err != nil { - return "", err +func (r *Runner) call(callCtx engine.Context, input string) (string, error) { + progress := make(chan types.CompletionMessage) + + e := engine.Engine{ + Client: r.c, + Progress: progress, } - defer spinner.Stop() - progress := make(chan types.CompletionMessage) - progressBuffer := &strings.Builder{} wg := sync.WaitGroup{} wg.Add(1) - defer wg.Wait() - go func() { defer wg.Done() for message := range progress { - progressBuffer.WriteString(message.String()) - spinner.Info(infoMsg(prefix, tool, input, progressBuffer.String())) + r.display.progress <- Event{ + Time: time.Now(), + Context: &callCtx, + Type: EventTypeUpdate, + Content: message.String(), + } } }() + defer wg.Wait() defer close(progress) - e := engine.Engine{ - Client: r.c, - Progress: progress, - } - - callCtx := engine.Context{ - Ctx: ctx, - Parent: parent, - Tool: tool, - } - for _, toolName := range tool.Tools { - callCtx.Tools = append(callCtx.Tools, toolSet[toolName]) + r.display.progress <- Event{ + Time: time.Now(), + Context: &callCtx, + Type: EventTypeStart, + Content: input, } result, err := e.Start(callCtx, input) @@ -120,7 +140,12 @@ func (r *Runner) call(ctx context.Context, parent *engine.Context, tool types.To for { if result.Result != nil { - spinner.Info(infoMsg(prefix, tool, input, *result.Result)) + r.display.progress <- Event{ + Time: time.Now(), + Context: &callCtx, + Type: EventTypeStop, + Content: *result.Result, + } return *result.Result, nil } @@ -129,13 +154,14 @@ func (r *Runner) call(ctx context.Context, parent *engine.Context, tool types.To resultLock sync.Mutex ) - eg, subCtx := errgroup.WithContext(ctx) + eg, subCtx := errgroup.WithContext(callCtx.Ctx) for id, call := range result.Calls { id := id call := call - tool := toolSet[call.ToolName] + callCtx := engine.NewContext(subCtx, &callCtx, callCtx.Tools[call.ToolName], callCtx.Tools) + callCtx.ID = id eg.Go(func() error { - result, err := r.call(subCtx, &callCtx, tool, toolSet, call.Input) + result, err := r.call(callCtx, call.Input) if err != nil { return err } @@ -155,7 +181,7 @@ func (r *Runner) call(ctx context.Context, parent *engine.Context, tool types.To return "", err } - result, err = e.Continue(ctx, result.State, callResults...) + result, err = e.Continue(callCtx.Ctx, result.State, callResults...) if err != nil { return "", err } diff --git a/pkg/types/completion.go b/pkg/types/completion.go index 3c2cdfa4..f36ead46 100644 --- a/pkg/types/completion.go +++ b/pkg/types/completion.go @@ -67,22 +67,11 @@ func Text(text string) []ContentPart { } func (in CompletionMessage) String() string { - if !in.HasContent() { - return "" - } buf := strings.Builder{} - if in.Role == CompletionMessageRoleTypeUser { - buf.WriteString("input -> ") - } else if in.Role == CompletionMessageRoleTypeTool && in.ToolCall != nil { - buf.WriteString(fmt.Sprintf("tool return %s -> ", in.ToolCall.Function.Name)) - } - for i, content := range in.Content { - if i > 0 { - buf.WriteString("\n -> ") - } + for _, content := range in.Content { buf.WriteString(content.Text) if content.ToolCall != nil { - buf.WriteString(fmt.Sprintf("tool call %s -> %s", content.ToolCall.Function.Name, content.ToolCall.Function.Arguments)) + buf.WriteString(fmt.Sprintf("tool call %s -> %s\n", content.ToolCall.Function.Name, content.ToolCall.Function.Arguments)) } if content.Image != nil { buf.WriteString("image: ") @@ -105,14 +94,6 @@ type ContentPart struct { Image *ImageURL `json:"image,omitempty"` } -func (in ContentPart) HasContent() bool { - return in.Text != "" || in.ToolCall != nil || in.Image != nil -} - -func (in CompletionMessage) HasContent() bool { - return len(in.Content) > 0 && in.Content[0].HasContent() -} - type ImageURLDetail string const ( From c0b8139a25bbe95f3cec632ad45ac74a0f69f5c5 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 30 Jan 2024 18:14:57 -0700 Subject: [PATCH 003/774] chore: Refactor CLI root and tool call sorting for code base improvements - Renamed Root struct to GPTScript and added Output field to streamline CLI usage. - Enhanced tool call sorting in the engine package for consistent ordering. - Implemented seed generation method for API call consistency in the OpenAI client module. This commit enhances the overall code quality and user experience by introducing better struct naming conventions, ensuring deterministic sorting of tool calls, and improving cache key generation for API responses. --- pkg/cli/root.go | 25 +++++++++++++++++-------- pkg/engine/engine.go | 21 ++++++++++++++------- pkg/openai/client.go | 21 ++++++++++++++++++++- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/pkg/cli/root.go b/pkg/cli/root.go index f768159d..617f82f0 100644 --- a/pkg/cli/root.go +++ b/pkg/cli/root.go @@ -13,21 +13,22 @@ import ( "golang.org/x/term" ) -type Root struct { +type GPTScript struct { runner.Options + Output string `usage:"Save output to a file" short:"o"` } func New() *cobra.Command { - return cmd.Command(&Root{}) + return cmd.Command(&GPTScript{}) } -func (r *Root) Customize(cmd *cobra.Command) { +func (r *GPTScript) Customize(cmd *cobra.Command) { cmd.Use = version.ProgramName cmd.Args = cobra.MinimumNArgs(1) cmd.Flags().SetInterspersed(false) } -func (r *Root) Run(cmd *cobra.Command, args []string) error { +func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { in, err := os.Open(args[0]) if err != nil { return err @@ -55,9 +56,17 @@ func (r *Root) Run(cmd *cobra.Command, args []string) error { return err } - fmt.Print(s) - if !strings.HasSuffix(s, "\n") { - fmt.Println() + if r.Output != "" { + err = os.WriteFile(r.Output, []byte(s), 0644) + if err != nil { + return err + } + } else { + fmt.Print(s) + if !strings.HasSuffix(s, "\n") { + fmt.Println() + } } - return err + + return nil } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 1fed075b..54dd20bd 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -267,12 +267,12 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu } var ( - added bool - pendingIDs []string + added bool + pendingToolCalls []types.CompletionToolCall ) for id, pending := range state.Pending { - pendingIDs = append(pendingIDs, id) + pendingToolCalls = append(pendingToolCalls, pending) if _, ok := state.Results[id]; !ok { ret.Calls[id] = Call{ ToolName: pending.Function.Name, @@ -285,11 +285,18 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu return &ret, nil } - sort.Strings(pendingIDs) + sort.Slice(pendingToolCalls, func(i, j int) bool { + left := pendingToolCalls[i].Function.Name + pendingToolCalls[i].Function.Arguments + right := pendingToolCalls[j].Function.Name + pendingToolCalls[j].Function.Arguments + if left == right { + return pendingToolCalls[i].ID < pendingToolCalls[j].ID + } + return left < right + }) - for _, id := range pendingIDs { - pending := state.Pending[id] - if result, ok := state.Results[id]; ok { + for _, pending := range pendingToolCalls { + pending := pending + if result, ok := state.Results[pending.ID]; ok { added = true state.Completion.Messages = append(state.Completion.Messages, types.CompletionMessage{ Role: types.CompletionMessageRoleTypeTool, diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 895624b7..0e9a2c31 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -58,6 +58,25 @@ func (c *Client) cacheKey(request openai.ChatCompletionRequest) string { return hash.Encode(request) } +func (c *Client) seed(request openai.ChatCompletionRequest) int { + newRequest := request + newRequest.Messages = nil + + for _, msg := range request.Messages { + newMsg := msg + newMsg.ToolCalls = nil + newMsg.ToolCallID = "" + + for _, tool := range msg.ToolCalls { + tool.ID = "" + newMsg.ToolCalls = append(newMsg.ToolCalls, tool) + } + + newRequest.Messages = append(newRequest.Messages, newMsg) + } + return hash.Seed(newRequest) +} + func (c *Client) fromCache(ctx context.Context, messageRequest types.CompletionRequest, request openai.ChatCompletionRequest) (result []openai.ChatCompletionStreamResponse, _ bool, _ error) { if messageRequest.Cache != nil && !*messageRequest.Cache { return nil, false, nil @@ -210,7 +229,7 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } } - request.Seed = ptr(hash.Seed(request)) + request.Seed = ptr(c.seed(request)) response, ok, err := c.fromCache(ctx, messageRequest, request) if err != nil { return nil, err From ad5b8a1707c747f811d5ddea651ff67536fba3e4 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 30 Jan 2024 18:17:00 -0700 Subject: [PATCH 004/774] chore: add .gitignore to exclude binary and IDE folders To prevent accidental inclusion of binary and IDE-specific configuration files, a .gitignore file has been added to the repository. This ensures that build artifacts and development environment settings do not clutter the repository and affect other developers working on the project. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..9eb30257 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/bin +/.idea From afe765df0162cc3a4cfbc57a315e43d246ee816b Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 30 Jan 2024 18:44:42 -0700 Subject: [PATCH 005/774] Attempt to make CLI output clearer --- pkg/runner/display.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/pkg/runner/display.go b/pkg/runner/display.go index 65a7ac9c..165bc543 100644 --- a/pkg/runner/display.go +++ b/pkg/runner/display.go @@ -110,10 +110,6 @@ func multiLineWrite(out io.StringWriter, prefix, lines string) { } func (d *display) printState(s state, depth int) string { - if !s.Running { - return "" - } - buf := &strings.Builder{} prefix := strings.Repeat(" ", depth) inPrefix := prefix + " |<- " @@ -124,24 +120,34 @@ func (d *display) printState(s state, depth int) string { if name == "" { name = "main" } - buf.WriteString("(running ") + if s.Running { + buf.WriteString("(running ") + } else { + buf.WriteString("(done ") + } buf.WriteString(name) buf.WriteString(")\n") if s.Input != "" { multiLineWrite(buf, inPrefix, "args: "+s.Input) } + childRunning := false for _, state := range d.states { if state.Context != nil && state.Context.Parent != nil && state.Context.Parent.ID == s.Context.ID { + if state.Running { + childRunning = true + } buf.WriteString(d.printState(state, depth+1)) } } - if len(s.Input) > 0 && len(s.Output) > 0 { - multiLineWrite(buf, outPrefix, "---") - } + if depth == 0 && !childRunning { + if len(s.Input) > 0 && len(s.Output) > 0 { + multiLineWrite(buf, outPrefix, "---") + } - multiLineWrite(buf, outPrefix, s.Output) + multiLineWrite(buf, outPrefix, s.Output) + } return buf.String() } From 2873222998fbcb2ac27332ceceec12997f24a5d7 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 30 Jan 2024 18:53:44 -0700 Subject: [PATCH 006/774] More CLI output adjustments --- pkg/runner/display.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/pkg/runner/display.go b/pkg/runner/display.go index 165bc543..c8de3a04 100644 --- a/pkg/runner/display.go +++ b/pkg/runner/display.go @@ -110,6 +110,10 @@ func multiLineWrite(out io.StringWriter, prefix, lines string) { } func (d *display) printState(s state, depth int) string { + if !s.Running { + return "" + } + buf := &strings.Builder{} prefix := strings.Repeat(" ", depth) inPrefix := prefix + " |<- " @@ -122,13 +126,22 @@ func (d *display) printState(s state, depth int) string { } if s.Running { buf.WriteString("(running ") + buf.WriteString(name) + buf.WriteString(")\n") + if s.Input != "" { + multiLineWrite(buf, inPrefix, "args: "+s.Input) + } } else { buf.WriteString("(done ") - } - buf.WriteString(name) - buf.WriteString(")\n") - if s.Input != "" { - multiLineWrite(buf, inPrefix, "args: "+s.Input) + buf.WriteString(name) + buf.WriteString(") ") + buf.WriteString("args: ") + head, tail := splitCount(s.Input, 40) + buf.WriteString(head) + if tail != "" { + buf.WriteString("...") + } + buf.WriteString("\n") } childRunning := false From 626ec974ca461c95ef63ca982a7a326c4afd869a Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 30 Jan 2024 19:03:28 -0700 Subject: [PATCH 007/774] Reorder waiting message --- pkg/openai/client.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 0e9a2c31..c19208a7 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -333,11 +333,14 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, msg := "" if len(request.Messages) > 0 { msg = request.Messages[len(request.Messages)-1].Content + if msg != "" { + msg = "Sent content:\n\n" + msg + "\n" + } } partial <- types.CompletionMessage{ Role: types.CompletionMessageRoleTypeAssistant, - Content: types.Text("Waiting for model response...\n" + msg), + Content: types.Text(msg + "Waiting for model response..."), } slog.Debug("calling openai", "message", request.Messages) From 4a81d2bdda3af199adf8e0091117ad074b25d44d Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 30 Jan 2024 19:12:28 -0700 Subject: [PATCH 008/774] Add Model responding message --- pkg/runner/runner.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index bc5ef88b..cb21075f 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -3,6 +3,7 @@ package runner import ( "context" "os" + "strings" "sync" "time" @@ -115,11 +116,15 @@ func (r *Runner) call(callCtx engine.Context, input string) (string, error) { go func() { defer wg.Done() for message := range progress { + content := message.String() + if strings.TrimSpace(content) != "" && !strings.Contains(content, "Sent content:") { + content += "\n\nModel responding..." + } r.display.progress <- Event{ Time: time.Now(), Context: &callCtx, Type: EventTypeUpdate, - Content: message.String(), + Content: content, } } }() From 18da184c611d6aa8cd0b224fdfc013487b358367 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 1 Feb 2024 00:23:36 -0700 Subject: [PATCH 009/774] Add file loading from github --- examples/helloworld.gpt | 1 + pkg/cli/root.go | 16 +-- pkg/engine/engine.go | 68 ++++++++--- pkg/loader/loader.go | 246 ++++++++++++++++++++++++++++++++++++++++ pkg/loader/log.go | 5 + pkg/mvl/log.go | 71 ++++++++++++ pkg/openai/client.go | 31 +++-- pkg/parser/parser.go | 48 +++----- pkg/runner/display.go | 23 ++-- pkg/runner/runner.go | 51 ++++++--- pkg/types/tool.go | 8 ++ 11 files changed, 472 insertions(+), 96 deletions(-) create mode 100644 examples/helloworld.gpt create mode 100644 pkg/loader/loader.go create mode 100644 pkg/loader/log.go create mode 100644 pkg/mvl/log.go diff --git a/examples/helloworld.gpt b/examples/helloworld.gpt new file mode 100644 index 00000000..c9fa3734 --- /dev/null +++ b/examples/helloworld.gpt @@ -0,0 +1 @@ +Say hello world diff --git a/pkg/cli/root.go b/pkg/cli/root.go index 617f82f0..9913bae9 100644 --- a/pkg/cli/root.go +++ b/pkg/cli/root.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/acorn-io/cmd" - "github.com/acorn-io/gptscript/pkg/parser" + "github.com/acorn-io/gptscript/pkg/loader" "github.com/acorn-io/gptscript/pkg/runner" "github.com/acorn-io/gptscript/pkg/version" "github.com/spf13/cobra" @@ -15,7 +15,8 @@ import ( type GPTScript struct { runner.Options - Output string `usage:"Save output to a file" short:"o"` + Output string `usage:"Save output to a file" short:"o"` + SubTool string `usage:"Target tool name in file to run"` } func New() *cobra.Command { @@ -25,17 +26,10 @@ func New() *cobra.Command { func (r *GPTScript) Customize(cmd *cobra.Command) { cmd.Use = version.ProgramName cmd.Args = cobra.MinimumNArgs(1) - cmd.Flags().SetInterspersed(false) } func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { - in, err := os.Open(args[0]) - if err != nil { - return err - } - defer in.Close() - - mainTool, toolSet, err := parser.Parse(in) + tool, err := loader.Tool(cmd.Context(), args[0], r.SubTool) if err != nil { return err } @@ -51,7 +45,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return err } - s, err := runner.Run(cmd.Context(), mainTool, toolSet, "") + s, err := runner.Run(cmd.Context(), *tool, "") if err != nil { return err } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 54dd20bd..7a45b075 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -17,6 +17,21 @@ import ( "github.com/acorn-io/gptscript/pkg/version" ) +// InternalSystemPrompt is added to all threads. Changing this is very dangerous as it has a +// terrible global effect and changes the behavior of all scripts. +var InternalSystemPrompt = ` +You are task oriented system. +You receive input from a user, process the input from the give instructions, and then output the result. +Your objective is to provide consist and correct results. +You are referred to as a tool. +` + +func init() { + if p := os.Getenv("GPTSCRIPT_INTERNAL_SYSTEM_PROMPT"); p != "" { + InternalSystemPrompt = p + } +} + type ErrToolNotFound struct { ToolName string } @@ -27,7 +42,7 @@ func (e *ErrToolNotFound) Error() string { type Engine struct { Client *openai.Client - Progress chan<- types.CompletionMessage + Progress chan<- openai.Status } // +k8s:deepcopy-gen=true @@ -55,36 +70,48 @@ type CallResult struct { } type Context struct { - ID string `json:"id,omitempty"` - Ctx context.Context `json:"-"` - Parent *Context `json:"parent,omitempty"` - Tool types.Tool `json:"tool,omitempty"` - Tools map[string]types.Tool `json:"tools,omitempty"` + ID string + Ctx context.Context + Parent *Context + Tool types.Tool +} + +func (c *Context) UnmarshalJSON(data []byte) error { + panic("this data struct is circular by design and can not be read from json") +} + +func (c *Context) MarshalJSON() ([]byte, error) { + var parentID string + if c.Parent != nil { + parentID = c.Parent.ID + } + return json.Marshal(map[string]any{ + "id": c.ID, + "parentID": parentID, + "tool": c.Tool, + }) } var execID int32 -func NewContext(ctx context.Context, parent *Context, tool types.Tool, tools map[string]types.Tool) Context { +func NewContext(ctx context.Context, parent *Context, tool types.Tool) Context { callCtx := Context{ ID: fmt.Sprint(atomic.AddInt32(&execID, 1)), Ctx: ctx, Parent: parent, Tool: tool, - Tools: tools, } return callCtx } func (c *Context) getTool(name string) (types.Tool, error) { - for _, tool := range c.Tools { - if tool.Name == name { - return tool, nil + tool, ok := c.Tool.ToolSet[name] + if !ok { + return types.Tool{}, &ErrToolNotFound{ + ToolName: name, } } - - return types.Tool{}, &ErrToolNotFound{ - ToolName: name, - } + return tool, nil } func (e *Engine) runCommand(tool types.Tool, input string) (string, error) { @@ -156,13 +183,18 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { completion := types.CompletionRequest{ Model: tool.ModelName, Vision: tool.Vision, - Tools: nil, - Messages: nil, MaxToken: tool.MaxTokens, JSONResponse: tool.JSONResponse, Cache: tool.Cache, } + if InternalSystemPrompt != "" { + completion.Messages = append(completion.Messages, types.CompletionMessage{ + Role: types.CompletionMessageRoleTypeSystem, + Content: types.Text(InternalSystemPrompt), + }) + } + for _, subToolName := range tool.Tools { subTool, err := ctx.getTool(subToolName) if err != nil { @@ -203,7 +235,7 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { func (e *Engine) complete(ctx context.Context, state *State) (*Return, error) { var ( - progress = make(chan types.CompletionMessage) + progress = make(chan openai.Status) ret = Return{ State: state, Calls: map[string]Call{}, diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go new file mode 100644 index 00000000..d8fb5a21 --- /dev/null +++ b/pkg/loader/loader.go @@ -0,0 +1,246 @@ +package loader + +import ( + "context" + "errors" + "fmt" + "io" + "io/fs" + "net/http" + "os" + "path/filepath" + "strings" + + "github.com/acorn-io/gptscript/pkg/parser" + "github.com/acorn-io/gptscript/pkg/types" +) + +const ( + Suffix = ".gpt" + GithubPrefix = "github.com/" + githubRawURL = "https://raw.githubusercontent.com/" +) + +type Source struct { + Content io.ReadCloser + Remote bool + Root string + Path string + Name string + File string +} + +func (s *Source) String() string { + if s.Path == "" && s.Name == "" { + return "" + } + return s.Path + "/" + s.Name +} + +func openFile(path string) (io.ReadCloser, bool, error) { + f, err := os.Open(path + Suffix) + if errors.Is(err, fs.ErrNotExist) { + return nil, false, nil + } else if err != nil { + return nil, false, err + } + return f, true, nil +} + +func loadLocal(base *Source, name string) (*Source, bool, error) { + path := filepath.Join(base.Path, name) + + content, ok, err := openFile(path) + if err != nil { + return nil, false, err + } else if !ok { + path = filepath.Join(base.Root, "vendor", path) + content, ok, err = openFile(path) + if err != nil { + return nil, false, err + } else if !ok { + return nil, false, nil + } + } + log.Debugf("opened %s%s for %s", path, Suffix, path) + + return &Source{ + Content: content, + Remote: false, + Root: base.Root, + Path: filepath.Dir(path), + Name: filepath.Base(path), + File: name + Suffix, + }, true, nil +} + +func loadGithub(ctx context.Context, base *Source, name string) (*Source, bool, error) { + urlName := filepath.Join(base.Path, name) + if !strings.HasPrefix(urlName, GithubPrefix) { + return nil, false, nil + } + + url, version, _ := strings.Cut(urlName, "@") + if version == "" { + version = "HEAD" + } + + parts := strings.Split(url, "/") + // Must be at least 4 parts github.com/ACCOUNT/REPO/FILE + if len(parts) < 4 { + return nil, false, fmt.Errorf("invalid github URL, must be at least 4 parts github.com/ACCOUNT/REPO/FILE: %s", url) + } + + url = githubRawURL + parts[1] + "/" + parts[2] + "/" + version + "/" + strings.Join(parts[3:], "/") + Suffix + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, false, err + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, false, err + } else if resp.StatusCode != http.StatusOK { + return nil, false, fmt.Errorf("error loading %s: %s", url, resp.Status) + } + + log.Debugf("opened %s for %s", url, urlName) + + return &Source{ + Content: resp.Body, + Remote: true, + Path: filepath.Dir(urlName), + Name: filepath.Base(urlName), + File: url, + }, true, nil +} + +func lookupRoot(path string) (string, error) { + current := path + for { + parent := filepath.Dir(current) + if parent == current { + break + } + if s, err := os.Stat(filepath.Join(parent, "vendor")); err == nil && s.IsDir() { + return parent, nil + } else if !errors.Is(err, fs.ErrNotExist) { + return "", err + } + current = parent + } + + return filepath.Dir(path), nil +} + +func ReadTool(ctx context.Context, base *Source, targetToolName string) (*types.Tool, error) { + defer base.Content.Close() + + tools, err := parser.Parse(base.Content) + if err != nil { + return nil, err + } + + if len(tools) == 0 { + return nil, fmt.Errorf("no tools found in %s", base) + } + + var ( + toolSet = types.ToolSet{} + mainTool types.Tool + ) + + for i, tool := range tools { + tool.Source.File = base.File + if i == 0 { + mainTool = tool + } + + if i != 0 && tool.Name == "" { + return nil, parser.NewErrLine(tool.Source.LineNo, fmt.Errorf("only the first tool in a file can have no name")) + } + + if targetToolName != "" && tool.Name == targetToolName { + mainTool = tool + } + + toolSet[tool.Name] = tool + } + + return link(ctx, base, mainTool, toolSet) +} + +func link(ctx context.Context, base *Source, tool types.Tool, toolSet types.ToolSet) (*types.Tool, error) { + tool.ToolSet = types.ToolSet{} + for _, targetToolName := range tool.Tools { + targetTool, ok := toolSet[targetToolName] + if ok { + linkedTool, err := link(ctx, base, targetTool, toolSet) + if err != nil { + return nil, fmt.Errorf("failed linking %s at %s: %w", targetToolName, base, err) + } + tool.ToolSet[targetToolName] = *linkedTool + } else { + resolvedTool, err := Resolve(ctx, base, targetToolName, "") + if err != nil { + return nil, fmt.Errorf("failed resolving %s at %s: %w", targetToolName, base, err) + } + tool.ToolSet[targetToolName] = *resolvedTool + } + } + + return &tool, nil +} + +func Tool(ctx context.Context, name, subToolName string) (*types.Tool, error) { + var base Source + + name = strings.TrimSuffix(name, Suffix) + + f, ok, err := openFile(name) + if errors.Is(err, fs.ErrNotExist) || !ok { + base = Source{ + Remote: true, + } + } else if err != nil { + return nil, err + } else { + _ = f.Close() + root, err := lookupRoot(name) + if err != nil { + return nil, err + } + base = Source{ + Root: root, + } + } + + return Resolve(ctx, &base, name, subToolName) +} + +func Resolve(ctx context.Context, base *Source, name, subTool string) (*types.Tool, error) { + s, err := Input(ctx, base, name) + if err != nil { + return nil, err + } + + return ReadTool(ctx, s, subTool) +} + +func Input(ctx context.Context, base *Source, name string) (*Source, error) { + name = strings.TrimSuffix(name, Suffix) + + if !base.Remote { + s, ok, err := loadLocal(base, name) + if err != nil || ok { + return s, err + } + } + + s, ok, err := loadGithub(ctx, base, name) + if err != nil || ok { + return s, err + } + + return nil, fmt.Errorf("can not load tools %s at %s", name, base.Path) +} diff --git a/pkg/loader/log.go b/pkg/loader/log.go new file mode 100644 index 00000000..c46464e7 --- /dev/null +++ b/pkg/loader/log.go @@ -0,0 +1,5 @@ +package loader + +import "github.com/acorn-io/gptscript/pkg/mvl" + +var log = mvl.Package() diff --git a/pkg/mvl/log.go b/pkg/mvl/log.go new file mode 100644 index 00000000..25d9a233 --- /dev/null +++ b/pkg/mvl/log.go @@ -0,0 +1,71 @@ +package mvl + +import ( + "runtime" + + "github.com/sirupsen/logrus" +) + +// This Package exists because I couldn't decide on a logging framework that didn't infuriate me. +// So this is simple place to make a better decision later about logging frameworks. I only care about +// the interface, not the implementation. Smarter people do that well. + +func init() { + logrus.SetLevel(logrus.DebugLevel) +} + +func Package() Logger { + _, p, _, _ := runtime.Caller(1) + return New(p) +} + +func New(name string) Logger { + return Logger{ + prefix: name + ": ", + log: logrus.StandardLogger(), + fields: logrus.Fields{}, + } +} + +type Logger struct { + prefix string + log *logrus.Logger + fields logrus.Fields +} + +func (l *Logger) Fields(kv ...any) Logger { + newFields := map[string]any{} + for k, v := range l.fields { + newFields[k] = v + } + for i, v := range kv { + if i%2 == 1 { + newFields[kv[i-1].(string)] = v + } + } + return Logger{ + prefix: l.prefix, + log: l.log, + fields: newFields, + } +} + +func (l *Logger) Infof(msg string, args ...any) { + l.log.WithFields(l.fields).Infof(l.prefix+msg, args...) +} + +func (l *Logger) Errorf(msg string, args ...any) { + l.log.WithFields(l.fields).Errorf(l.prefix+msg, args...) +} + +func (l *Logger) Tracef(msg string, args ...any) { + l.log.WithFields(l.fields).Tracef(l.prefix+msg, args...) +} + +func (l *Logger) Debugf(msg string, args ...any) { + l.log.WithFields(l.fields).Debugf(l.prefix+msg, args...) +} + +func (l *Logger) Fatalf(msg string, args ...any) { + l.log.WithFields(l.fields).Fatalf(l.prefix+msg, args...) +} diff --git a/pkg/openai/client.go b/pkg/openai/client.go index c19208a7..1d1e36ad 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -178,7 +178,14 @@ func toMessages(ctx context.Context, cache *cache.Client, request types.Completi return } -func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- types.CompletionMessage) (*types.CompletionMessage, error) { +type Status struct { + DebugRequest any `json:"request,omitempty"` + DebugResponse any `json:"response,omitempty"` + DebugChunks any `json:"-"` + PartialResponse *types.CompletionMessage `json:"partialResponse,omitempty"` +} + +func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- Status) (*types.CompletionMessage, error) { msgs, err := toMessages(ctx, c.cache, messageRequest) if err != nil { return nil, err @@ -245,6 +252,12 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques result = appendMessage(result, response) } + status <- Status{ + DebugRequest: request, + DebugChunks: response, + DebugResponse: result, + } + return &result, nil } @@ -326,7 +339,7 @@ func (c *Client) store(ctx context.Context, key string, responses []openai.ChatC return c.cache.Store(ctx, key, buf.Bytes()) } -func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, partial chan<- types.CompletionMessage) (responses []openai.ChatCompletionStreamResponse, _ error) { +func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, partial chan<- Status) (responses []openai.ChatCompletionStreamResponse, _ error) { cacheKey := c.cacheKey(request) request.Stream = true @@ -338,9 +351,11 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, } } - partial <- types.CompletionMessage{ - Role: types.CompletionMessageRoleTypeAssistant, - Content: types.Text(msg + "Waiting for model response..."), + partial <- Status{ + PartialResponse: &types.CompletionMessage{ + Role: types.CompletionMessageRoleTypeAssistant, + Content: types.Text(msg + "Waiting for model response..."), + }, } slog.Debug("calling openai", "message", request.Messages) @@ -361,9 +376,9 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, slog.Debug("stream", "content", response.Choices[0].Delta.Content) if partial != nil { partialMessage = appendMessage(partialMessage, response) - //d, _ := json.MarshalIndent(partialMessage, "", " ") - //fmt.Println(string(d)) - partial <- partialMessage + partial <- Status{ + PartialResponse: &partialMessage, + } } responses = append(responses, response) } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 04525d42..5ae504df 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -9,7 +9,6 @@ import ( "github.com/acorn-io/gptscript/pkg/openai" "github.com/acorn-io/gptscript/pkg/types" - "golang.org/x/exp/maps" ) var defaultToolSchema = types.JSONSchema{ @@ -84,7 +83,7 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { case "description": tool.Description = value case "tools": - tool.Tools = csv(strings.ToLower(value)) + tool.Tools = append(tool.Tools, csv(strings.ToLower(value))...) case "args": fallthrough case "arg": @@ -96,6 +95,8 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { if err != nil { return false, err } + case "maxtoken": + fallthrough case "maxtokens": tool.MaxTokens, err = strconv.Atoi(value) if err != nil { @@ -132,7 +133,7 @@ func (e *ErrLine) Error() string { return fmt.Sprintf("line %d: %v", e.Line, e.Err) } -func errLine(lineNo int, err error) error { +func NewErrLine(lineNo int, err error) error { return &ErrLine{ Line: lineNo, Err: err, @@ -156,7 +157,7 @@ func (c *context) finish(tools *[]types.Tool) { *c = context{} } -func Parse(input io.Reader) (types.Tool, types.ToolSet, error) { +func Parse(input io.Reader) ([]types.Tool, error) { scan := bufio.NewScanner(input) var ( @@ -167,6 +168,10 @@ func Parse(input io.Reader) (types.Tool, types.ToolSet, error) { for scan.Scan() { lineNo++ + if context.tool.Source.LineNo == 0 { + context.tool.Source.LineNo = lineNo + } + line := scan.Text() + "\n" if line == "---\n" { @@ -175,14 +180,19 @@ func Parse(input io.Reader) (types.Tool, types.ToolSet, error) { } if !context.inBody { + // This is a comment if strings.HasPrefix(line, "#") && !strings.HasPrefix(line, "#!") { continue } + + // Blank line if strings.TrimSpace(line) == "" { continue } + + // Look for params if isParam, err := isParam(line, &context.tool); err != nil { - return types.Tool{}, nil, errLine(lineNo, err) + return nil, NewErrLine(lineNo, err) } else if isParam { continue } @@ -193,31 +203,5 @@ func Parse(input io.Reader) (types.Tool, types.ToolSet, error) { } context.finish(&tools) - - var ( - mainTool types.Tool - toolSet = types.ToolSet{} - ) - - for i, tool := range tools { - if i == 0 { - mainTool = tool - } - if tool.Name != "" { - if _, ok := toolSet[tool.Name]; ok { - return mainTool, nil, fmt.Errorf("duplicate tool named %s", tool.Name) - } - toolSet[tool.Name] = tool - } - } - - for _, tool := range append(maps.Values(toolSet), mainTool) { - for _, tool := range tool.Tools { - if _, ok := toolSet[tool]; !ok { - return mainTool, nil, fmt.Errorf("missing reference to tool named: %s", tool) - } - } - } - - return mainTool, toolSet, nil + return tools, nil } diff --git a/pkg/runner/display.go b/pkg/runner/display.go index c8de3a04..6376d8e6 100644 --- a/pkg/runner/display.go +++ b/pkg/runner/display.go @@ -13,16 +13,18 @@ import ( ) type display struct { - progress chan Event - states []state - done chan struct{} - area *pterm.AreaPrinter - quiet bool + progress chan Event + states []state + done chan struct{} + area *pterm.AreaPrinter + quiet bool + showFinished bool } -func newDisplay(quiet bool) *display { +func newDisplay(quiet, showFinished bool) *display { return &display{ - quiet: quiet, + quiet: quiet, + showFinished: showFinished, } } @@ -30,7 +32,7 @@ func (d *display) Start(ctx context.Context) (err error) { if !d.quiet { d.area, err = pterm.DefaultArea. //WithFullscreen(true). - WithRemoveWhenDone(true). + //WithRemoveWhenDone(true). Start("Starting...") if err != nil { return err @@ -110,7 +112,7 @@ func multiLineWrite(out io.StringWriter, prefix, lines string) { } func (d *display) printState(s state, depth int) string { - if !s.Running { + if !d.showFinished && !s.Running { return "" } @@ -195,6 +197,8 @@ func (d *display) addEvent(msg Event) { state.Running = false state.Output = msg.Content state.End = msg.Time + case EventTypeDebug: + state.Debug = append(state.Debug, msg.Debug) } d.states[i] = state } @@ -215,6 +219,7 @@ func (d *display) addEvent(msg Event) { type state struct { Context *engine.Context `json:"context,omitempty"` + Debug []any `json:"debug,omitempty"` Running bool `json:"running,omitempty"` Start time.Time `json:"start,omitempty"` End time.Time `json:"end,omitempty"` diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index cb21075f..6e157e67 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -15,9 +15,10 @@ import ( ) type Options struct { - Quiet bool `usage:"Do not print status" short:"q"` - DumpState string `usage:"Dump the internal execution state to a file"` - Cache *bool `usage:"Disable caching" default:"true"` + Quiet bool `usage:"Do not print status" short:"q"` + DumpState string `usage:"Dump the internal execution state to a file"` + Cache *bool `usage:"Disable caching" default:"true"` + ShowFinished bool `usage:"Show finished calls results"` } func complete(opts ...Options) (result Options) { @@ -31,6 +32,9 @@ func complete(opts ...Options) (result Options) { if opt.Cache != nil { result.Cache = opt.Cache } + if opt.ShowFinished { + result.ShowFinished = opt.ShowFinished + } } if result.Cache == nil { result.Cache = &[]bool{true}[0] @@ -63,12 +67,12 @@ func New(opts ...Options) (*Runner, error) { } return &Runner{ c: c, - display: newDisplay(opt.Quiet), + display: newDisplay(opt.Quiet, opt.ShowFinished), dumpState: opt.DumpState, }, nil } -func (r *Runner) Run(ctx context.Context, tool types.Tool, toolSet types.ToolSet, input string) (string, error) { +func (r *Runner) Run(ctx context.Context, tool types.Tool, input string) (string, error) { if err := r.display.Start(ctx); err != nil { return "", err } @@ -84,7 +88,7 @@ func (r *Runner) Run(ctx context.Context, tool types.Tool, toolSet types.ToolSet } }() - callCtx := engine.NewContext(ctx, nil, tool, toolSet) + callCtx := engine.NewContext(ctx, nil, tool) return r.call(callCtx, input) } @@ -92,6 +96,7 @@ type Event struct { Time time.Time Context *engine.Context Type EventType + Debug any Content string } @@ -100,11 +105,12 @@ type EventType string var ( EventTypeStart = EventType("start") EventTypeUpdate = EventType("progress") + EventTypeDebug = EventType("debug") EventTypeStop = EventType("stop") ) func (r *Runner) call(callCtx engine.Context, input string) (string, error) { - progress := make(chan types.CompletionMessage) + progress := make(chan openai.Status) e := engine.Engine{ Client: r.c, @@ -115,16 +121,25 @@ func (r *Runner) call(callCtx engine.Context, input string) (string, error) { wg.Add(1) go func() { defer wg.Done() - for message := range progress { - content := message.String() - if strings.TrimSpace(content) != "" && !strings.Contains(content, "Sent content:") { - content += "\n\nModel responding..." - } - r.display.progress <- Event{ - Time: time.Now(), - Context: &callCtx, - Type: EventTypeUpdate, - Content: content, + for status := range progress { + if message := status.PartialResponse; message != nil { + content := message.String() + if strings.TrimSpace(content) != "" && !strings.Contains(content, "Sent content:") { + content += "\n\nModel responding..." + } + r.display.progress <- Event{ + Time: time.Now(), + Context: &callCtx, + Type: EventTypeUpdate, + Content: content, + } + } else { + r.display.progress <- Event{ + Time: time.Now(), + Context: &callCtx, + Type: EventTypeDebug, + Debug: status, + } } } }() @@ -163,7 +178,7 @@ func (r *Runner) call(callCtx engine.Context, input string) (string, error) { for id, call := range result.Calls { id := id call := call - callCtx := engine.NewContext(subCtx, &callCtx, callCtx.Tools[call.ToolName], callCtx.Tools) + callCtx := engine.NewContext(subCtx, &callCtx, callCtx.Tool.ToolSet[call.ToolName]) callCtx.ID = id eg.Go(func() error { result, err := r.call(callCtx, call.Input) diff --git a/pkg/types/tool.go b/pkg/types/tool.go index 05336dfe..48402dc8 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -18,6 +18,14 @@ type Tool struct { ModelName string `json:"modelName,omitempty"` JSONResponse bool `json:"jsonResponse,omitempty"` Cache *bool `json:"cache,omitempty"` + + ToolSet ToolSet `json:"-"` + Source ToolSource `json:"source,omitempty"` +} + +type ToolSource struct { + File string `json:"file,omitempty"` + LineNo int `json:"lineNo,omitempty"` } func (t Tool) IsCommand() bool { From 76385e08f5f56a14d8ad9aa4a4bcfa835000350e Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 1 Feb 2024 20:20:27 -0700 Subject: [PATCH 010/774] Add args and url loading --- examples/input.gpt | 1 + pkg/assemble/assemble.go | 18 ++++ pkg/cli/root.go | 35 ++++++- pkg/input/input.go | 32 ++++++ pkg/input/log.go | 5 + pkg/loader/loader.go | 201 +++++++++++++++++++++++--------------- pkg/mvl/log.go | 19 +++- pkg/openai/client.go | 12 +-- pkg/openai/client_test.go | 17 ++++ pkg/types/tool.go | 2 +- 10 files changed, 253 insertions(+), 89 deletions(-) create mode 100644 examples/input.gpt create mode 100644 pkg/assemble/assemble.go create mode 100644 pkg/input/input.go create mode 100644 pkg/input/log.go create mode 100644 pkg/openai/client_test.go diff --git a/examples/input.gpt b/examples/input.gpt new file mode 100644 index 00000000..2b4b6d55 --- /dev/null +++ b/examples/input.gpt @@ -0,0 +1 @@ +echo "${input}" diff --git a/pkg/assemble/assemble.go b/pkg/assemble/assemble.go new file mode 100644 index 00000000..f1b06a0e --- /dev/null +++ b/pkg/assemble/assemble.go @@ -0,0 +1,18 @@ +package assemble + +import ( + "context" + "encoding/json" + "io" + + "github.com/acorn-io/gptscript/pkg/types" +) + +var Header = []byte("GPTSCRIPT\x00") + +func Assemble(ctx context.Context, tool types.Tool, output io.Writer) error { + if _, err := output.Write(Header); err != nil { + return err + } + return json.NewEncoder(output).Encode(tool) +} diff --git a/pkg/cli/root.go b/pkg/cli/root.go index 9913bae9..ff5e114e 100644 --- a/pkg/cli/root.go +++ b/pkg/cli/root.go @@ -2,10 +2,13 @@ package cli import ( "fmt" + "io" "os" "strings" "github.com/acorn-io/cmd" + "github.com/acorn-io/gptscript/pkg/assemble" + "github.com/acorn-io/gptscript/pkg/input" "github.com/acorn-io/gptscript/pkg/loader" "github.com/acorn-io/gptscript/pkg/runner" "github.com/acorn-io/gptscript/pkg/version" @@ -15,8 +18,10 @@ import ( type GPTScript struct { runner.Options - Output string `usage:"Save output to a file" short:"o"` - SubTool string `usage:"Target tool name in file to run"` + Output string `usage:"Save output to a file" short:"o"` + Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"` + SubTool string `usage:"Target tool name in file to run"` + Assemble bool `usage:"Assemble tool to a single artifact and saved to --output"` } func New() *cobra.Command { @@ -26,6 +31,7 @@ func New() *cobra.Command { func (r *GPTScript) Customize(cmd *cobra.Command) { cmd.Use = version.ProgramName cmd.Args = cobra.MinimumNArgs(1) + cmd.Flags().SetInterspersed(false) } func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { @@ -34,6 +40,20 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return err } + if r.Assemble { + var out io.Writer = os.Stdout + if r.Output != "" { + f, err := os.Create(r.Output) + if err != nil { + return fmt.Errorf("opening %s: %w", r.Output, err) + } + defer f.Close() + out = f + } + + return assemble.Assemble(cmd.Context(), *tool, out) + } + if !r.Quiet { if !term.IsTerminal(int(os.Stdout.Fd())) { r.Quiet = true @@ -45,7 +65,16 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return err } - s, err := runner.Run(cmd.Context(), *tool, "") + toolInput, err := input.FromFile(r.Input) + if err != nil { + return err + } + + if toolInput == "" { + toolInput = input.FromArgs(args[1:]) + } + + s, err := runner.Run(cmd.Context(), *tool, toolInput) if err != nil { return err } diff --git a/pkg/input/input.go b/pkg/input/input.go new file mode 100644 index 00000000..3aaa8cc7 --- /dev/null +++ b/pkg/input/input.go @@ -0,0 +1,32 @@ +package input + +import ( + "fmt" + "io" + "os" + "strings" +) + +func FromArgs(args []string) string { + return strings.Join(args, " ") +} + +func FromFile(file string) (string, error) { + if file == "-" { + log.Debugf("reading stdin") + data, err := io.ReadAll(os.Stdin) + if err != nil { + return "", fmt.Errorf("reading stdin: %w", err) + } + return string(data), nil + } else if file != "" { + log.Debugf("reading file %s", file) + data, err := os.ReadFile(file) + if err != nil { + return "", fmt.Errorf("reading %s: %w", file, err) + } + return string(data), nil + } + + return "", nil +} diff --git a/pkg/input/log.go b/pkg/input/log.go new file mode 100644 index 00000000..7ffc0a4c --- /dev/null +++ b/pkg/input/log.go @@ -0,0 +1,5 @@ +package input + +import "github.com/acorn-io/gptscript/pkg/mvl" + +var log = mvl.Package() diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index d8fb5a21..e65b7fca 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -1,22 +1,28 @@ package loader import ( + "bytes" "context" + "crypto/md5" + "encoding/hex" + "encoding/json" "errors" "fmt" "io" "io/fs" "net/http" + url2 "net/url" "os" "path/filepath" + "regexp" "strings" + "github.com/acorn-io/gptscript/pkg/assemble" "github.com/acorn-io/gptscript/pkg/parser" "github.com/acorn-io/gptscript/pkg/types" ) const ( - Suffix = ".gpt" GithubPrefix = "github.com/" githubRawURL = "https://raw.githubusercontent.com/" ) @@ -24,7 +30,6 @@ const ( type Source struct { Content io.ReadCloser Remote bool - Root string Path string Name string File string @@ -38,7 +43,7 @@ func (s *Source) String() string { } func openFile(path string) (io.ReadCloser, bool, error) { - f, err := os.Open(path + Suffix) + f, err := os.Open(path) if errors.Is(err, fs.ErrNotExist) { return nil, false, nil } else if err != nil { @@ -54,30 +59,22 @@ func loadLocal(base *Source, name string) (*Source, bool, error) { if err != nil { return nil, false, err } else if !ok { - path = filepath.Join(base.Root, "vendor", path) - content, ok, err = openFile(path) - if err != nil { - return nil, false, err - } else if !ok { - return nil, false, nil - } + return nil, false, nil } - log.Debugf("opened %s%s for %s", path, Suffix, path) + log.Debugf("opened %s", path) return &Source{ Content: content, Remote: false, - Root: base.Root, Path: filepath.Dir(path), Name: filepath.Base(path), - File: name + Suffix, + File: path, }, true, nil } -func loadGithub(ctx context.Context, base *Source, name string) (*Source, bool, error) { - urlName := filepath.Join(base.Path, name) +func githubURL(urlName string) (string, bool) { if !strings.HasPrefix(urlName, GithubPrefix) { - return nil, false, nil + return "", false } url, version, _ := strings.Cut(urlName, "@") @@ -88,10 +85,25 @@ func loadGithub(ctx context.Context, base *Source, name string) (*Source, bool, parts := strings.Split(url, "/") // Must be at least 4 parts github.com/ACCOUNT/REPO/FILE if len(parts) < 4 { - return nil, false, fmt.Errorf("invalid github URL, must be at least 4 parts github.com/ACCOUNT/REPO/FILE: %s", url) + return "", false + } + + url = githubRawURL + parts[1] + "/" + parts[2] + "/" + version + "/" + strings.Join(parts[3:], "/") + return url, true +} + +func loadURL(ctx context.Context, base *Source, name string) (*Source, bool, error) { + url := name + if base.Path != "" { + url = base.Path + "/" + name + } + if githubURL, ok := githubURL(url); ok { + url = githubURL + } + if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { + return nil, false, nil } - url = githubRawURL + parts[1] + "/" + parts[2] + "/" + version + "/" + strings.Join(parts[3:], "/") + Suffix req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return nil, false, err @@ -104,39 +116,38 @@ func loadGithub(ctx context.Context, base *Source, name string) (*Source, bool, return nil, false, fmt.Errorf("error loading %s: %s", url, resp.Status) } - log.Debugf("opened %s for %s", url, urlName) + log.Debugf("opened %s", url) + + parsed, err := url2.Parse(url) + if err != nil { + return nil, false, err + } + + pathURL := *parsed + pathURL.Path = filepath.Dir(parsed.Path) return &Source{ Content: resp.Body, Remote: true, - Path: filepath.Dir(urlName), - Name: filepath.Base(urlName), + Path: pathURL.String(), + Name: filepath.Base(parsed.Path), File: url, }, true, nil } -func lookupRoot(path string) (string, error) { - current := path - for { - parent := filepath.Dir(current) - if parent == current { - break - } - if s, err := os.Stat(filepath.Join(parent, "vendor")); err == nil && s.IsDir() { - return parent, nil - } else if !errors.Is(err, fs.ErrNotExist) { - return "", err - } - current = parent +func ReadTool(ctx context.Context, base *Source, targetToolName string) (*types.Tool, error) { + data, err := io.ReadAll(base.Content) + if err != nil { + return nil, err } + _ = base.Content.Close() - return filepath.Dir(path), nil -} - -func ReadTool(ctx context.Context, base *Source, targetToolName string) (*types.Tool, error) { - defer base.Content.Close() + if bytes.HasPrefix(data, assemble.Header) { + var tool types.Tool + return &tool, json.Unmarshal(data[len(assemble.Header):], &tool) + } - tools, err := parser.Parse(base.Content) + tools, err := parser.Parse(bytes.NewReader(data)) if err != nil { return nil, err } @@ -170,52 +181,90 @@ func ReadTool(ctx context.Context, base *Source, targetToolName string) (*types. return link(ctx, base, mainTool, toolSet) } +var ( + validToolName = regexp.MustCompile("^[a-zA-Z0-9_-]{1,64}$") + invalidChars = regexp.MustCompile("[^a-zA-Z0-9_-]+") +) + +func toolNormalizer(tool string) string { + if validToolName.MatchString(tool) { + return tool + } + + name := invalidChars.ReplaceAllString(tool, "-") + if len(name) > 55 { + name = name[:55] + } + + hash := md5.Sum([]byte(tool)) + hexed := hex.EncodeToString(hash[:]) + + return name + "-" + hexed[:8] +} + +func pickToolName(toolName string, existing map[string]struct{}) string { + newName, suffix, ok := strings.Cut(toolName, "/") + if ok { + newName = suffix + } + newName = strings.TrimSuffix(newName, filepath.Ext(newName)) + if newName == "" { + newName = "external" + } + + for { + testName := toolNormalizer(newName) + if _, ok := existing[testName]; !ok { + existing[testName] = struct{}{} + return testName + } + newName += "0" + } +} + func link(ctx context.Context, base *Source, tool types.Tool, toolSet types.ToolSet) (*types.Tool, error) { tool.ToolSet = types.ToolSet{} + toolNames := map[string]struct{}{} + for _, targetToolName := range tool.Tools { targetTool, ok := toolSet[targetToolName] - if ok { - linkedTool, err := link(ctx, base, targetTool, toolSet) - if err != nil { - return nil, fmt.Errorf("failed linking %s at %s: %w", targetToolName, base, err) - } - tool.ToolSet[targetToolName] = *linkedTool - } else { - resolvedTool, err := Resolve(ctx, base, targetToolName, "") - if err != nil { - return nil, fmt.Errorf("failed resolving %s at %s: %w", targetToolName, base, err) - } - tool.ToolSet[targetToolName] = *resolvedTool + if !ok { + continue } - } - - return &tool, nil -} -func Tool(ctx context.Context, name, subToolName string) (*types.Tool, error) { - var base Source + linkedTool, err := link(ctx, base, targetTool, toolSet) + if err != nil { + return nil, fmt.Errorf("failed linking %s at %s: %w", targetToolName, base, err) + } + tool.ToolSet[targetToolName] = *linkedTool + toolNames[targetToolName] = struct{}{} + } - name = strings.TrimSuffix(name, Suffix) + for i, targetToolName := range tool.Tools { + _, ok := toolSet[targetToolName] + if ok { + continue + } - f, ok, err := openFile(name) - if errors.Is(err, fs.ErrNotExist) || !ok { - base = Source{ - Remote: true, + toolName, subTool, ok := strings.Cut(targetToolName, " from ") + if ok { + toolName = strings.TrimSpace(toolName) + subTool = strings.TrimSpace(subTool) } - } else if err != nil { - return nil, err - } else { - _ = f.Close() - root, err := lookupRoot(name) + resolvedTool, err := Resolve(ctx, base, toolName, subTool) if err != nil { - return nil, err - } - base = Source{ - Root: root, + return nil, fmt.Errorf("failed resolving %s at %s: %w", targetToolName, base, err) } + newToolName := pickToolName(toolName, toolNames) + tool.ToolSet[newToolName] = *resolvedTool + tool.Tools[i] = newToolName } - return Resolve(ctx, &base, name, subToolName) + return &tool, nil +} + +func Tool(ctx context.Context, name, subToolName string) (*types.Tool, error) { + return Resolve(ctx, &Source{}, name, subToolName) } func Resolve(ctx context.Context, base *Source, name, subTool string) (*types.Tool, error) { @@ -228,8 +277,6 @@ func Resolve(ctx context.Context, base *Source, name, subTool string) (*types.To } func Input(ctx context.Context, base *Source, name string) (*Source, error) { - name = strings.TrimSuffix(name, Suffix) - if !base.Remote { s, ok, err := loadLocal(base, name) if err != nil || ok { @@ -237,10 +284,10 @@ func Input(ctx context.Context, base *Source, name string) (*Source, error) { } } - s, ok, err := loadGithub(ctx, base, name) + s, ok, err := loadURL(ctx, base, name) if err != nil || ok { return s, err } - return nil, fmt.Errorf("can not load tools %s at %s", name, base.Path) + return nil, fmt.Errorf("can not load tools path=%s name=%s", base.Path, name) } diff --git a/pkg/mvl/log.go b/pkg/mvl/log.go index 25d9a233..63296871 100644 --- a/pkg/mvl/log.go +++ b/pkg/mvl/log.go @@ -33,7 +33,22 @@ type Logger struct { fields logrus.Fields } -func (l *Logger) Fields(kv ...any) Logger { +func (l *Logger) FieldsMap(kv map[string]any) *Logger { + newFields := map[string]any{} + for k, v := range l.fields { + newFields[k] = v + } + for k, v := range kv { + newFields[k] = v + } + return &Logger{ + prefix: l.prefix, + log: l.log, + fields: newFields, + } +} + +func (l *Logger) Fields(kv ...any) *Logger { newFields := map[string]any{} for k, v := range l.fields { newFields[k] = v @@ -43,7 +58,7 @@ func (l *Logger) Fields(kv ...any) Logger { newFields[kv[i-1].(string)] = v } } - return Logger{ + return &Logger{ prefix: l.prefix, log: l.log, fields: newFields, diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 1d1e36ad..9caa952c 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -179,9 +179,9 @@ func toMessages(ctx context.Context, cache *cache.Client, request types.Completi } type Status struct { - DebugRequest any `json:"request,omitempty"` - DebugResponse any `json:"response,omitempty"` - DebugChunks any `json:"-"` + Request any `json:"request,omitempty"` + Response any `json:"response,omitempty"` + Chunks any `json:"-"` PartialResponse *types.CompletionMessage `json:"partialResponse,omitempty"` } @@ -253,9 +253,9 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } status <- Status{ - DebugRequest: request, - DebugChunks: response, - DebugResponse: result, + Request: request, + Chunks: response, + Response: result, } return &result, nil diff --git a/pkg/openai/client_test.go b/pkg/openai/client_test.go new file mode 100644 index 00000000..c0ed9ce8 --- /dev/null +++ b/pkg/openai/client_test.go @@ -0,0 +1,17 @@ +package openai + +import ( + "strings" + "testing" +) + +func Test_toolNormalizer(t *testing.T) { + output := toolNormalizer("x/" + strings.Repeat("a", 64)) + if len(output) != 64 { + t.Fatalf("not 64 characters %s %d", output, len(output)) + } + exp := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-7f46b2b2" + if output != exp { + t.Fatalf("%s != %s", output, exp) + } +} diff --git a/pkg/types/tool.go b/pkg/types/tool.go index 48402dc8..cc5ea436 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -19,7 +19,7 @@ type Tool struct { JSONResponse bool `json:"jsonResponse,omitempty"` Cache *bool `json:"cache,omitempty"` - ToolSet ToolSet `json:"-"` + ToolSet ToolSet `json:"toolSet,omitempty"` Source ToolSource `json:"source,omitempty"` } From 64be97b186ab90cc8826c2a074bec4d0f990f7c3 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 2 Feb 2024 20:31:06 -0700 Subject: [PATCH 011/774] Refactor runner --- Makefile | 7 +- README.md | 6 +- examples/describe.gpt | 6 +- examples/echo.gpt | 2 + examples/fib.gpt | 15 ++ examples/input.gpt | 1 - examples/summarize-syntax.gpt | 2 +- examples/tables.gpt | 2 +- go.mod | 20 ++- go.sum | 53 ++++++- pkg/assemble/assemble.go | 6 +- pkg/cache/cache.go | 31 +++- pkg/cli/gptscript.go | 138 ++++++++++++++++++ pkg/cli/root.go | 95 ------------ pkg/engine/engine.go | 52 +++++-- pkg/engine/log.go | 5 + pkg/input/input.go | 9 ++ pkg/loader/defaults.go | 37 +++++ pkg/loader/loader.go | 120 +++++++++++---- pkg/loader/loader_test.go | 6 + pkg/{runner => monitor}/display.go | 80 ++++++++-- pkg/mvl/log.go | 15 +- pkg/openai/client.go | 84 ++++++++--- pkg/openai/client_test.go | 17 --- pkg/parser/parser.go | 17 --- pkg/runner/monitor.go | 23 +++ pkg/runner/runner.go | 123 ++++++++-------- pkg/test/examples_test.go | 41 ++++++ .../testdata/TestExamples/describe.gpt.golden | 1 + .../testdata/TestExamples/echo.gpt.golden | 1 + pkg/test/testdata/TestExamples/fib.gpt.golden | 1 + .../TestExamples/git-commit.gpt.golden | 1 + .../TestExamples/helloworld.gpt.golden | 1 + .../TestExamples/summarize-syntax.gpt.golden | 1 + .../testdata/TestExamples/tables.gpt.golden | 1 + pkg/types/jsonschema.go | 2 +- pkg/types/tool.go | 34 ++++- scripts/ci.gpt | 20 +++ 38 files changed, 768 insertions(+), 308 deletions(-) create mode 100644 examples/echo.gpt create mode 100644 examples/fib.gpt delete mode 100644 examples/input.gpt create mode 100644 pkg/cli/gptscript.go delete mode 100644 pkg/cli/root.go create mode 100644 pkg/engine/log.go create mode 100644 pkg/loader/defaults.go create mode 100644 pkg/loader/loader_test.go rename pkg/{runner => monitor}/display.go (70%) delete mode 100644 pkg/openai/client_test.go create mode 100644 pkg/runner/monitor.go create mode 100644 pkg/test/examples_test.go create mode 100644 pkg/test/testdata/TestExamples/describe.gpt.golden create mode 100644 pkg/test/testdata/TestExamples/echo.gpt.golden create mode 100644 pkg/test/testdata/TestExamples/fib.gpt.golden create mode 100644 pkg/test/testdata/TestExamples/git-commit.gpt.golden create mode 100644 pkg/test/testdata/TestExamples/helloworld.gpt.golden create mode 100644 pkg/test/testdata/TestExamples/summarize-syntax.gpt.golden create mode 100644 pkg/test/testdata/TestExamples/tables.gpt.golden create mode 100644 scripts/ci.gpt diff --git a/Makefile b/Makefile index d57309c7..144a2561 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,8 @@ -GO_TAGS ?= netgo build: CGO_ENABLED=0 go build -o bin/gptscript -tags "${GO_TAGS}" -ldflags "-s -w" . + +test: + go test -v ./... + +ci: build + ./bin/gptscript ./scripts/ci.gpt diff --git a/README.md b/README.md index 84f0970a..5bb5728b 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ arg: file: The filename to read #!/bin/bash -cat ${ARG_FILE} Date: Fri, 2 Feb 2024 21:40:49 -0700 Subject: [PATCH 012/774] Add sys.read and sys.write --- pkg/builtin/builtin.go | 68 +++++++++++++++++++++++++++++++++++++++++ pkg/builtin/log.go | 5 +++ pkg/engine/engine.go | 8 +++-- pkg/loader/loader.go | 9 ++++++ pkg/types/jsonschema.go | 18 +++++++++++ pkg/types/tool.go | 4 +++ 6 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 pkg/builtin/builtin.go create mode 100644 pkg/builtin/log.go diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go new file mode 100644 index 00000000..0c517e89 --- /dev/null +++ b/pkg/builtin/builtin.go @@ -0,0 +1,68 @@ +package builtin + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "os" + "unicode/utf8" + + "github.com/acorn-io/gptscript/pkg/types" +) + +var Tools = map[string]types.Tool{ + "sys.read": { + Description: "Reads the contents of a file", + Arguments: types.ObjectSchema( + "filename", "The name of the file to read"), + BuiltinFunc: func(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Filename string `json:"filename,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + log.Debugf("Reading file %s", params.Filename) + data, err := os.ReadFile(params.Filename) + if err != nil { + return "", err + } + + if utf8.Valid(data) { + return string(data), nil + } + return base64.StdEncoding.EncodeToString(data), nil + }, + }, + "sys.write": { + Description: "Write the contents to a file", + Arguments: types.ObjectSchema( + "filename", "The name of the file to write to", + "content", "The content to write"), + BuiltinFunc: func(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Filename string `json:"filename,omitempty"` + Content string `json:"content,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + data := []byte(params.Content) + msg := fmt.Sprintf("Wrote %d bytes to file %s", len(data), params.Filename) + log.Debugf(msg) + + return "", os.WriteFile(params.Filename, data, 0644) + }, + }, +} + +func Builtin(name string) (types.Tool, bool) { + t, ok := Tools[name] + t.Name = name + t.ID = name + t.Instructions = "#!" + name + return t, ok +} diff --git a/pkg/builtin/log.go b/pkg/builtin/log.go new file mode 100644 index 00000000..8457cf2e --- /dev/null +++ b/pkg/builtin/log.go @@ -0,0 +1,5 @@ +package builtin + +import "github.com/acorn-io/gptscript/pkg/mvl" + +var log = mvl.Package() diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 7983a19c..1b75ab16 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -137,7 +137,11 @@ func (c *Context) getTool(name string) (types.Tool, error) { return tool, nil } -func (e *Engine) runCommand(tool types.Tool, input string) (string, error) { +func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) (string, error) { + if tool.BuiltinFunc != nil { + return tool.BuiltinFunc(ctx, e.Env, input) + } + env := e.Env[:] data := map[string]any{} @@ -197,7 +201,7 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { tool := ctx.Tool if tool.IsCommand() { - s, err := e.runCommand(tool, input) + s, err := e.runCommand(ctx.Ctx, tool, input) if err != nil { return nil, err } diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index c6640709..ca459855 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -19,6 +19,7 @@ import ( "strings" "github.com/acorn-io/gptscript/pkg/assemble" + "github.com/acorn-io/gptscript/pkg/builtin" "github.com/acorn-io/gptscript/pkg/parser" "github.com/acorn-io/gptscript/pkg/types" ) @@ -332,6 +333,14 @@ func Program(ctx context.Context, name, subToolName string) (types.Program, erro } func Resolve(ctx context.Context, prg *types.Program, base *Source, name, subTool string) (types.Tool, error) { + if subTool == "" { + t, ok := builtin.Builtin(name) + if ok { + prg.ToolSet[t.ID] = t + return t, nil + } + } + s, err := Input(ctx, base, name) if err != nil { return types.Tool{}, err diff --git a/pkg/types/jsonschema.go b/pkg/types/jsonschema.go index 670c6788..575fdc01 100644 --- a/pkg/types/jsonschema.go +++ b/pkg/types/jsonschema.go @@ -16,6 +16,24 @@ type JSONSchema struct { AdditionalProperties bool `json:"additionalProperties,omitempty"` } +func ObjectSchema(kv ...string) *JSONSchema { + s := &JSONSchema{ + Property: Property{ + Type: "object", + }, + Properties: map[string]Property{}, + } + for i, v := range kv { + if i%2 == 1 { + s.Properties[kv[i-1]] = Property{ + Description: v, + Type: "string", + } + } + } + return s +} + type Property struct { Description string `json:"description,omitempty"` Type string `json:"type,omitempty"` diff --git a/pkg/types/tool.go b/pkg/types/tool.go index a7212617..e13d76be 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -1,6 +1,7 @@ package types import ( + "context" "fmt" "strings" ) @@ -12,6 +13,8 @@ type Program struct { ToolSet ToolSet `json:"toolSet,omitempty"` } +type BuiltinFunc func(ctx context.Context, env []string, input string) (string, error) + type Tool struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` @@ -20,6 +23,7 @@ type Tool struct { Instructions string `json:"instructions,omitempty"` Tools []string `json:"tools,omitempty"` ToolMapping map[string]string `json:"toolMapping,omitempty"` + BuiltinFunc BuiltinFunc `json:"-"` Vision bool `json:"vision,omitempty"` MaxTokens int `json:"maxTokens,omitempty"` From 061cfc3d2d949dde1b455252f0b0ead81e11564e Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 2 Feb 2024 21:53:55 -0700 Subject: [PATCH 013/774] Remove deepcopy --- generate.go | 3 - go.mod | 12 +- go.sum | 35 ---- pkg/engine/engine.go | 10 +- pkg/engine/zz_generated.deepcopy.go | 40 ---- pkg/types/doc.go | 3 - pkg/types/jsonschema.go | 2 - pkg/types/zz_generated.deepcopy.go | 308 ---------------------------- tools/header.txt | 0 tools/vendor.go | 6 - 10 files changed, 11 insertions(+), 408 deletions(-) delete mode 100644 generate.go delete mode 100644 pkg/engine/zz_generated.deepcopy.go delete mode 100644 pkg/types/doc.go delete mode 100644 pkg/types/zz_generated.deepcopy.go delete mode 100644 tools/header.txt delete mode 100644 tools/vendor.go diff --git a/generate.go b/generate.go deleted file mode 100644 index 8611e894..00000000 --- a/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -//go:generate go run github.com/acorn-io/baaah/cmd/deepcopy ./pkg/engine/ ./pkg/types/ - -package main diff --git a/go.mod b/go.mod index a574f383..37a19a55 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/acorn-io/gptscript go 1.21.5 require ( - github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb github.com/adrg/xdg v0.4.0 github.com/hexops/autogold/v2 v2.1.0 @@ -16,6 +15,13 @@ require ( golang.org/x/term v0.16.0 ) +require ( + github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect + github.com/onsi/gomega v1.29.0 // indirect +) + require ( atomicgo.dev/cursor v0.2.0 // indirect atomicgo.dev/keyboard v0.2.9 // indirect @@ -24,7 +30,6 @@ require ( github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.15.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect @@ -50,11 +55,8 @@ require ( golang.org/x/sys v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.16.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apimachinery v0.29.0 // indirect k8s.io/klog/v2 v2.110.1 // indirect mvdan.cc/gofumpt v0.4.0 // indirect sigs.k8s.io/controller-runtime v0.16.3 // indirect - sigs.k8s.io/controller-tools v0.12.0 // indirect ) diff --git a/go.sum b/go.sum index 1e764352..f8dbc8c9 100644 --- a/go.sum +++ b/go.sum @@ -37,17 +37,11 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= -github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -56,8 +50,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ= github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= @@ -75,8 +67,6 @@ github.com/hexops/valast v1.4.3 h1:oBoGERMJh6UZdRc6cduE1CTPK+VAdXA59Y1HFgu3sm0= github.com/hexops/valast v1.4.3/go.mod h1:Iqx2kLj3Jn47wuXpj3wX40xn6F93QNFBHuiKBerkTGA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -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/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= @@ -103,16 +93,8 @@ github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -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 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/nightlyone/lockfile v1.0.0 h1:RHep2cFKK4PonZJDdEl4GmkabuhbsRMgk/k3uAmxBiA= github.com/nightlyone/lockfile v1.0.0/go.mod h1:rywoIealpdNse2r832aiD9jRk8ErCatROs6LzC841CI= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= @@ -236,33 +218,16 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/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-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM= mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= -sigs.k8s.io/controller-tools v0.12.0 h1:TY6CGE6+6hzO7hhJFte65ud3cFmmZW947jajXkuDfBw= -sigs.k8s.io/controller-tools v0.12.0/go.mod h1:rXlpTfFHZMpZA8aGq9ejArgZiieHd+fkk/fTatY8A2M= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 1b75ab16..b63f5c2b 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -47,8 +47,6 @@ type Engine struct { Progress chan<- openai.Status } -// +k8s:deepcopy-gen=true - type State struct { Completion types.CompletionRequest `json:"completion,omitempty"` Pending map[string]types.CompletionToolCall `json:"pending,omitempty"` @@ -313,10 +311,10 @@ func (e *Engine) complete(ctx context.Context, state *State) (*Return, error) { } func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResult) (*Return, error) { - state = state.DeepCopy() - - if state.Results == nil { - state.Results = map[string]CallResult{} + state = &State{ + Completion: state.Completion, + Pending: state.Pending, + Results: map[string]CallResult{}, } for _, result := range results { diff --git a/pkg/engine/zz_generated.deepcopy.go b/pkg/engine/zz_generated.deepcopy.go deleted file mode 100644 index b1b8c009..00000000 --- a/pkg/engine/zz_generated.deepcopy.go +++ /dev/null @@ -1,40 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -// Code generated by controller-gen. DO NOT EDIT. - -package engine - -import ( - "github.com/acorn-io/gptscript/pkg/types" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *State) DeepCopyInto(out *State) { - *out = *in - in.Completion.DeepCopyInto(&out.Completion) - if in.Pending != nil { - in, out := &in.Pending, &out.Pending - *out = make(map[string]types.CompletionToolCall, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Results != nil { - in, out := &in.Results, &out.Results - *out = make(map[string]CallResult, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new State. -func (in *State) DeepCopy() *State { - if in == nil { - return nil - } - out := new(State) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/types/doc.go b/pkg/types/doc.go deleted file mode 100644 index 281ef8dd..00000000 --- a/pkg/types/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// +k8s:deepcopy-gen=package - -package types diff --git a/pkg/types/jsonschema.go b/pkg/types/jsonschema.go index 575fdc01..a89c59dd 100644 --- a/pkg/types/jsonschema.go +++ b/pkg/types/jsonschema.go @@ -1,5 +1,3 @@ -// +k8s:deepcopy-gen=package - package types import "encoding/json" diff --git a/pkg/types/zz_generated.deepcopy.go b/pkg/types/zz_generated.deepcopy.go deleted file mode 100644 index 0893e459..00000000 --- a/pkg/types/zz_generated.deepcopy.go +++ /dev/null @@ -1,308 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -// Code generated by controller-gen. DO NOT EDIT. - -package types - -import () - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CompletionFunctionCall) DeepCopyInto(out *CompletionFunctionCall) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompletionFunctionCall. -func (in *CompletionFunctionCall) DeepCopy() *CompletionFunctionCall { - if in == nil { - return nil - } - out := new(CompletionFunctionCall) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CompletionFunctionDefinition) DeepCopyInto(out *CompletionFunctionDefinition) { - *out = *in - if in.Parameters != nil { - in, out := &in.Parameters, &out.Parameters - *out = new(JSONSchema) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompletionFunctionDefinition. -func (in *CompletionFunctionDefinition) DeepCopy() *CompletionFunctionDefinition { - if in == nil { - return nil - } - out := new(CompletionFunctionDefinition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CompletionMessage) DeepCopyInto(out *CompletionMessage) { - *out = *in - if in.Content != nil { - in, out := &in.Content, &out.Content - *out = make([]ContentPart, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.ToolCall != nil { - in, out := &in.ToolCall, &out.ToolCall - *out = new(CompletionToolCall) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompletionMessage. -func (in *CompletionMessage) DeepCopy() *CompletionMessage { - if in == nil { - return nil - } - out := new(CompletionMessage) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CompletionRequest) DeepCopyInto(out *CompletionRequest) { - *out = *in - if in.Tools != nil { - in, out := &in.Tools, &out.Tools - *out = make([]CompletionTool, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Messages != nil { - in, out := &in.Messages, &out.Messages - *out = make([]CompletionMessage, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Cache != nil { - in, out := &in.Cache, &out.Cache - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompletionRequest. -func (in *CompletionRequest) DeepCopy() *CompletionRequest { - if in == nil { - return nil - } - out := new(CompletionRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CompletionTool) DeepCopyInto(out *CompletionTool) { - *out = *in - in.Function.DeepCopyInto(&out.Function) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompletionTool. -func (in *CompletionTool) DeepCopy() *CompletionTool { - if in == nil { - return nil - } - out := new(CompletionTool) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CompletionToolCall) DeepCopyInto(out *CompletionToolCall) { - *out = *in - if in.Index != nil { - in, out := &in.Index, &out.Index - *out = new(int) - **out = **in - } - out.Function = in.Function -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompletionToolCall. -func (in *CompletionToolCall) DeepCopy() *CompletionToolCall { - if in == nil { - return nil - } - out := new(CompletionToolCall) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ContentPart) DeepCopyInto(out *ContentPart) { - *out = *in - if in.ToolCall != nil { - in, out := &in.ToolCall, &out.ToolCall - *out = new(CompletionToolCall) - (*in).DeepCopyInto(*out) - } - if in.Image != nil { - in, out := &in.Image, &out.Image - *out = new(ImageURL) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContentPart. -func (in *ContentPart) DeepCopy() *ContentPart { - if in == nil { - return nil - } - out := new(ContentPart) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ImageURL) DeepCopyInto(out *ImageURL) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageURL. -func (in *ImageURL) DeepCopy() *ImageURL { - if in == nil { - return nil - } - out := new(ImageURL) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JSONSchema) DeepCopyInto(out *JSONSchema) { - *out = *in - in.Property.DeepCopyInto(&out.Property) - if in.Properties != nil { - in, out := &in.Properties, &out.Properties - *out = make(map[string]Property, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Required != nil { - in, out := &in.Required, &out.Required - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Defs != nil { - in, out := &in.Defs, &out.Defs - *out = make(map[string]JSONSchema, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchema. -func (in *JSONSchema) DeepCopy() *JSONSchema { - if in == nil { - return nil - } - out := new(JSONSchema) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Property) DeepCopyInto(out *Property) { - *out = *in - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]JSONSchema, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Property. -func (in *Property) DeepCopy() *Property { - if in == nil { - return nil - } - out := new(Property) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Tool) DeepCopyInto(out *Tool) { - *out = *in - if in.Arguments != nil { - in, out := &in.Arguments, &out.Arguments - *out = new(JSONSchema) - (*in).DeepCopyInto(*out) - } - if in.Tools != nil { - in, out := &in.Tools, &out.Tools - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Cache != nil { - in, out := &in.Cache, &out.Cache - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tool. -func (in *Tool) DeepCopy() *Tool { - if in == nil { - return nil - } - out := new(Tool) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in ToolSet) DeepCopyInto(out *ToolSet) { - { - in := &in - *out = make(ToolSet, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ToolSet. -func (in ToolSet) DeepCopy() ToolSet { - if in == nil { - return nil - } - out := new(ToolSet) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in Type) DeepCopyInto(out *Type) { - { - in := &in - *out = make(Type, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Type. -func (in Type) DeepCopy() Type { - if in == nil { - return nil - } - out := new(Type) - in.DeepCopyInto(out) - return *out -} diff --git a/tools/header.txt b/tools/header.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/tools/vendor.go b/tools/vendor.go deleted file mode 100644 index 4b4dbffa..00000000 --- a/tools/vendor.go +++ /dev/null @@ -1,6 +0,0 @@ -package tools - -import ( - // Needed for go generate deepcopy - _ "github.com/acorn-io/baaah/pkg/deepcopy" -) From ce79ae089f7f562f7b5a577637721c1f9ed48fe7 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 2 Feb 2024 22:13:12 -0700 Subject: [PATCH 014/774] Add sys.http.get and sys.http.post --- pkg/builtin/builtin.go | 78 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 0c517e89..309508f4 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -2,11 +2,12 @@ package builtin import ( "context" - "encoding/base64" "encoding/json" "fmt" + "io" + "net/http" "os" - "unicode/utf8" + "strings" "github.com/acorn-io/gptscript/pkg/types" ) @@ -30,10 +31,7 @@ var Tools = map[string]types.Tool{ return "", err } - if utf8.Valid(data) { - return string(data), nil - } - return base64.StdEncoding.EncodeToString(data), nil + return string(data), nil }, }, "sys.write": { @@ -57,6 +55,74 @@ var Tools = map[string]types.Tool{ return "", os.WriteFile(params.Filename, data, 0644) }, }, + "sys.http.get": { + Description: "Download the contents of a http or https URL", + Arguments: types.ObjectSchema( + "url", "The URL to download"), + BuiltinFunc: func(ctx context.Context, env []string, input string) (string, error) { + var params struct { + URL string `json:"url,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + log.Debugf("http get %s", params.URL) + resp, err := http.Get(params.URL) + if err != nil { + return "", err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("failed to download %s: %s", params.URL, resp.Status) + } + + data, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return string(data), nil + }, + }, + "sys.http.post": { + Description: "Write contents to a http or https URL using the POST method", + Arguments: types.ObjectSchema( + "url", "The URL to POST to", + "content", "The content to POST", + "contentType", "The \"content type\" of the content such as application/json or text/plain"), + BuiltinFunc: func(ctx context.Context, env []string, input string) (string, error) { + var params struct { + URL string `json:"url,omitempty"` + Content string `json:"content,omitempty"` + ContentType string `json:"contentType,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, params.URL, strings.NewReader(params.Content)) + if err != nil { + return "", err + } + if params.ContentType != "" { + req.Header.Set("Content-Type", params.ContentType) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + _, _ = io.ReadAll(resp.Body) + if resp.StatusCode > 399 { + return "", fmt.Errorf("failed to post %s: %s", params.URL, resp.Status) + } + + return fmt.Sprintf("Wrote %d to %s", len([]byte(params.Content)), params.URL), nil + }, + }, } func Builtin(name string) (types.Tool, bool) { From f82253a7834f4ead3f544191646985718f45f47e Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 3 Feb 2024 23:00:01 -0700 Subject: [PATCH 015/774] Change output to be log based --- go.mod | 11 -- go.sum | 74 --------- pkg/cli/gptscript.go | 13 ++ pkg/engine/engine.go | 47 +++--- pkg/monitor/display.go | 343 ++++++++++++++++++----------------------- pkg/monitor/log.go | 5 + pkg/mvl/log.go | 42 +++-- pkg/openai/client.go | 18 ++- pkg/runner/monitor.go | 2 +- pkg/runner/runner.go | 192 +++++++++++++---------- 10 files changed, 345 insertions(+), 402 deletions(-) create mode 100644 pkg/monitor/log.go diff --git a/go.mod b/go.mod index 37a19a55..6be6189a 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb github.com/adrg/xdg v0.4.0 github.com/hexops/autogold/v2 v2.1.0 - github.com/pterm/pterm v0.12.76 github.com/sashabaranov/go-openai v1.18.3 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 @@ -23,33 +22,23 @@ require ( ) require ( - atomicgo.dev/cursor v0.2.0 // indirect - atomicgo.dev/keyboard v0.2.9 // indirect - atomicgo.dev/schedule v0.1.0 // indirect github.com/bombsimon/logrusr/v4 v4.0.0 // indirect - github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.15.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect - github.com/gookit/color v1.5.4 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/hexops/valast v1.4.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect github.com/nightlyone/lockfile v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/samber/lo v1.38.1 // indirect github.com/samber/slog-logrus v1.0.0 // indirect - github.com/sergi/go-diff v1.3.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sys v0.16.0 // indirect diff --git a/go.sum b/go.sum index f8dbc8c9..241e8229 100644 --- a/go.sum +++ b/go.sum @@ -1,32 +1,11 @@ -atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg= -atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ= -atomicgo.dev/cursor v0.2.0 h1:H6XN5alUJ52FZZUkI7AlJbUc1aW38GWZalpYRPpoPOw= -atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU= -atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8= -atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= -atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= -atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= -github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= -github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= -github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= -github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k= -github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI= -github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= -github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= -github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4= -github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc4n3EjyIYvEY= github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd h1:Zbau2J6sEPl1H4gqnEx4/TI55eZncQR5cjfPOcG2lxE= github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd/go.mod h1:13nTO3svO8zTD3j9E5c86tCtK5YrKsK5sxca4Lwkbc0= github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb h1:UVs3i5r0bOh3KEZV5dTsSQzG4MG/8F0m+dcYIzXOO5I= github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb/go.mod h1:J0xhtXVfrJk3Fz1HYz3AoJ/ON9gaHu/baTkqOvywcfo= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= -github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/bombsimon/logrusr/v4 v4.0.0 h1:Pm0InGphX0wMhPqC02t31onlq9OVyJ98eP/Vh63t1Oo= github.com/bombsimon/logrusr/v4 v4.0.0/go.mod h1:pjfHC5e59CvjTBIU3V3sGhFWFAnsnhOR03TRc6im0l8= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -52,10 +31,6 @@ github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYd github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= -github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= -github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= -github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/hexops/autogold v0.8.1/go.mod h1:97HLDXyG23akzAoRYJh/2OBs3kd80eHyKPvZw0S5ZBY= github.com/hexops/autogold v1.3.1 h1:YgxF9OHWbEIUjhDbpnLhgVsjUDsiHDTyDfy2lrfdlzo= github.com/hexops/autogold v1.3.1/go.mod h1:sQO+mQUCVfxOKPht+ipDSkJ2SCJ7BNJVHZexsXqWMx4= @@ -67,11 +42,6 @@ github.com/hexops/valast v1.4.3 h1:oBoGERMJh6UZdRc6cduE1CTPK+VAdXA59Y1HFgu3sm0= github.com/hexops/valast v1.4.3/go.mod h1:Iqx2kLj3Jn47wuXpj3wX40xn6F93QNFBHuiKBerkTGA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -80,8 +50,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= -github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -90,9 +58,6 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/nightlyone/lockfile v1.0.0 h1:RHep2cFKK4PonZJDdEl4GmkabuhbsRMgk/k3uAmxBiA= github.com/nightlyone/lockfile v1.0.0/go.mod h1:rywoIealpdNse2r832aiD9jRk8ErCatROs6LzC841CI= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= @@ -102,18 +67,6 @@ github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8P github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= -github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= -github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= -github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU= -github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= -github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= -github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= -github.com/pterm/pterm v0.12.76 h1:x1gbA2c7mJEd0PjJP3EYN04PR1DVrE3Z8sRDMP+qH6g= -github.com/pterm/pterm v0.12.76/go.mod h1:1v/gzOF1N0FsjbgTHZ1wVycRkKiatFvJSJC4IGaQAAo= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= @@ -125,9 +78,6 @@ github.com/samber/slog-logrus v1.0.0 h1:SsrN0p9akjCEaYd42Q5GtisMdHm0q11UD4fp4XCZ github.com/samber/slog-logrus v1.0.0/go.mod h1:ZTdPCmVWljwlfjz6XflKNvW4TcmYlexz4HMUOO/42bI= github.com/sashabaranov/go-openai v1.18.3 h1:dspFGkmZbhjg1059KhqLYSV2GaCiRIn+bOu50TlXUq8= github.com/sashabaranov/go-openai v1.18.3/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= @@ -135,14 +85,9 @@ github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyh 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -150,14 +95,12 @@ golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcH golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -170,59 +113,42 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20211013075003-97ac67df715c/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-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -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-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 3c587e73..29e5c576 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -28,6 +28,7 @@ type GPTScript struct { runner.Options DisplayOptions Debug bool `usage:"Enable debug logging"` + Quiet bool `usage:"No output logging" short:"q"` Output string `usage:"Save output to a file" short:"o"` Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"` SubTool string `usage:"Use tool of this name, not the first tool in file"` @@ -65,6 +66,11 @@ func (r *GPTScript) listModels(ctx context.Context) error { func (r *GPTScript) Pre(cmd *cobra.Command, args []string) error { if r.Debug { mvl.SetDebug() + } else { + mvl.SetSimpleFormat() + } + if r.Quiet { + mvl.SetError() } return nil } @@ -128,6 +134,13 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return err } } else { + if !r.Quiet { + if toolInput != "" { + _, _ = fmt.Fprintln(os.Stderr, "\nINPUT:\n") + _, _ = fmt.Fprintln(os.Stderr, toolInput) + } + _, _ = fmt.Fprintln(os.Stderr, "\nOUTPUT:\n") + } fmt.Print(s) if !strings.HasSuffix(s, "\n") { fmt.Println() diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index b63f5c2b..90ebc73f 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -7,7 +7,6 @@ import ( "fmt" "os" "os/exec" - "sort" "strings" "sync" "sync/atomic" @@ -77,6 +76,13 @@ type Context struct { Tool types.Tool } +func (c *Context) ParentID() string { + if c.Parent == nil { + return "" + } + return c.Parent.ID +} + func (c *Context) UnmarshalJSON(data []byte) error { panic("this data struct is circular by design and can not be read from json") } @@ -327,12 +333,10 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu } var ( - added bool - pendingToolCalls []types.CompletionToolCall + added bool ) for id, pending := range state.Pending { - pendingToolCalls = append(pendingToolCalls, pending) if _, ok := state.Results[id]; !ok { ret.Calls[id] = Call{ ToolName: pending.Function.Name, @@ -345,25 +349,28 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu return &ret, nil } - sort.Slice(pendingToolCalls, func(i, j int) bool { - left := pendingToolCalls[i].Function.Name + pendingToolCalls[i].Function.Arguments - right := pendingToolCalls[j].Function.Name + pendingToolCalls[j].Function.Arguments - if left == right { - return pendingToolCalls[i].ID < pendingToolCalls[j].ID + for _, content := range state.Completion.Messages[len(state.Completion.Messages)-1].Content { + if content.ToolCall == nil { + continue + } + result, ok := state.Results[content.ToolCall.ID] + if !ok { + return nil, fmt.Errorf("missing tool call result for id %s, most likely a %s BUG", + content.ToolCall.ID, version.ProgramName) } - return left < right - }) - for _, pending := range pendingToolCalls { - pending := pending - if result, ok := state.Results[pending.ID]; ok { - added = true - state.Completion.Messages = append(state.Completion.Messages, types.CompletionMessage{ - Role: types.CompletionMessageRoleTypeTool, - Content: types.Text(result.Result), - ToolCall: &pending, - }) + pending, ok := state.Pending[content.ToolCall.ID] + if !ok { + return nil, fmt.Errorf("missing tool call pennding for id %s, most likely a %s BUG", + content.ToolCall.ID, version.ProgramName) } + + added = true + state.Completion.Messages = append(state.Completion.Messages, types.CompletionMessage{ + Role: types.CompletionMessageRoleTypeTool, + Content: types.Text(result.Result), + ToolCall: &pending, + }) } if !added { diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index 301d2388..144d9ea7 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -3,59 +3,125 @@ package monitor import ( "context" "encoding/json" + "fmt" "io" "os" + "sort" "strings" + "sync/atomic" "time" - "github.com/acorn-io/gptscript/pkg/engine" "github.com/acorn-io/gptscript/pkg/runner" "github.com/acorn-io/gptscript/pkg/types" - "github.com/pterm/pterm" ) type Options struct { - Quiet bool `usage:"Do not print status" short:"q"` - DumpState string `usage:"Dump the internal execution state to a file"` - ShowFinished bool `usage:"Show finished calls results"` + DumpState string `usage:"Dump the internal execution state to a file"` } func complete(opts ...Options) (result Options) { for _, opt := range opts { result.DumpState = types.FirstSet(opt.DumpState, result.DumpState) - result.Quiet = types.FirstSet(opt.Quiet, result.Quiet) - result.ShowFinished = types.FirstSet(opt.ShowFinished, result.ShowFinished) } return } type Console struct { - quiet bool - dumpState string - showFinished bool + dumpState string } +var runID int64 + func (c *Console) Start(ctx context.Context, prg *types.Program, env []string, input string) (runner.Monitor, error) { - mon := newDisplay(c.quiet, c.showFinished, c.dumpState) - return mon, mon.Start(ctx) + id := atomic.AddInt64(&runID, 1) + mon := newDisplay(c.dumpState) + mon.dump.ID = fmt.Sprint(id) + mon.dump.Program = prg + mon.dump.Input = input + + log.Fields("runID", mon.dump.ID, "input", input).Debugf("Run started") + return mon, nil } type display struct { - progress chan runner.Event - states []state - done chan struct{} - area *pterm.AreaPrinter - quiet bool - showFinished bool - dumpState string + dump dump + dumpState string } func (d *display) Event(event runner.Event) { - d.progress <- event + var ( + currentIndex = -1 + currentCall call + ) + + for i, existing := range d.dump.Calls { + if event.CallContext.ID == existing.ID { + currentIndex = i + currentCall = existing + break + } + } + + if currentIndex == -1 { + currentIndex = len(d.dump.Calls) + currentCall = call{ + ID: event.CallContext.ID, + ParentID: event.CallContext.ParentID(), + ToolID: event.CallContext.Tool.ID, + } + d.dump.Calls = append(d.dump.Calls, currentCall) + } + + log := log.Fields( + "id", currentCall.ID, + "parentID", currentCall.ParentID, + "toolID", currentCall.ToolID) + + callName := callName{ + call: ¤tCall, + prg: d.dump.Program, + calls: d.dump.Calls, + } + + switch event.Type { + case runner.EventTypeCallStart: + currentCall.Start = event.Time + currentCall.Input = event.Content + log.Fields("input", event.Content).Infof("%s started", callName) + case runner.EventTypeCallProgress: + case runner.EventTypeCallContinue: + log.Fields("toolResults", event.ToolResults).Infof("%s continue", callName) + case runner.EventTypeChat: + if event.ChatRequest == nil { + log = log.Fields( + "response", toJSON(event.ChatResponse), + "cached", event.ChatResponseCached, + ) + } else { + log.Infof("%s openai request sent", callName) + log = log.Fields( + "request", toJSON(event.ChatRequest), + ) + } + log.Debugf("messages") + currentCall.Messages = append(currentCall.Messages, message{ + Request: event.ChatRequest, + Response: event.ChatResponse, + Cached: event.ChatResponseCached, + }) + case runner.EventTypeCallFinish: + currentCall.End = event.Time + currentCall.Output = event.Content + log.Fields("output", event.Content).Infof("%s ended", callName) + } + + d.dump.Calls[currentIndex] = currentCall } -func (d *display) Stop() { - d.stop() +func (d *display) Stop(output string, err error) { + log.Fields("runID", d.dump.ID, "output", output, "err", err).Debugf("Run stopped") + d.dump.Output = output + d.dump.Err = err if d.dumpState != "" { f, err := os.Create(d.dumpState) if err == nil { @@ -68,211 +134,96 @@ func (d *display) Stop() { func NewConsole(opts ...Options) *Console { opt := complete(opts...) return &Console{ - quiet: opt.Quiet, - dumpState: opt.DumpState, - showFinished: opt.ShowFinished, + dumpState: opt.DumpState, } } -func newDisplay(quiet, showFinished bool, dumpState string) *display { +func newDisplay(dumpState string) *display { return &display{ - quiet: quiet, - showFinished: showFinished, - dumpState: dumpState, + dumpState: dumpState, } } -func (d *display) Start(ctx context.Context) (err error) { - if !d.quiet { - d.area, err = pterm.DefaultArea. - //WithFullscreen(true). - //WithRemoveWhenDone(true). - Start("Starting...") - if err != nil { - return err - } - } - - d.progress = make(chan runner.Event) - d.done = make(chan struct{}) - go func() { - t := time.NewTicker(time.Second) - defer t.Stop() - for { - select { - case <-t.C: - d.print() - case <-d.done: - return - } - } - }() - go func() { - for msg := range d.progress { - d.addEvent(msg) - } - close(d.done) - }() - return nil -} - func (d *display) Dump(out io.Writer) error { enc := json.NewEncoder(out) enc.SetIndent("", " ") - return enc.Encode(struct { - State []state `json:"state,omitempty"` - }{ - State: d.states, - }) + return enc.Encode(d.dump) } -func (d *display) stop() { - close(d.progress) - <-d.done - if d.area != nil { - _ = d.area.Stop() - } +func toJSON(obj any) jsonDump { + return jsonDump{obj: obj} } -func splitCount(line string, length int) (head, tail string) { - if len(line) < length { - return line, "" - } - return line[:length], line[length:] +type jsonDump struct { + obj any } -func multiLineWrite(out io.StringWriter, prefix, lines string) { - if lines == "" { - _, _ = out.WriteString("\n") - } - width := pterm.GetTerminalWidth() - for _, line := range strings.Split(lines, "\n") { - line = prefix + line - for { - head, tail := splitCount(line, width) - _, _ = out.WriteString(head) - _, _ = out.WriteString("\n") - - if tail == "" { - break - } - line = prefix + tail - } +func (j jsonDump) String() string { + d, err := json.Marshal(j.obj) + if err != nil { + return err.Error() } + return string(d) } -func (d *display) printState(s state, depth int) string { - if !d.showFinished && !s.Running { - return "" - } +type callName struct { + call *call + prg *types.Program + calls []call +} - buf := &strings.Builder{} - prefix := strings.Repeat(" ", depth) - inPrefix := prefix + " |<- " - outPrefix := prefix + " |-> " +func (c callName) String() string { + var ( + msg []string + currentCall = c.call + ) - buf.WriteString(prefix) - name := s.Context.Tool.Name - if name == "" { - name = "main" - } - if s.Running { - buf.WriteString("(running ") - buf.WriteString(name) - buf.WriteString(")\n") - if s.Input != "" { - multiLineWrite(buf, inPrefix, "args: "+s.Input) - } - } else { - buf.WriteString("(done ") - buf.WriteString(name) - buf.WriteString(") ") - buf.WriteString("args: ") - head, tail := splitCount(s.Input, 40) - buf.WriteString(head) - if tail != "" { - buf.WriteString("...") + for { + tool := c.prg.ToolSet[currentCall.ToolID] + name := tool.Name + if name == "" { + name = tool.Source.File } - buf.WriteString("\n") - } - - childRunning := false - for _, state := range d.states { - if state.Context != nil && state.Context.Parent != nil && state.Context.Parent.ID == s.Context.ID { - if state.Running { - childRunning = true + msg = append(msg, name) + found := false + for _, parent := range c.calls { + if parent.ID == currentCall.ParentID { + found = true + currentCall = &parent + break } - buf.WriteString(d.printState(state, depth+1)) } - } - - if depth == 0 && !childRunning { - if len(s.Input) > 0 && len(s.Output) > 0 { - multiLineWrite(buf, outPrefix, "---") + if !found { + break } - - multiLineWrite(buf, outPrefix, s.Output) } - return buf.String() -} - -func (d *display) print() { - if d.quiet { - return - } - d.area.Update(d.String() + "\n") + sort.Sort(sort.Reverse(sort.StringSlice(msg))) + return strings.Join(msg, "->") } -func (d *display) String() string { - buf := strings.Builder{} - if len(d.states) > 0 { - buf.WriteString(d.printState(d.states[0], 0)) - } - - return buf.String() +type dump struct { + ID string `json:"id,omitempty"` + Program *types.Program `json:"program,omitempty"` + Calls []call `json:"calls,omitempty"` + Input string `json:"input,omitempty"` + Output string `json:"output,omitempty"` + Err error `json:"err,omitempty"` } -func (d *display) addEvent(msg runner.Event) { - found := false - for i, state := range d.states { - if state.Context.ID != msg.Context.ID { - continue - } - found = true - switch msg.Type { - case runner.EventTypeUpdate: - state.Output = msg.Content - case runner.EventTypeStop: - state.Running = false - state.Output = msg.Content - state.End = msg.Time - case runner.EventTypeDebug: - state.Debug = append(state.Debug, msg.Debug) - } - d.states[i] = state - } - if !found && msg.Type == runner.EventTypeStart { - d.states = append(d.states, state{ - Context: msg.Context, - Running: true, - Start: msg.Time, - Input: msg.Content, - }) - } else if !found { - enc := json.NewEncoder(os.Stderr) - enc.SetIndent("", " ") - enc.Encode(msg) - panic("why?") - } +type message struct { + Request any `json:"request,omitempty"` + Response any `json:"response,omitempty"` + Cached bool `json:"cached,omitempty"` } -type state struct { - Context *engine.Context `json:"context,omitempty"` - Debug []any `json:"debug,omitempty"` - Running bool `json:"running,omitempty"` - Start time.Time `json:"start,omitempty"` - End time.Time `json:"end,omitempty"` - Input string `json:"input,omitempty"` - Output string `json:"output,omitempty"` +type call struct { + ID string `json:"id,omitempty"` + ParentID string `json:"parentID,omitempty"` + ToolID string `json:"toolID,omitempty"` + Messages []message `json:"messages,omitempty"` + Start time.Time `json:"start,omitempty"` + End time.Time `json:"end,omitempty"` + Input string `json:"input,omitempty"` + Output string `json:"output,omitempty"` } diff --git a/pkg/monitor/log.go b/pkg/monitor/log.go new file mode 100644 index 00000000..36a8d5aa --- /dev/null +++ b/pkg/monitor/log.go @@ -0,0 +1,5 @@ +package monitor + +import "github.com/acorn-io/gptscript/pkg/mvl" + +var log = mvl.Package() diff --git a/pkg/mvl/log.go b/pkg/mvl/log.go index 8c2e5df3..915a7c9a 100644 --- a/pkg/mvl/log.go +++ b/pkg/mvl/log.go @@ -1,8 +1,10 @@ package mvl import ( + "fmt" "runtime" "strings" + "time" "github.com/sirupsen/logrus" ) @@ -13,10 +15,28 @@ import ( // So this is simple place to make a better decision later about logging frameworks. I only care about // the interface, not the implementation. Smarter people do that well. +func SetSimpleFormat() { + logrus.SetFormatter(&formatter{}) +} + +type formatter struct { +} + +func (f formatter) Format(entry *logrus.Entry) ([]byte, error) { + return []byte(fmt.Sprintf("%s %s %s\n", + entry.Time.Format(time.RFC3339), + entry.Level, + entry.Message)), nil +} + func SetDebug() { logrus.SetLevel(logrus.DebugLevel) } +func SetError() { + logrus.SetLevel(logrus.ErrorLevel) +} + func Package() Logger { _, p, _, _ := runtime.Caller(1) _, suffix, _ := strings.Cut(p, "gptscript/") @@ -25,19 +45,19 @@ func Package() Logger { } func New(name string) Logger { - var prefix string + var fields logrus.Fields if name != "" { - prefix = name + ": " + fields = logrus.Fields{ + "logger": name, + } } return Logger{ - prefix: prefix, log: logrus.StandardLogger(), - fields: logrus.Fields{}, + fields: fields, } } type Logger struct { - prefix string log *logrus.Logger fields logrus.Fields } @@ -51,7 +71,6 @@ func (l *Logger) FieldsMap(kv map[string]any) *Logger { newFields[k] = v } return &Logger{ - prefix: l.prefix, log: l.log, fields: newFields, } @@ -68,28 +87,27 @@ func (l *Logger) Fields(kv ...any) *Logger { } } return &Logger{ - prefix: l.prefix, log: l.log, fields: newFields, } } func (l *Logger) Infof(msg string, args ...any) { - l.log.WithFields(l.fields).Infof(l.prefix+msg, args...) + l.log.WithFields(l.fields).Infof(msg, args...) } func (l *Logger) Errorf(msg string, args ...any) { - l.log.WithFields(l.fields).Errorf(l.prefix+msg, args...) + l.log.WithFields(l.fields).Errorf(msg, args...) } func (l *Logger) Tracef(msg string, args ...any) { - l.log.WithFields(l.fields).Tracef(l.prefix+msg, args...) + l.log.WithFields(l.fields).Tracef(msg, args...) } func (l *Logger) Debugf(msg string, args ...any) { - l.log.WithFields(l.fields).Debugf(l.prefix+msg, args...) + l.log.WithFields(l.fields).Debugf(msg, args...) } func (l *Logger) Fatalf(msg string, args ...any) { - l.log.WithFields(l.fields).Fatalf(l.prefix+msg, args...) + l.log.WithFields(l.fields).Fatalf(msg, args...) } diff --git a/pkg/openai/client.go b/pkg/openai/client.go index bd952caa..a8c5cba1 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -231,10 +231,11 @@ func toMessages(ctx context.Context, cache *cache.Client, request types.Completi } type Status struct { - Request any `json:"request,omitempty"` - Response any `json:"response,omitempty"` - Chunks any `json:"-"` - PartialResponse *types.CompletionMessage `json:"partialResponse,omitempty"` + Request any + Response any + Cached bool + Chunks any + PartialResponse *types.CompletionMessage } func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- Status) (*types.CompletionMessage, error) { @@ -280,6 +281,11 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } } + status <- Status{ + Request: request, + } + + var cacheResponse bool request.Seed = ptr(c.seed(request)) response, ok, err := c.fromCache(ctx, messageRequest, request) if err != nil { @@ -289,6 +295,8 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques if err != nil { return nil, err } + } else { + cacheResponse = true } result := types.CompletionMessage{} @@ -297,9 +305,9 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } status <- Status{ - Request: request, Chunks: response, Response: result, + Cached: cacheResponse, } return &result, nil diff --git a/pkg/runner/monitor.go b/pkg/runner/monitor.go index 69c4d092..db228196 100644 --- a/pkg/runner/monitor.go +++ b/pkg/runner/monitor.go @@ -19,5 +19,5 @@ type noopMonitor struct { func (n noopMonitor) Event(event Event) { } -func (n noopMonitor) Stop() { +func (n noopMonitor) Stop(output string, err error) { } diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 6192bd12..55c0dbc9 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -2,7 +2,6 @@ package runner import ( "context" - "strings" "sync" "time" @@ -19,7 +18,7 @@ type MonitorFactory interface { type Monitor interface { Event(event Event) - Stop() + Stop(output string, err error) } type ( @@ -70,36 +69,43 @@ func New(opts ...Options) (*Runner, error) { }, nil } -func (r *Runner) Run(ctx context.Context, prg types.Program, env []string, input string) (string, error) { +func (r *Runner) Run(ctx context.Context, prg types.Program, env []string, input string) (output string, err error) { monitor, err := r.factory.Start(ctx, &prg, env, input) if err != nil { return "", err } - defer monitor.Stop() + defer func() { + monitor.Stop(output, err) + }() callCtx := engine.NewContext(ctx, &prg) return r.call(callCtx, monitor, env, input) } type Event struct { - Time time.Time - Context *engine.Context - Type EventType - Debug any - Content string + Time time.Time + CallContext *engine.Context + ToolResults int + Type EventType + ChatRequest any + ChatResponse any + ChatResponseCached bool + Content string } type EventType string var ( - EventTypeStart = EventType("start") - EventTypeUpdate = EventType("progress") - EventTypeDebug = EventType("debug") - EventTypeStop = EventType("stop") + EventTypeCallStart = EventType("callStart") + EventTypeCallContinue = EventType("callContinue") + EventTypeCallProgress = EventType("callProgress") + EventTypeChat = EventType("callChat") + EventTypeCallFinish = EventType("callFinish") ) func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, input string) (string, error) { - progress := make(chan openai.Status) + progress, progressClose := streamProgress(&callCtx, monitor) + defer progressClose() e := engine.Engine{ Client: r.c, @@ -107,40 +113,11 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp Env: env, } - wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - for status := range progress { - if message := status.PartialResponse; message != nil { - content := message.String() - if strings.TrimSpace(content) != "" && !strings.Contains(content, "Sent content:") { - content += "\n\nModel responding..." - } - monitor.Event(Event{ - Time: time.Now(), - Context: &callCtx, - Type: EventTypeUpdate, - Content: content, - }) - } else { - monitor.Event(Event{ - Time: time.Now(), - Context: &callCtx, - Type: EventTypeDebug, - Debug: status, - }) - } - } - }() - defer wg.Wait() - defer close(progress) - monitor.Event(Event{ - Time: time.Now(), - Context: &callCtx, - Type: EventTypeStart, - Content: input, + Time: time.Now(), + CallContext: &callCtx, + Type: EventTypeCallStart, + Content: input, }) result, err := e.Start(callCtx, input) @@ -151,52 +128,101 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp for { if result.Result != nil && len(result.Calls) == 0 { monitor.Event(Event{ - Time: time.Now(), - Context: &callCtx, - Type: EventTypeStop, - Content: *result.Result, + Time: time.Now(), + CallContext: &callCtx, + Type: EventTypeCallFinish, + Content: *result.Result, }) return *result.Result, nil } - var ( - callResults []engine.CallResult - resultLock sync.Mutex - ) - - eg, subCtx := errgroup.WithContext(callCtx.Ctx) - for id, call := range result.Calls { - id := id - call := call - eg.Go(func() error { - callCtx, err := callCtx.SubCall(subCtx, call.ToolName, id) - if err != nil { - return err - } - - result, err := r.call(callCtx, monitor, env, call.Input) - if err != nil { - return err - } - - resultLock.Lock() - defer resultLock.Unlock() - callResults = append(callResults, engine.CallResult{ - ID: id, - Result: result, - }) - - return nil - }) - } - - if err := eg.Wait(); err != nil { + callResults, err := r.subCalls(callCtx, monitor, env, result) + if err != nil { return "", err } + monitor.Event(Event{ + Time: time.Now(), + CallContext: &callCtx, + Type: EventTypeCallContinue, + ToolResults: len(callResults), + }) + result, err = e.Continue(callCtx.Ctx, result.State, callResults...) if err != nil { return "", err } } } + +func streamProgress(callCtx *engine.Context, monitor Monitor) (chan openai.Status, func()) { + progress := make(chan openai.Status) + + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + for status := range progress { + if message := status.PartialResponse; message != nil { + monitor.Event(Event{ + Time: time.Now(), + CallContext: callCtx, + Type: EventTypeCallProgress, + Content: message.String(), + }) + } else { + monitor.Event(Event{ + Time: time.Now(), + CallContext: callCtx, + Type: EventTypeChat, + ChatRequest: status.Request, + ChatResponse: status.Response, + ChatResponseCached: status.Cached, + }) + } + } + }() + + return progress, func() { + close(progress) + wg.Wait() + } +} + +func (r *Runner) subCalls(callCtx engine.Context, monitor Monitor, env []string, lastReturn *engine.Return) (callResults []engine.CallResult, _ error) { + var ( + resultLock sync.Mutex + ) + + eg, subCtx := errgroup.WithContext(callCtx.Ctx) + for id, call := range lastReturn.Calls { + id := id + call := call + eg.Go(func() error { + callCtx, err := callCtx.SubCall(subCtx, call.ToolName, id) + if err != nil { + return err + } + + result, err := r.call(callCtx, monitor, env, call.Input) + if err != nil { + return err + } + + resultLock.Lock() + defer resultLock.Unlock() + callResults = append(callResults, engine.CallResult{ + ID: id, + Result: result, + }) + + return nil + }) + } + + if err := eg.Wait(); err != nil { + return nil, err + } + + return +} From 449cbe1f6fb8b674d67c3179456a0c44c6e952fc Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sun, 4 Feb 2024 21:13:46 -0700 Subject: [PATCH 016/774] Small script tweaks --- examples/fib.gpt | 28 ++++++++++++++++++++++------ pkg/monitor/display.go | 23 +++++++++++++++++------ pkg/mvl/log.go | 32 +++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/examples/fib.gpt b/examples/fib.gpt index 0bc95a86..3551e4b7 100644 --- a/examples/fib.gpt +++ b/examples/fib.gpt @@ -3,13 +3,29 @@ What's the myfunction of 3 --- name: myfunction +tools: sub, mul description: A function taking an integer as argument and returns an integer args: number: An integer tools: myfunction -Do the following steps in strict sequence: -Step 1. If ${number} is 0, skip the remaining steps and return 1 -Step 2. Calculate ${number} minus 1 -Step 3. Calculate myfunction of the result of Step 2 -Step 4. Multiply result of Step 3 with ${number} -Step 5. Return the result of Step 4 +If ${number} is 0 return 1. Otherwise return myfunction(${number}-1) * ${number} + +--- +name: sub +description: Subtract two numbers +args: left: a number +args: right: a number + +#!/bin/bash + +echo $((${LEFT} - ${RIGHT})) + +--- +name: mul +description: Multiply two numbers +args: left: a number +args: right: a number + +#!/bin/bash + +echo $((${LEFT} * ${RIGHT})) diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index 144d9ea7..8699458e 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -6,7 +6,7 @@ import ( "fmt" "io" "os" - "sort" + "slices" "strings" "sync/atomic" "time" @@ -87,10 +87,10 @@ func (d *display) Event(event runner.Event) { case runner.EventTypeCallStart: currentCall.Start = event.Time currentCall.Input = event.Content - log.Fields("input", event.Content).Infof("%s started", callName) + log.Fields("input", event.Content).Infof("started [%s]", callName) case runner.EventTypeCallProgress: case runner.EventTypeCallContinue: - log.Fields("toolResults", event.ToolResults).Infof("%s continue", callName) + log.Fields("toolResults", event.ToolResults).Infof("continue [%s]", callName) case runner.EventTypeChat: if event.ChatRequest == nil { log = log.Fields( @@ -98,7 +98,7 @@ func (d *display) Event(event runner.Event) { "cached", event.ChatResponseCached, ) } else { - log.Infof("%s openai request sent", callName) + log.Infof("openai request sent [%s]", callName) log = log.Fields( "request", toJSON(event.ChatRequest), ) @@ -112,7 +112,7 @@ func (d *display) Event(event runner.Event) { case runner.EventTypeCallFinish: currentCall.End = event.Time currentCall.Output = event.Content - log.Fields("output", event.Content).Infof("%s ended", callName) + log.Fields("output", event.Content).Infof("ended [%s]", callName) } d.dump.Calls[currentIndex] = currentCall @@ -158,6 +158,10 @@ type jsonDump struct { obj any } +func (j jsonDump) MarshalJSON() ([]byte, error) { + return json.Marshal(j.obj) +} + func (j jsonDump) String() string { d, err := json.Marshal(j.obj) if err != nil { @@ -184,6 +188,9 @@ func (c callName) String() string { if name == "" { name = tool.Source.File } + if currentCall.ID != "1" { + name += "(" + currentCall.ID + ")" + } msg = append(msg, name) found := false for _, parent := range c.calls { @@ -198,7 +205,7 @@ func (c callName) String() string { } } - sort.Sort(sort.Reverse(sort.StringSlice(msg))) + slices.Reverse(msg) return strings.Join(msg, "->") } @@ -227,3 +234,7 @@ type call struct { Input string `json:"input,omitempty"` Output string `json:"output,omitempty"` } + +func (c call) String() string { + return c.ID +} diff --git a/pkg/mvl/log.go b/pkg/mvl/log.go index 915a7c9a..6e9f7650 100644 --- a/pkg/mvl/log.go +++ b/pkg/mvl/log.go @@ -1,7 +1,9 @@ package mvl import ( + "encoding/json" "fmt" + "os" "runtime" "strings" "time" @@ -23,13 +25,37 @@ type formatter struct { } func (f formatter) Format(entry *logrus.Entry) ([]byte, error) { - return []byte(fmt.Sprintf("%s %s %s\n", + msg := entry.Message + if i, ok := entry.Data["input"].(string); ok && i != "" { + msg += fmt.Sprintf(" [input=%s]", i) + } + return []byte(fmt.Sprintf("%s %s\n", entry.Time.Format(time.RFC3339), - entry.Level, - entry.Message)), nil + msg)), nil +} + +type verbose struct { +} + +func (f verbose) Format(entry *logrus.Entry) ([]byte, error) { + buf, err := json.MarshalIndent(struct { + Time time.Time `json:"time,omitempty"` + Level string `json:"level,omitempty"` + Message string `json:"message,omitempty"` + Data any `json:"data,omitempty"` + }{ + Time: entry.Time, + Level: entry.Level.String(), + Message: entry.Message, + Data: entry.Data, + }, "", " ") + return append(buf, []byte("\n")...), err } func SetDebug() { + logrus.SetFormatter(&logrus.JSONFormatter{ + PrettyPrint: os.Getenv("GPTSCRIPT_JSON_LOG_SINGLE_LINE") != "true", + }) logrus.SetLevel(logrus.DebugLevel) } From 2198b8c6dd86d689f38a08fc099c6c5fb42c5696 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sun, 4 Feb 2024 22:03:09 -0700 Subject: [PATCH 017/774] Update CI scripts --- Makefile | 4 ++++ go.mod | 1 + go.sum | 2 ++ pkg/builtin/builtin.go | 15 +++++++++++++++ pkg/cli/gptscript.go | 4 ++-- pkg/engine/engine.go | 22 +++++++++++++++++++--- pkg/mvl/log.go | 19 ------------------- pkg/test/examples_test.go | 16 +++++++--------- scripts/ci.gpt | 13 ++++--------- 9 files changed, 54 insertions(+), 42 deletions(-) diff --git a/Makefile b/Makefile index 144a2561..42f78b01 100644 --- a/Makefile +++ b/Makefile @@ -4,5 +4,9 @@ build: test: go test -v ./... +validate: + go vet ./... + golangci-lint run + ci: build ./bin/gptscript ./scripts/ci.gpt diff --git a/go.mod b/go.mod index 6be6189a..a0e9f585 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.21.5 require ( github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb github.com/adrg/xdg v0.4.0 + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hexops/autogold/v2 v2.1.0 github.com/sashabaranov/go-openai v1.18.3 github.com/sirupsen/logrus v1.9.3 diff --git a/go.sum b/go.sum index 241e8229..e9bf20c3 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYd github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/hexops/autogold v0.8.1/go.mod h1:97HLDXyG23akzAoRYJh/2OBs3kd80eHyKPvZw0S5ZBY= github.com/hexops/autogold v1.3.1 h1:YgxF9OHWbEIUjhDbpnLhgVsjUDsiHDTyDfy2lrfdlzo= github.com/hexops/autogold v1.3.1/go.mod h1:sQO+mQUCVfxOKPht+ipDSkJ2SCJ7BNJVHZexsXqWMx4= diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 309508f4..b3a15389 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -85,6 +85,21 @@ var Tools = map[string]types.Tool{ return string(data), nil }, }, + "sys.abort": { + Description: "Aborts execution", + Arguments: types.ObjectSchema( + "message", "The description of the error or unexpected result that caused abort to be called", + ), + BuiltinFunc: func(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Message string `json:"message,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + return "", fmt.Errorf("ABORT: %s", params.Message) + }, + }, "sys.http.post": { Description: "Write contents to a http or https URL using the POST method", Arguments: types.ObjectSchema( diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 29e5c576..949f18c6 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -136,10 +136,10 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { } else { if !r.Quiet { if toolInput != "" { - _, _ = fmt.Fprintln(os.Stderr, "\nINPUT:\n") + _, _ = fmt.Fprint(os.Stderr, "\nINPUT:\n\n") _, _ = fmt.Fprintln(os.Stderr, toolInput) } - _, _ = fmt.Fprintln(os.Stderr, "\nOUTPUT:\n") + _, _ = fmt.Fprint(os.Stderr, "\nOUTPUT:\n\n") } fmt.Print(s) if !strings.HasSuffix(s, "\n") { diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 90ebc73f..187471da 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -14,6 +14,7 @@ import ( "github.com/acorn-io/gptscript/pkg/openai" "github.com/acorn-io/gptscript/pkg/types" "github.com/acorn-io/gptscript/pkg/version" + "github.com/google/shlex" ) // InternalSystemPrompt is added to all threads. Changing this is very dangerous as it has a @@ -152,19 +153,24 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) dec := json.NewDecoder(bytes.NewReader([]byte(input))) dec.UseNumber() + envMap := map[string]string{} if err := json.Unmarshal([]byte(input), &data); err == nil { for k, v := range data { - envName := fmt.Sprintf("%s", strings.ToUpper(strings.ReplaceAll(k, "-", "_"))) + envName := strings.ToUpper(strings.ReplaceAll(k, "-", "_")) switch val := v.(type) { case string: + envMap[envName] = val env = append(env, envName+"="+val) case json.Number: + envMap[envName] = string(val) env = append(env, envName+"="+string(val)) case bool: + envMap[envName] = fmt.Sprint(val) env = append(env, envName+"="+fmt.Sprint(val)) default: data, err := json.Marshal(val) if err == nil { + envMap[envName] = string(data) env = append(env, envName+"="+string(data)) } } @@ -184,9 +190,19 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) return "", err } interpreter = strings.TrimSpace(interpreter)[2:] + + interpreter = os.Expand(interpreter, func(s string) string { + return envMap[s] + }) + + args, err := shlex.Split(interpreter) + if err != nil { + return "", err + } + output := &bytes.Buffer{} - cmd := exec.Command(interpreter, f.Name()) + cmd := exec.Command(args[0], append(args[1:], f.Name())...) cmd.Env = env cmd.Stdin = strings.NewReader(input) cmd.Stderr = os.Stderr @@ -198,7 +214,7 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) return "", err } - return string(output.Bytes()), nil + return output.String(), nil } func (e *Engine) Start(ctx Context, input string) (*Return, error) { diff --git a/pkg/mvl/log.go b/pkg/mvl/log.go index 6e9f7650..e4a5c3da 100644 --- a/pkg/mvl/log.go +++ b/pkg/mvl/log.go @@ -1,7 +1,6 @@ package mvl import ( - "encoding/json" "fmt" "os" "runtime" @@ -34,24 +33,6 @@ func (f formatter) Format(entry *logrus.Entry) ([]byte, error) { msg)), nil } -type verbose struct { -} - -func (f verbose) Format(entry *logrus.Entry) ([]byte, error) { - buf, err := json.MarshalIndent(struct { - Time time.Time `json:"time,omitempty"` - Level string `json:"level,omitempty"` - Message string `json:"message,omitempty"` - Data any `json:"data,omitempty"` - }{ - Time: entry.Time, - Level: entry.Level.String(), - Message: entry.Message, - Data: entry.Data, - }, "", " ") - return append(buf, []byte("\n")...), err -} - func SetDebug() { logrus.SetFormatter(&logrus.JSONFormatter{ PrettyPrint: os.Getenv("GPTSCRIPT_JSON_LOG_SINGLE_LINE") != "true", diff --git a/pkg/test/examples_test.go b/pkg/test/examples_test.go index 86167054..74856b22 100644 --- a/pkg/test/examples_test.go +++ b/pkg/test/examples_test.go @@ -17,19 +17,17 @@ const ( ) func TestExamples(t *testing.T) { - l, err := os.ReadDir(examplePath) - require.NoError(t, err) - if err != nil { - t.Fatal(err) + tests := []string{ + "fib.gpt", + "echo.gpt", + "helloworld.gpt", } - - for _, entry := range l { - entry.Name() - t.Run(entry.Name(), func(t *testing.T) { + for _, entry := range tests { + t.Run(entry, func(t *testing.T) { r, err := runner.New() require.NoError(t, err) - prg, err := loader.Program(context.Background(), filepath.Join(examplePath, entry.Name()), "") + prg, err := loader.Program(context.Background(), filepath.Join(examplePath, entry), "") require.NoError(t, err) output, err := r.Run(context.Background(), prg, os.Environ(), "") diff --git a/scripts/ci.gpt b/scripts/ci.gpt index b2696198..71506e98 100644 --- a/scripts/ci.gpt +++ b/scripts/ci.gpt @@ -1,9 +1,10 @@ -tools: make +tools: make, sys.abort -Run each step sequentially +Run each step sequentially, if either step fails abort 1. Run "make" to compile 2. Run "make test" to test +3. Run "make validate" to test Then print SUCCESS --- @@ -11,10 +12,4 @@ tool: make description: Runs the "make" args: arg: the args to pass to make -#!/bin/sh -set -e - -echo "START MAKE OUTPUT:" -echo "Running make ${ARG}" -make ${ARG} -echo "END MAKE OUTPUT" +#!make ${ARG} From 4dace5c6091d0236d0094dde801bf7a58b67e221 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 08:40:33 -0700 Subject: [PATCH 018/774] Cleanup some tests --- pkg/test/examples_test.go | 14 +++++++++++++- pkg/test/testdata/TestEcho.golden | 1 + pkg/test/testdata/TestExamples/describe.gpt.golden | 1 - pkg/test/testdata/TestExamples/echo.gpt.golden | 1 - .../testdata/TestExamples/git-commit.gpt.golden | 1 - .../TestExamples/summarize-syntax.gpt.golden | 1 - pkg/test/testdata/TestExamples/tables.gpt.golden | 1 - 7 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 pkg/test/testdata/TestEcho.golden delete mode 100644 pkg/test/testdata/TestExamples/describe.gpt.golden delete mode 100644 pkg/test/testdata/TestExamples/echo.gpt.golden delete mode 100644 pkg/test/testdata/TestExamples/git-commit.gpt.golden delete mode 100644 pkg/test/testdata/TestExamples/summarize-syntax.gpt.golden delete mode 100644 pkg/test/testdata/TestExamples/tables.gpt.golden diff --git a/pkg/test/examples_test.go b/pkg/test/examples_test.go index 74856b22..f69473a2 100644 --- a/pkg/test/examples_test.go +++ b/pkg/test/examples_test.go @@ -19,7 +19,6 @@ const ( func TestExamples(t *testing.T) { tests := []string{ "fib.gpt", - "echo.gpt", "helloworld.gpt", } for _, entry := range tests { @@ -37,3 +36,16 @@ func TestExamples(t *testing.T) { }) } } + +func TestEcho(t *testing.T) { + r, err := runner.New() + require.NoError(t, err) + + prg, err := loader.Program(context.Background(), filepath.Join(examplePath, "echo.gpt"), "") + require.NoError(t, err) + + output, err := r.Run(context.Background(), prg, os.Environ(), "this is a test") + require.NoError(t, err) + + autogold.ExpectFile(t, output) +} diff --git a/pkg/test/testdata/TestEcho.golden b/pkg/test/testdata/TestEcho.golden new file mode 100644 index 00000000..8ad1ddf9 --- /dev/null +++ b/pkg/test/testdata/TestEcho.golden @@ -0,0 +1 @@ +"this is a test" diff --git a/pkg/test/testdata/TestExamples/describe.gpt.golden b/pkg/test/testdata/TestExamples/describe.gpt.golden deleted file mode 100644 index 16002503..00000000 --- a/pkg/test/testdata/TestExamples/describe.gpt.golden +++ /dev/null @@ -1 +0,0 @@ -"The go program with the most lines of code, consisting of 41 lines, appears to be a test package for GPT-Script. It includes functionality to verify examples through automated testing. The program iterates over examples, executes them using a runner, and validates outputs. The `autogold` package is used for output checking and `require.NoError` is utilized for error handling within the test cases." diff --git a/pkg/test/testdata/TestExamples/echo.gpt.golden b/pkg/test/testdata/TestExamples/echo.gpt.golden deleted file mode 100644 index 7a5e8184..00000000 --- a/pkg/test/testdata/TestExamples/echo.gpt.golden +++ /dev/null @@ -1 +0,0 @@ -"I am ready to process your input. Please provide the instructions or input for me to process." diff --git a/pkg/test/testdata/TestExamples/git-commit.gpt.golden b/pkg/test/testdata/TestExamples/git-commit.gpt.golden deleted file mode 100644 index dc3253ae..00000000 --- a/pkg/test/testdata/TestExamples/git-commit.gpt.golden +++ /dev/null @@ -1 +0,0 @@ -"chore: Refactor CLI implementation for GPTScript and renamed runner package to monitor" diff --git a/pkg/test/testdata/TestExamples/summarize-syntax.gpt.golden b/pkg/test/testdata/TestExamples/summarize-syntax.gpt.golden deleted file mode 100644 index c69389c1..00000000 --- a/pkg/test/testdata/TestExamples/summarize-syntax.gpt.golden +++ /dev/null @@ -1 +0,0 @@ -"It appears that the contents of the GPT files are empty, so I am unable to provide a README that describes the syntax of the GPT files. If the files have contents that were not read correctly, please ensure the files are not empty and contain the expected data, then I can assist in creating the README." diff --git a/pkg/test/testdata/TestExamples/tables.gpt.golden b/pkg/test/testdata/TestExamples/tables.gpt.golden deleted file mode 100644 index 91aa605f..00000000 --- a/pkg/test/testdata/TestExamples/tables.gpt.golden +++ /dev/null @@ -1 +0,0 @@ -"The table with the most amount of rows in the Chinook database is `PlaylistTrack` with 8,715 rows." From 2dc8c61d684bd2d6672a79f04a15c079976d2da7 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 08:44:25 -0700 Subject: [PATCH 019/774] Skip tests that require openai key --- pkg/test/examples_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/test/examples_test.go b/pkg/test/examples_test.go index f69473a2..30bf8e29 100644 --- a/pkg/test/examples_test.go +++ b/pkg/test/examples_test.go @@ -17,6 +17,8 @@ const ( ) func TestExamples(t *testing.T) { + RequireOpenAPIKey(t) + tests := []string{ "fib.gpt", "helloworld.gpt", @@ -38,6 +40,8 @@ func TestExamples(t *testing.T) { } func TestEcho(t *testing.T) { + RequireOpenAPIKey(t) + r, err := runner.New() require.NoError(t, err) @@ -49,3 +53,9 @@ func TestEcho(t *testing.T) { autogold.ExpectFile(t, output) } + +func RequireOpenAPIKey(t *testing.T) { + if os.Getenv("OPENAI_API_KEY") == "" { + t.Skip() + } +} From 86387edf5c229ff2d34a3b83206bbeb3e75b8bf0 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 10:38:47 -0700 Subject: [PATCH 020/774] Add --list-tools --- examples/summarize-syntax.gpt | 15 ++- pkg/builtin/builtin.go | 218 +++++++++++++++++++--------------- pkg/cli/gptscript.go | 15 +++ pkg/monitor/display.go | 50 +++++++- pkg/openai/client.go | 2 +- pkg/parser/parser.go | 2 + pkg/runner/runner.go | 8 +- pkg/types/completion.go | 7 +- pkg/types/tool.go | 46 +++++++ 9 files changed, 250 insertions(+), 113 deletions(-) diff --git a/examples/summarize-syntax.gpt b/examples/summarize-syntax.gpt index 3202c12b..8a4570a2 100644 --- a/examples/summarize-syntax.gpt +++ b/examples/summarize-syntax.gpt @@ -1,6 +1,8 @@ -tools: ls, cat +tools: ls, sys.read, help -Read all gpt files and then write a README that describes the syntax of the gpt files +Write a README.md for this github repo that describes this project, it's usage, and a description of the +GPT file syntax. Example GPT files can be found by listing and read them. Also document the help of the +gptscript command. --- name: ls @@ -11,10 +13,7 @@ description: list all gpt files find . -name '*.gpt' --- -name: cat -description: Reads the contents of a file -arg: file: The filename to read +name: help +description: Get the help output of gptscript -#!/bin/bash - -cat ${FILE} 399 { - return "", fmt.Errorf("failed to post %s: %s", params.URL, resp.Status) - } - - return fmt.Sprintf("Wrote %d to %s", len([]byte(params.Content)), params.URL), nil - }, + BuiltinFunc: SysHTTPPost, }, } +func ListTools() (result []types.Tool) { + var keys []string + for k := range Tools { + keys = append(keys, k) + } + + sort.Strings(keys) + for _, key := range keys { + t, _ := Builtin(key) + result = append(result, t) + } + + return +} + func Builtin(name string) (types.Tool, bool) { t, ok := Tools[name] t.Name = name @@ -147,3 +72,104 @@ func Builtin(name string) (types.Tool, bool) { t.Instructions = "#!" + name return t, ok } + +func SysRead(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Filename string `json:"filename,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + log.Debugf("Reading file %s", params.Filename) + data, err := os.ReadFile(params.Filename) + if err != nil { + return "", err + } + + return string(data), nil +} + +func SysWrite(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Filename string `json:"filename,omitempty"` + Content string `json:"content,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + data := []byte(params.Content) + msg := fmt.Sprintf("Wrote %d bytes to file %s", len(data), params.Filename) + log.Debugf(msg) + + return "", os.WriteFile(params.Filename, data, 0644) +} + +func SysHTTPGet(ctx context.Context, env []string, input string) (string, error) { + var params struct { + URL string `json:"url,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + log.Debugf("http get %s", params.URL) + resp, err := http.Get(params.URL) + if err != nil { + return "", err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("failed to download %s: %s", params.URL, resp.Status) + } + + data, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return string(data), nil +} + +func SysHTTPPost(ctx context.Context, env []string, input string) (string, error) { + var params struct { + URL string `json:"url,omitempty"` + Content string `json:"content,omitempty"` + ContentType string `json:"contentType,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, params.URL, strings.NewReader(params.Content)) + if err != nil { + return "", err + } + if params.ContentType != "" { + req.Header.Set("Content-Type", params.ContentType) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + _, _ = io.ReadAll(resp.Body) + if resp.StatusCode > 399 { + return "", fmt.Errorf("failed to post %s: %s", params.URL, resp.Status) + } + + return fmt.Sprintf("Wrote %d to %s", len([]byte(params.Content)), params.URL), nil +} + +func SysAbort(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Message string `json:"message,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + return "", fmt.Errorf("ABORT: %s", params.Message) +} diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 949f18c6..5011e319 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -9,6 +9,7 @@ import ( "github.com/acorn-io/cmd" "github.com/acorn-io/gptscript/pkg/assemble" + "github.com/acorn-io/gptscript/pkg/builtin" "github.com/acorn-io/gptscript/pkg/input" "github.com/acorn-io/gptscript/pkg/loader" "github.com/acorn-io/gptscript/pkg/monitor" @@ -34,6 +35,7 @@ type GPTScript struct { SubTool string `usage:"Use tool of this name, not the first tool in file"` Assemble bool `usage:"Assemble tool to a single artifact, saved to --output"` ListModels bool `usage:"List the models available and exit"` + ListTools bool `usage:"List built-in tools and exit"` } func New() *cobra.Command { @@ -45,6 +47,15 @@ func (r *GPTScript) Customize(cmd *cobra.Command) { cmd.Flags().SetInterspersed(false) } +func (r *GPTScript) listTools(ctx context.Context) error { + var lines []string + for _, tool := range builtin.ListTools() { + lines = append(lines, tool.String()) + } + fmt.Println(strings.Join(lines, "\n---\n")) + return nil +} + func (r *GPTScript) listModels(ctx context.Context) error { c, err := openai.NewClient(openai.Options(r.OpenAIOptions)) if err != nil { @@ -80,6 +91,10 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return r.listModels(cmd.Context()) } + if r.ListTools { + return r.listTools(cmd.Context()) + } + if len(args) == 0 { return fmt.Errorf("scripts argument required") } diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index 8699458e..91a9d1fe 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -16,18 +16,21 @@ import ( ) type Options struct { - DumpState string `usage:"Dump the internal execution state to a file"` + LiveOutput bool `usage:"-"` + DumpState string `usage:"Dump the internal execution state to a file"` } func complete(opts ...Options) (result Options) { for _, opt := range opts { result.DumpState = types.FirstSet(opt.DumpState, result.DumpState) + result.LiveOutput = types.FirstSet(opt.LiveOutput, result.LiveOutput) } return } type Console struct { - dumpState string + dumpState string + liveOutput bool } var runID int64 @@ -44,8 +47,39 @@ func (c *Console) Start(ctx context.Context, prg *types.Program, env []string, i } type display struct { - dump dump - dumpState string + dump dump + livePrinter *livePrinter + dumpState string +} + +type livePrinter struct { + lastLines map[string]string + needsNewline bool +} + +func (l *livePrinter) end() { + if l == nil { + return + } + if l.needsNewline { + fmt.Println() + } + l.needsNewline = false +} + +func (l *livePrinter) print(event runner.Event, c call) { + if l == nil { + return + } + if c.ParentID != "" { + return + } + + last := l.lastLines[c.ID] + line := strings.TrimPrefix(event.Content, last) + fmt.Print(line) + l.needsNewline = !strings.HasSuffix(line, "\n") + l.lastLines[c.ID] = event.Content } func (d *display) Event(event runner.Event) { @@ -85,13 +119,17 @@ func (d *display) Event(event runner.Event) { switch event.Type { case runner.EventTypeCallStart: + d.livePrinter.end() currentCall.Start = event.Time currentCall.Input = event.Content log.Fields("input", event.Content).Infof("started [%s]", callName) case runner.EventTypeCallProgress: + d.livePrinter.print(event, currentCall) case runner.EventTypeCallContinue: + d.livePrinter.end() log.Fields("toolResults", event.ToolResults).Infof("continue [%s]", callName) case runner.EventTypeChat: + d.livePrinter.end() if event.ChatRequest == nil { log = log.Fields( "response", toJSON(event.ChatResponse), @@ -110,6 +148,7 @@ func (d *display) Event(event runner.Event) { Cached: event.ChatResponseCached, }) case runner.EventTypeCallFinish: + d.livePrinter.end() currentCall.End = event.Time currentCall.Output = event.Content log.Fields("output", event.Content).Infof("ended [%s]", callName) @@ -141,6 +180,9 @@ func NewConsole(opts ...Options) *Console { func newDisplay(dumpState string) *display { return &display{ dumpState: dumpState, + livePrinter: &livePrinter{ + lastLines: map[string]string{}, + }, } } diff --git a/pkg/openai/client.go b/pkg/openai/client.go index a8c5cba1..fbba7110 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -406,7 +406,7 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, partial <- Status{ PartialResponse: &types.CompletionMessage{ Role: types.CompletionMessageRoleTypeAssistant, - Content: types.Text(msg + "Waiting for model response..."), + Content: types.Text(msg + "Waiting for model response...\n"), }, } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 94dc32ad..efe65aff 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -64,6 +64,8 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { fallthrough case "name": tool.Name = strings.ToLower(value) + case "model": + fallthrough case "modelname": tool.ModelName = value case "description": diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 55c0dbc9..dcfd4e18 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -127,6 +127,7 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp for { if result.Result != nil && len(result.Calls) == 0 { + progressClose() monitor.Event(Event{ Time: time.Now(), CallContext: &callCtx, @@ -183,9 +184,12 @@ func streamProgress(callCtx *engine.Context, monitor Monitor) (chan openai.Statu } }() + var once sync.Once return progress, func() { - close(progress) - wg.Wait() + once.Do(func() { + close(progress) + wg.Wait() + }) } } diff --git a/pkg/types/completion.go b/pkg/types/completion.go index f36ead46..715d7294 100644 --- a/pkg/types/completion.go +++ b/pkg/types/completion.go @@ -68,10 +68,13 @@ func Text(text string) []ContentPart { func (in CompletionMessage) String() string { buf := strings.Builder{} - for _, content := range in.Content { + for i, content := range in.Content { + if i > 0 { + buf.WriteString("\n") + } buf.WriteString(content.Text) if content.ToolCall != nil { - buf.WriteString(fmt.Sprintf("tool call %s -> %s\n", content.ToolCall.Function.Name, content.ToolCall.Function.Arguments)) + buf.WriteString(fmt.Sprintf("tool call %s -> %s", content.ToolCall.Function.Name, content.ToolCall.Function.Arguments)) } if content.Image != nil { buf.WriteString("image: ") diff --git a/pkg/types/tool.go b/pkg/types/tool.go index e13d76be..b442960f 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -3,6 +3,7 @@ package types import ( "context" "fmt" + "sort" "strings" ) @@ -34,6 +35,51 @@ type Tool struct { Source ToolSource `json:"source,omitempty"` } +func (t Tool) String() string { + buf := &strings.Builder{} + if t.Name != "" { + _, _ = fmt.Fprintf(buf, "Name: %s\n", t.Name) + } + if t.Description != "" { + _, _ = fmt.Fprintf(buf, "Description: %s\n", t.Name) + } + if len(t.Tools) != 0 { + _, _ = fmt.Fprintf(buf, "Tools: %s\n", strings.Join(t.Tools, ", ")) + } + if t.Vision { + _, _ = fmt.Fprintln(buf, "Vision: true") + } + if t.MaxTokens != 0 { + _, _ = fmt.Fprintf(buf, "Max Tokens: %d\n", t.MaxTokens) + } + if t.ModelName != "" { + _, _ = fmt.Fprintf(buf, "Model Name: %s\n", t.ModelName) + } + if t.JSONResponse { + _, _ = fmt.Fprintln(buf, "JSON Response: true") + } + if t.Cache != nil && !*t.Cache { + _, _ = fmt.Fprintln(buf, "Cache: false") + } + if t.Arguments != nil { + var keys []string + for k := range t.Arguments.Properties { + keys = append(keys, k) + } + sort.Strings(keys) + for _, key := range keys { + prop := t.Arguments.Properties[key] + _, _ = fmt.Fprintf(buf, "Arg: %s: %s\n", key, prop.Description) + } + } + if t.Instructions != "" && t.BuiltinFunc == nil { + _, _ = fmt.Fprintln(buf) + _, _ = fmt.Fprintln(buf, t.Instructions) + } + + return buf.String() +} + type ToolSource struct { File string `json:"file,omitempty"` LineNo int `json:"lineNo,omitempty"` From 5a7ebe0f5b2831960a517c5150127fe0968dfdc8 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 11:19:47 -0700 Subject: [PATCH 021/774] Add find and exec --- README.md | 104 +++++++++++++--------------------- examples/summarize-syntax.gpt | 20 ++----- pkg/builtin/builtin.go | 77 +++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index 5bb5728b..1ffe9893 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,55 @@ -# README for GPT File Syntax +# README.md for GPTscript Project -## Overview -GPT files found in this project use a custom syntax to describe various shell tools and their respective functionalities. Each file contains definitions for tools including their names, descriptions, arguments, and executable code. Below is an explanation of the syntax based on the contents of the GPT files reviewed (`./describe.gpt`, `./summarize-syntax.gpt`, `./tables.gpt`). +## Project Description -## Syntax Description +This project utilizes `GPTscript`, a powerful scripting tool that leverages OpenAI's GPT plugins to execute tasks specified in `.gpt` files. These scripts can combine traditional scripting with GPT's AI capabilities to automate complex workflows, parse information, and more. -### General Format -GPT files follow a structured format that includes a preamble (indicating available tools), followed by metadata (descriptions of each tool), and Bash script examples for the tool's operation. +## Usage -Here's the general layout of a GPT file definition: -``` -Tools: - ---- (3 hyphens to separate each tool definition) -name: -description: -arg: (Optional and re-occurring) - - -``` +The primary command used to run GPT scripts is `gptscript`, which can be invoked with various flags to control the script execution. A typical usage pattern looks like this: -### Tool Definition Header -A tool definition always starts with three hyphens (`---`). This is a separator used to distinguish between different tool descriptions within the file. +```bash +gptscript [flags] PROGRAM_FILE [INPUT...] +``` -### Name -The `name` field defines the name of the tool. It is used to invoke a specific functionality. +Where `PROGRAM_FILE` is the script to be executed, optionally followed by `INPUT` arguments to pass into the script. -### Description -The `description` field provides a concise explanation of what the tool does. +## GPT File Syntax -### Arguments -The `arg` fields describe the arguments that the tool accepts. Each argument is paired with a brief description. Argument definitions are optional and can be repeated if a tool accepts multiple arguments. +GPT script files (`*.gpt`) follow a syntax which allows for defining tools, their descriptions, arguments, and embedded traditional scripting codes. Here's a breakdown of the syntax: -### Executable Code Block -Following the metadata, an executable code block is provided. It is written in Bash and contains the script to execute the tool's functionality. +- `tools:` Followed by the tool names to be used. +- `name:` Defines the tool's name. +- `description:` Describes what the tool does. +- `args:` Lists arguments the tool accepts, describing the expected input. +- `tools:` Below the main tool definition, you can specify other tools used by this tool. +- A line containing `---` signifies the separation between tool metadata and the script code itself. -### Examples -Here are examples extracted from the GPT files which follow the syntax described: +## Example `.gpt` Files and Their Syntax -#### From `./describe.gpt` -``` ---- -name: ls -description: Recursively lists all go files +The repository contains several example `.gpt` files, such as: -#!/bin/bash - -find . -name '*.go' -``` -#### From `./summarize-syntax.gpt` -``` ---- -name: cat -description: Reads the contents of a file -arg: file: The filename to read +- `describe.gpt`: Provides functionalities for working with Go files, with tools like `ls`, `count`, `summarize`, and `compare`. +- `echo.gpt`: A simple script that echoes the provided input. +- `fib.gpt`: An example demonstrating a recursive function `myfunction`. +- `git-commit.gpt`: Automates the creation of a well-formed git commit message. +- `helloworld.gpt`: A basic script outputs the traditional "hello world" message. +- `summarize-syntax.gpt`: Meta-script for generating documentation based on `.gpt` files in a directory. +- `tables.gpt`: Using SQLite, identifies the table in a database with the most rows. -#!/bin/bash - -cat ${FILE} Date: Sun, 4 Feb 2024 22:31:28 -0700 Subject: [PATCH 022/774] Update CI scripts --- pkg/builtin/builtin.go | 20 ++++++++++++++++++++ pkg/monitor/display.go | 3 +-- scripts/ci.gpt | 16 ++++++---------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 6a3faa88..223c4a29 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -67,6 +67,12 @@ var Tools = map[string]types.Tool{ ), BuiltinFunc: SysExec, }, + "sys.getenv": { + Description: "Gets the value of an OS environment variable", + Arguments: types.ObjectSchema( + "name", "The environment variable name to lookup"), + BuiltinFunc: SysGetenv, + }, } func ListTools() (result []types.Tool) { @@ -147,6 +153,9 @@ func SysExec(ctx context.Context, env []string, input string) (string, error) { cmd.Env = env cmd.Dir = params.Directory out, err := cmd.CombinedOutput() + if err != nil { + _, _ = os.Stdout.Write(out) + } return string(out), err } @@ -241,6 +250,17 @@ func SysHTTPPost(ctx context.Context, env []string, input string) (string, error return fmt.Sprintf("Wrote %d to %s", len([]byte(params.Content)), params.URL), nil } +func SysGetenv(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Name string `json:"name,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + log.Debugf("looking up env var %s", params.Name) + return os.Getenv(params.Name), nil +} + func SysAbort(ctx context.Context, env []string, input string) (string, error) { var params struct { Message string `json:"message,omitempty"` diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index 91a9d1fe..a29182e9 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -29,8 +29,7 @@ func complete(opts ...Options) (result Options) { } type Console struct { - dumpState string - liveOutput bool + dumpState string } var runID int64 diff --git a/scripts/ci.gpt b/scripts/ci.gpt index 71506e98..f37acd6c 100644 --- a/scripts/ci.gpt +++ b/scripts/ci.gpt @@ -1,15 +1,11 @@ -tools: make, sys.abort +tools: sys.exec, sys.abort, sys.getenv Run each step sequentially, if either step fails abort -1. Run "make" to compile -2. Run "make test" to test -3. Run "make validate" to test +1. If DANGEROUS environment variable does not equal "true" then abort +2. Run "make" to compile +3. Run the standard set of go validation tools: test, vet, and fmt recursively +4. Install golangci-lint and validate the code using it +5. If the git workspace is dirty, then abort Then print SUCCESS ---- -tool: make -description: Runs the "make" -args: arg: the args to pass to make - -#!make ${ARG} From c90355fe55fbfc567533137c16ce58d9d73b1e33 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 14:56:28 -0700 Subject: [PATCH 023/774] Add sys.http.html2text --- examples/search.gpt | 16 ++++++++++++++++ go.mod | 6 +++++- go.sum | 8 ++++++++ pkg/builtin/builtin.go | 28 ++++++++++++++++++++++++++++ pkg/types/tool.go | 2 +- 5 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 examples/search.gpt diff --git a/examples/search.gpt b/examples/search.gpt new file mode 100644 index 00000000..b084f946 --- /dev/null +++ b/examples/search.gpt @@ -0,0 +1,16 @@ +tools: search + +Search the web for vacation spots in Florida, for each +vacation spot give the name and description. + +--- +name: search +description: Searches the internet for content +args: query: The query to search for +tools: sys.http.text? + +First download the content of "https://html.duckduckgo.com/html/?q=${query}". +Look for the first 5 search results. Download each search result and look for content +that would best answer the query ${query}. + +With all that information try your best to provide an answer or useful context to ${query}. diff --git a/go.mod b/go.mod index a0e9f585..1d2dff77 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/adrg/xdg v0.4.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hexops/autogold/v2 v2.1.0 + github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 github.com/sashabaranov/go-openai v1.18.3 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 @@ -34,16 +35,19 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/nightlyone/lockfile v1.0.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/samber/lo v1.38.1 // indirect github.com/samber/slog-logrus v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.19.0 // indirect golang.org/x/sys v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.16.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect diff --git a/go.sum b/go.sum index e9bf20c3..d4ac634c 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,8 @@ github.com/hexops/valast v1.4.3 h1:oBoGERMJh6UZdRc6cduE1CTPK+VAdXA59Y1HFgu3sm0= github.com/hexops/valast v1.4.3/go.mod h1:Iqx2kLj3Jn47wuXpj3wX40xn6F93QNFBHuiKBerkTGA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA= +github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -60,8 +62,12 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/nightlyone/lockfile v1.0.0 h1:RHep2cFKK4PonZJDdEl4GmkabuhbsRMgk/k3uAmxBiA= github.com/nightlyone/lockfile v1.0.0/go.mod h1:rywoIealpdNse2r832aiD9jRk8ErCatROs6LzC841CI= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= @@ -86,6 +92,8 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= 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/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= +github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 223c4a29..aecb2d7f 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -14,6 +14,7 @@ import ( "strings" "github.com/acorn-io/gptscript/pkg/types" + "github.com/jaytaylor/html2text" ) var Tools = map[string]types.Tool{ @@ -36,6 +37,12 @@ var Tools = map[string]types.Tool{ "url", "The URL to download"), BuiltinFunc: SysHTTPGet, }, + "sys.http.html2text": { + Description: "Download the contents of a http or https URL returning the content as rendered text converted from HTML", + Arguments: types.ObjectSchema( + "url", "The URL to download"), + BuiltinFunc: SysHTTPHtml2Text, + }, "sys.abort": { Description: "Aborts execution", Arguments: types.ObjectSchema( @@ -91,10 +98,21 @@ func ListTools() (result []types.Tool) { } func Builtin(name string) (types.Tool, bool) { + name, dontFail := strings.CutSuffix(name, "?") t, ok := Tools[name] t.Name = name t.ID = name t.Instructions = "#!" + name + if ok && dontFail { + orig := t.BuiltinFunc + t.BuiltinFunc = func(ctx context.Context, env []string, input string) (string, error) { + s, err := orig(ctx, env, input) + if err != nil { + return fmt.Sprintf("ERROR: %s", err.Error()), nil + } + return s, err + } + } return t, ok } @@ -218,6 +236,16 @@ func SysHTTPGet(ctx context.Context, env []string, input string) (string, error) return string(data), nil } +func SysHTTPHtml2Text(ctx context.Context, env []string, input string) (string, error) { + content, err := SysHTTPGet(ctx, env, input) + if err != nil { + return "", err + } + return html2text.FromString(content, html2text.Options{ + PrettyTables: true, + }) +} + func SysHTTPPost(ctx context.Context, env []string, input string) (string, error) { var params struct { URL string `json:"url,omitempty"` diff --git a/pkg/types/tool.go b/pkg/types/tool.go index b442960f..d84ff6bd 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -69,7 +69,7 @@ func (t Tool) String() string { sort.Strings(keys) for _, key := range keys { prop := t.Arguments.Properties[key] - _, _ = fmt.Fprintf(buf, "Arg: %s: %s\n", key, prop.Description) + _, _ = fmt.Fprintf(buf, "Args: %s: %s\n", key, prop.Description) } } if t.Instructions != "" && t.BuiltinFunc == nil { From 231b4f072e64bebc27f4a80ad813b03492707f3f Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 17:33:14 -0700 Subject: [PATCH 024/774] Add chatID to logs --- pkg/monitor/display.go | 10 +++++++--- pkg/openai/client.go | 44 ++++++++++++++++++++++++++++-------------- pkg/runner/runner.go | 11 +++++++---- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index a29182e9..f5826b13 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -131,17 +131,20 @@ func (d *display) Event(event runner.Event) { d.livePrinter.end() if event.ChatRequest == nil { log = log.Fields( + "chatID", event.ChatTransactionID, "response", toJSON(event.ChatResponse), "cached", event.ChatResponseCached, ) } else { log.Infof("openai request sent [%s]", callName) log = log.Fields( + "chatID", event.ChatTransactionID, "request", toJSON(event.ChatRequest), ) } log.Debugf("messages") currentCall.Messages = append(currentCall.Messages, message{ + ChatID: event.ChatTransactionID, Request: event.ChatRequest, Response: event.ChatResponse, Cached: event.ChatResponseCached, @@ -260,9 +263,10 @@ type dump struct { } type message struct { - Request any `json:"request,omitempty"` - Response any `json:"response,omitempty"` - Cached bool `json:"cached,omitempty"` + ChatID string `json:"chatID,omitempty"` + Request any `json:"request,omitempty"` + Response any `json:"response,omitempty"` + Cached bool `json:"cached,omitempty"` } type call struct { diff --git a/pkg/openai/client.go b/pkg/openai/client.go index fbba7110..2b9ab4c8 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -11,6 +11,7 @@ import ( "os" "sort" "strings" + "sync/atomic" "github.com/acorn-io/gptscript/pkg/cache" "github.com/acorn-io/gptscript/pkg/hash" @@ -27,11 +28,14 @@ const ( ) var ( - key = os.Getenv("OPENAI_API_KEY") - url = os.Getenv("OPENAI_URL") + key = os.Getenv("OPENAI_API_KEY") + url = os.Getenv("OPENAI_URL") + transactionID int64 ) type Client struct { + url string + key string c *openai.Client cache *cache.Client } @@ -107,7 +111,11 @@ func (c *Client) ListModules(ctx context.Context) (result []string, _ error) { } func (c *Client) cacheKey(request openai.ChatCompletionRequest) string { - return hash.Encode(request) + return hash.Encode(map[string]any{ + "url": c.url, + "key": c.key, + "request": request, + }) } func (c *Client) seed(request openai.ChatCompletionRequest) int { @@ -231,11 +239,12 @@ func toMessages(ctx context.Context, cache *cache.Client, request types.Completi } type Status struct { - Request any - Response any - Cached bool - Chunks any - PartialResponse *types.CompletionMessage + OpenAITransactionID string + Request any + Response any + Cached bool + Chunks any + PartialResponse *types.CompletionMessage } func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- Status) (*types.CompletionMessage, error) { @@ -281,8 +290,10 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } } + id := fmt.Sprint(atomic.AddInt64(&transactionID, 1)) status <- Status{ - Request: request, + OpenAITransactionID: id, + Request: request, } var cacheResponse bool @@ -291,7 +302,7 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques if err != nil { return nil, err } else if !ok { - response, err = c.call(ctx, request, status) + response, err = c.call(ctx, request, id, status) if err != nil { return nil, err } @@ -305,9 +316,10 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } status <- Status{ - Chunks: response, - Response: result, - Cached: cacheResponse, + OpenAITransactionID: id, + Chunks: response, + Response: result, + Cached: cacheResponse, } return &result, nil @@ -391,7 +403,7 @@ func (c *Client) store(ctx context.Context, key string, responses []openai.ChatC return c.cache.Store(ctx, key, buf.Bytes()) } -func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, partial chan<- Status) (responses []openai.ChatCompletionStreamResponse, _ error) { +func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, transactionID string, partial chan<- Status) (responses []openai.ChatCompletionStreamResponse, _ error) { cacheKey := c.cacheKey(request) request.Stream = true @@ -404,6 +416,7 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, } partial <- Status{ + OpenAITransactionID: transactionID, PartialResponse: &types.CompletionMessage{ Role: types.CompletionMessageRoleTypeAssistant, Content: types.Text(msg + "Waiting for model response...\n"), @@ -429,7 +442,8 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, if partial != nil { partialMessage = appendMessage(partialMessage, response) partial <- Status{ - PartialResponse: &partialMessage, + OpenAITransactionID: transactionID, + PartialResponse: &partialMessage, } } responses = append(responses, response) diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index dcfd4e18..6e7e007f 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -87,6 +87,7 @@ type Event struct { CallContext *engine.Context ToolResults int Type EventType + ChatTransactionID string ChatRequest any ChatResponse any ChatResponseCached bool @@ -166,16 +167,18 @@ func streamProgress(callCtx *engine.Context, monitor Monitor) (chan openai.Statu for status := range progress { if message := status.PartialResponse; message != nil { monitor.Event(Event{ - Time: time.Now(), - CallContext: callCtx, - Type: EventTypeCallProgress, - Content: message.String(), + Time: time.Now(), + CallContext: callCtx, + Type: EventTypeCallProgress, + ChatTransactionID: status.OpenAITransactionID, + Content: message.String(), }) } else { monitor.Event(Event{ Time: time.Now(), CallContext: callCtx, Type: EventTypeChat, + ChatTransactionID: status.OpenAITransactionID, ChatRequest: status.Request, ChatResponse: status.Response, ChatResponseCached: status.Cached, From 43e09561cd00e280544fb69c3d21da895d57d91b Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 17:35:16 -0700 Subject: [PATCH 025/774] Rename chatID to completionID --- pkg/monitor/display.go | 20 ++++++++++---------- pkg/openai/client.go | 38 +++++++++++++++++++------------------- pkg/runner/runner.go | 14 +++++++------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index f5826b13..7229704c 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -131,23 +131,23 @@ func (d *display) Event(event runner.Event) { d.livePrinter.end() if event.ChatRequest == nil { log = log.Fields( - "chatID", event.ChatTransactionID, + "completionID", event.ChatCompletionID, "response", toJSON(event.ChatResponse), "cached", event.ChatResponseCached, ) } else { log.Infof("openai request sent [%s]", callName) log = log.Fields( - "chatID", event.ChatTransactionID, + "completionID", event.ChatCompletionID, "request", toJSON(event.ChatRequest), ) } log.Debugf("messages") currentCall.Messages = append(currentCall.Messages, message{ - ChatID: event.ChatTransactionID, - Request: event.ChatRequest, - Response: event.ChatResponse, - Cached: event.ChatResponseCached, + CompletionID: event.ChatCompletionID, + Request: event.ChatRequest, + Response: event.ChatResponse, + Cached: event.ChatResponseCached, }) case runner.EventTypeCallFinish: d.livePrinter.end() @@ -263,10 +263,10 @@ type dump struct { } type message struct { - ChatID string `json:"chatID,omitempty"` - Request any `json:"request,omitempty"` - Response any `json:"response,omitempty"` - Cached bool `json:"cached,omitempty"` + CompletionID string `json:"completionID,omitempty"` + Request any `json:"request,omitempty"` + Response any `json:"response,omitempty"` + Cached bool `json:"cached,omitempty"` } type call struct { diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 2b9ab4c8..d95562a3 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -28,9 +28,9 @@ const ( ) var ( - key = os.Getenv("OPENAI_API_KEY") - url = os.Getenv("OPENAI_URL") - transactionID int64 + key = os.Getenv("OPENAI_API_KEY") + url = os.Getenv("OPENAI_URL") + completionID int64 ) type Client struct { @@ -239,12 +239,12 @@ func toMessages(ctx context.Context, cache *cache.Client, request types.Completi } type Status struct { - OpenAITransactionID string - Request any - Response any - Cached bool - Chunks any - PartialResponse *types.CompletionMessage + CompletionID string + Request any + Response any + Cached bool + Chunks any + PartialResponse *types.CompletionMessage } func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- Status) (*types.CompletionMessage, error) { @@ -290,10 +290,10 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } } - id := fmt.Sprint(atomic.AddInt64(&transactionID, 1)) + id := fmt.Sprint(atomic.AddInt64(&completionID, 1)) status <- Status{ - OpenAITransactionID: id, - Request: request, + CompletionID: id, + Request: request, } var cacheResponse bool @@ -316,10 +316,10 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } status <- Status{ - OpenAITransactionID: id, - Chunks: response, - Response: result, - Cached: cacheResponse, + CompletionID: id, + Chunks: response, + Response: result, + Cached: cacheResponse, } return &result, nil @@ -416,7 +416,7 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, } partial <- Status{ - OpenAITransactionID: transactionID, + CompletionID: transactionID, PartialResponse: &types.CompletionMessage{ Role: types.CompletionMessageRoleTypeAssistant, Content: types.Text(msg + "Waiting for model response...\n"), @@ -442,8 +442,8 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, if partial != nil { partialMessage = appendMessage(partialMessage, response) partial <- Status{ - OpenAITransactionID: transactionID, - PartialResponse: &partialMessage, + CompletionID: transactionID, + PartialResponse: &partialMessage, } } responses = append(responses, response) diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 6e7e007f..e17cd7e6 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -87,7 +87,7 @@ type Event struct { CallContext *engine.Context ToolResults int Type EventType - ChatTransactionID string + ChatCompletionID string ChatRequest any ChatResponse any ChatResponseCached bool @@ -167,18 +167,18 @@ func streamProgress(callCtx *engine.Context, monitor Monitor) (chan openai.Statu for status := range progress { if message := status.PartialResponse; message != nil { monitor.Event(Event{ - Time: time.Now(), - CallContext: callCtx, - Type: EventTypeCallProgress, - ChatTransactionID: status.OpenAITransactionID, - Content: message.String(), + Time: time.Now(), + CallContext: callCtx, + Type: EventTypeCallProgress, + ChatCompletionID: status.CompletionID, + Content: message.String(), }) } else { monitor.Event(Event{ Time: time.Now(), CallContext: callCtx, Type: EventTypeChat, - ChatTransactionID: status.OpenAITransactionID, + ChatCompletionID: status.CompletionID, ChatRequest: status.Request, ChatResponse: status.Response, ChatResponseCached: status.Cached, From b5f198e047ca864c153ebd11f0eb4f6a3b0922e6 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 17:47:02 -0700 Subject: [PATCH 026/774] Add logging for commands --- pkg/engine/engine.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 187471da..e353e849 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -27,6 +27,8 @@ You do not need to explain the steps taken, only provide the result to the given You are referred to as a tool. ` +var completionID int64 + func init() { if p := os.Getenv("GPTSCRIPT_INTERNAL_SYSTEM_PROMPT"); p != "" { InternalSystemPrompt = p @@ -142,8 +144,27 @@ func (c *Context) getTool(name string) (types.Tool, error) { return tool, nil } -func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) (string, error) { +func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) (cmdOut string, cmdErr error) { + id := fmt.Sprint(atomic.AddInt64(&completionID, 1)) + + defer func() { + e.Progress <- openai.Status{ + CompletionID: id, + Response: map[string]any{ + "output": cmdOut, + "err": cmdErr, + }, + } + }() + if tool.BuiltinFunc != nil { + e.Progress <- openai.Status{ + CompletionID: id, + Request: map[string]any{ + "command": []string{tool.ID}, + "input": input, + }, + } return tool.BuiltinFunc(ctx, e.Env, input) } @@ -200,6 +221,14 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) return "", err } + e.Progress <- openai.Status{ + CompletionID: id, + Request: map[string]any{ + "command": args, + "input": input, + }, + } + output := &bytes.Buffer{} cmd := exec.Command(args[0], append(args[1:], f.Name())...) From c030edd91fea4f356d41d96c4f9ed8c4fcf23bcd Mon Sep 17 00:00:00 2001 From: sheng-liang Date: Mon, 5 Feb 2024 17:21:39 -0800 Subject: [PATCH 027/774] Rename fib.gpt to fac.gpt --- examples/{fib.gpt => fac.gpt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{fib.gpt => fac.gpt} (100%) diff --git a/examples/fib.gpt b/examples/fac.gpt similarity index 100% rename from examples/fib.gpt rename to examples/fac.gpt From 7b6d1b9b2fcc693a24b107565e30497f33b965d6 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 5 Feb 2024 18:45:37 -0700 Subject: [PATCH 028/774] Fix samples --- examples/git-commit.gpt | 4 +++- pkg/monitor/display.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/git-commit.gpt b/examples/git-commit.gpt index 256c8afd..6462b080 100644 --- a/examples/git-commit.gpt +++ b/examples/git-commit.gpt @@ -1,4 +1,4 @@ -tools: gitstatus +tools: gitstatus, sys.abort Create well formed git commit message based of off the currently stated file contents. The message should convey why something was changed and not what @@ -9,6 +9,8 @@ the go.sum file. Do not use markdown format for the output. +If there are no changes abort. + --- name: gitstatus diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index 7229704c..8f390c44 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -41,7 +41,7 @@ func (c *Console) Start(ctx context.Context, prg *types.Program, env []string, i mon.dump.Program = prg mon.dump.Input = input - log.Fields("runID", mon.dump.ID, "input", input).Debugf("Run started") + log.Fields("runID", mon.dump.ID, "input", input, "program", prg).Debugf("Run started") return mon, nil } From b57117aa6dec3fa72fe18a4f658b0b02c5263ac4 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 6 Feb 2024 10:42:53 -0700 Subject: [PATCH 029/774] Add server --- go.mod | 3 + go.sum | 6 + pkg/cli/gptscript.go | 59 ++++++---- pkg/monitor/display.go | 25 ++-- pkg/runner/runner.go | 18 +-- pkg/server/log.go | 5 + pkg/server/server.go | 257 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 334 insertions(+), 39 deletions(-) create mode 100644 pkg/server/log.go create mode 100644 pkg/server/server.go diff --git a/go.mod b/go.mod index 1d2dff77..15796f4e 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,13 @@ module github.com/acorn-io/gptscript go 1.21.5 require ( + github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb github.com/adrg/xdg v0.4.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hexops/autogold/v2 v2.1.0 github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 + github.com/olahol/melody v1.1.4 github.com/sashabaranov/go-openai v1.18.3 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 @@ -30,6 +32,7 @@ require ( github.com/go-logr/logr v1.4.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/hexops/valast v1.4.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index d4ac634c..042e46be 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd h1:Zbau2J6sEPl1H4gqnEx4/TI55eZncQR5cjfPOcG2lxE= github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd/go.mod h1:13nTO3svO8zTD3j9E5c86tCtK5YrKsK5sxca4Lwkbc0= +github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d h1:hfpNQkJ4I2b8+DbMr8m97gG67ku0uPsMzUfskVu3cHU= +github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d/go.mod h1:WF6FYrEqW0+ZtY5OKb21JhSL0aeL5VJoVrm+u0d4gOE= github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb h1:UVs3i5r0bOh3KEZV5dTsSQzG4MG/8F0m+dcYIzXOO5I= github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb/go.mod h1:J0xhtXVfrJk3Fz1HYz3AoJ/ON9gaHu/baTkqOvywcfo= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= @@ -33,6 +35,8 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hexops/autogold v0.8.1/go.mod h1:97HLDXyG23akzAoRYJh/2OBs3kd80eHyKPvZw0S5ZBY= github.com/hexops/autogold v1.3.1 h1:YgxF9OHWbEIUjhDbpnLhgVsjUDsiHDTyDfy2lrfdlzo= github.com/hexops/autogold v1.3.1/go.mod h1:sQO+mQUCVfxOKPht+ipDSkJ2SCJ7BNJVHZexsXqWMx4= @@ -66,6 +70,8 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/nightlyone/lockfile v1.0.0 h1:RHep2cFKK4PonZJDdEl4GmkabuhbsRMgk/k3uAmxBiA= github.com/nightlyone/lockfile v1.0.0/go.mod h1:rywoIealpdNse2r832aiD9jRk8ErCatROs6LzC841CI= +github.com/olahol/melody v1.1.4 h1:RQHfKZkQmDxI0+SLZRNBCn4LiXdqxLKRGSkT8Dyoe/E= +github.com/olahol/melody v1.1.4/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 5011e319..e8344872 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -16,6 +16,7 @@ import ( "github.com/acorn-io/gptscript/pkg/mvl" "github.com/acorn-io/gptscript/pkg/openai" "github.com/acorn-io/gptscript/pkg/runner" + "github.com/acorn-io/gptscript/pkg/server" "github.com/acorn-io/gptscript/pkg/version" "github.com/spf13/cobra" "golang.org/x/term" @@ -28,14 +29,16 @@ type ( type GPTScript struct { runner.Options DisplayOptions - Debug bool `usage:"Enable debug logging"` - Quiet bool `usage:"No output logging" short:"q"` - Output string `usage:"Save output to a file" short:"o"` - Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"` - SubTool string `usage:"Use tool of this name, not the first tool in file"` - Assemble bool `usage:"Assemble tool to a single artifact, saved to --output"` - ListModels bool `usage:"List the models available and exit"` - ListTools bool `usage:"List built-in tools and exit"` + Debug bool `usage:"Enable debug logging"` + Quiet bool `usage:"No output logging" short:"q"` + Output string `usage:"Save output to a file" short:"o"` + Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"` + SubTool string `usage:"Use tool of this name, not the first tool in file"` + Assemble bool `usage:"Assemble tool to a single artifact, saved to --output"` + ListModels bool `usage:"List the models available and exit"` + ListTools bool `usage:"List built-in tools and exit"` + Server bool `usage:"Start server"` + ListenAddress string `usage:"Server listen address" default:"127.0.0.1:9090"` } func New() *cobra.Command { @@ -75,13 +78,21 @@ func (r *GPTScript) listModels(ctx context.Context) error { } func (r *GPTScript) Pre(cmd *cobra.Command, args []string) error { + if r.Quiet { + if term.IsTerminal(int(os.Stdout.Fd())) { + r.Quiet = false + } else { + r.Quiet = true + } + } + if r.Debug { mvl.SetDebug() } else { mvl.SetSimpleFormat() - } - if r.Quiet { - mvl.SetError() + if r.Quiet { + mvl.SetError() + } } return nil } @@ -95,6 +106,18 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return r.listTools(cmd.Context()) } + if r.Server { + s, err := server.New(server.Options{ + CacheOptions: r.CacheOptions, + OpenAIOptions: r.OpenAIOptions, + ListenAddress: r.ListenAddress, + }) + if err != nil { + return err + } + return s.Start(cmd.Context()) + } + if len(args) == 0 { return fmt.Errorf("scripts argument required") } @@ -118,16 +141,12 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return assemble.Assemble(cmd.Context(), prg, out) } - if !r.Quiet { - if !term.IsTerminal(int(os.Stdout.Fd())) { - r.Quiet = true - } - } - runner, err := runner.New(r.Options, runner.Options{ - CacheOptions: r.CacheOptions, - OpenAIOptions: r.OpenAIOptions, - MonitorFactory: monitor.NewConsole(monitor.Options(r.DisplayOptions)), + CacheOptions: r.CacheOptions, + OpenAIOptions: r.OpenAIOptions, + MonitorFactory: monitor.NewConsole(monitor.Options(r.DisplayOptions), monitor.Options{ + DisplayProgress: !r.Quiet, + }), }) if err != nil { return err diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index 8f390c44..fdbd6565 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -16,27 +16,28 @@ import ( ) type Options struct { - LiveOutput bool `usage:"-"` - DumpState string `usage:"Dump the internal execution state to a file"` + DisplayProgress bool `usage:"-"` + DumpState string `usage:"Dump the internal execution state to a file"` } func complete(opts ...Options) (result Options) { for _, opt := range opts { result.DumpState = types.FirstSet(opt.DumpState, result.DumpState) - result.LiveOutput = types.FirstSet(opt.LiveOutput, result.LiveOutput) + result.DisplayProgress = types.FirstSet(opt.DisplayProgress, result.DisplayProgress) } return } type Console struct { - dumpState string + dumpState string + displayProgress bool } var runID int64 func (c *Console) Start(ctx context.Context, prg *types.Program, env []string, input string) (runner.Monitor, error) { id := atomic.AddInt64(&runID, 1) - mon := newDisplay(c.dumpState) + mon := newDisplay(c.dumpState, c.displayProgress) mon.dump.ID = fmt.Sprint(id) mon.dump.Program = prg mon.dump.Input = input @@ -175,17 +176,21 @@ func (d *display) Stop(output string, err error) { func NewConsole(opts ...Options) *Console { opt := complete(opts...) return &Console{ - dumpState: opt.DumpState, + dumpState: opt.DumpState, + displayProgress: opt.DisplayProgress, } } -func newDisplay(dumpState string) *display { - return &display{ +func newDisplay(dumpState string, progress bool) *display { + display := &display{ dumpState: dumpState, - livePrinter: &livePrinter{ + } + if progress { + display.livePrinter = &livePrinter{ lastLines: map[string]string{}, - }, + } } + return display } func (d *display) Dump(out io.Writer) error { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index e17cd7e6..7081db32 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -83,15 +83,15 @@ func (r *Runner) Run(ctx context.Context, prg types.Program, env []string, input } type Event struct { - Time time.Time - CallContext *engine.Context - ToolResults int - Type EventType - ChatCompletionID string - ChatRequest any - ChatResponse any - ChatResponseCached bool - Content string + Time time.Time `json:"time,omitempty"` + CallContext *engine.Context `json:"callContext,omitempty"` + ToolResults int `json:"toolResults,omitempty"` + Type EventType `json:"type,omitempty"` + ChatCompletionID string `json:"chatCompletionId,omitempty"` + ChatRequest any `json:"chatRequest,omitempty"` + ChatResponse any `json:"chatResponse,omitempty"` + ChatResponseCached bool `json:"chatResponseCached,omitempty"` + Content string `json:"content,omitempty"` } type EventType string diff --git a/pkg/server/log.go b/pkg/server/log.go new file mode 100644 index 00000000..aa5ff9ac --- /dev/null +++ b/pkg/server/log.go @@ -0,0 +1,5 @@ +package server + +import "github.com/acorn-io/gptscript/pkg/mvl" + +var log = mvl.Package() diff --git a/pkg/server/server.go b/pkg/server/server.go new file mode 100644 index 00000000..5c129e48 --- /dev/null +++ b/pkg/server/server.go @@ -0,0 +1,257 @@ +package server + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "io/fs" + "net/http" + "os" + "path/filepath" + "strings" + "sync/atomic" + "time" + + "github.com/acorn-io/broadcaster" + "github.com/acorn-io/gptscript/pkg/loader" + "github.com/acorn-io/gptscript/pkg/runner" + "github.com/acorn-io/gptscript/pkg/types" + "github.com/olahol/melody" +) + +type Options struct { + runner.CacheOptions + runner.OpenAIOptions + ListenAddress string +} + +func complete(opts []Options) (runnerOpts []runner.Options, result Options) { + for _, opt := range opts { + result.ListenAddress = types.FirstSet(opt.ListenAddress, result.ListenAddress) + runnerOpts = append(runnerOpts, runner.Options{ + CacheOptions: opt.CacheOptions, + OpenAIOptions: opt.OpenAIOptions, + }) + } + if result.ListenAddress == "" { + result.ListenAddress = "127.0.0.1:89090" + } + return +} + +func New(opts ...Options) (*Server, error) { + events := broadcaster.New[Event]() + + runnerOpts, opt := complete(opts) + r, err := runner.New(append(runnerOpts, runner.Options{ + MonitorFactory: &SessionFactory{ + events: events, + }, + })...) + if err != nil { + return nil, err + } + + return &Server{ + melody: melody.New(), + events: events, + runner: r, + listenAddress: opt.ListenAddress, + }, nil +} + +type Event struct { + runner.Event `json:",inline"` + RunID string `json:"runID,omitempty"` + Program *types.Program `json:"program,omitempty"` + Input string `json:"input,omitempty"` + Output string `json:"output,omitempty"` + Err string `json:"err,omitempty"` +} + +type Server struct { + melody *melody.Melody + runner *runner.Runner + events *broadcaster.Broadcaster[Event] + listenAddress string +} + +var ( + execID int64 +) + +type execKey struct{} + +func (s *Server) list(rw http.ResponseWriter, req *http.Request) { + path := filepath.Join(".", req.URL.Path) + files, err := os.ReadDir(path) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + var result []string + for _, file := range files { + if file.IsDir() && !strings.HasPrefix(file.Name(), ".") { + result = append(result, filepath.Join(path, file.Name())+"/") + } else if strings.HasSuffix(file.Name(), ".gpt") { + result = append(result, filepath.Join(path, file.Name())) + } + } + + enc := json.NewEncoder(rw) + enc.SetIndent("", " ") + _ = enc.Encode(result) +} + +func (s *Server) run(rw http.ResponseWriter, req *http.Request) { + path := filepath.Join(".", req.URL.Path) + if !strings.HasSuffix(path, ".gpt") { + path += ".gpt" + } + + prg, err := loader.Program(req.Context(), path, "") + if errors.Is(err, fs.ErrNotExist) { + http.NotFound(rw, req) + return + } else if err != nil { + http.Error(rw, err.Error(), http.StatusNotAcceptable) + return + } + + body, err := io.ReadAll(req.Body) + if err != nil { + http.Error(rw, err.Error(), http.StatusNotAcceptable) + return + } + + id := fmt.Sprint(atomic.AddInt64(&execID, 1)) + ctx := context.WithValue(req.Context(), execKey{}, id) + if req.URL.Query().Has("async") { + go func() { + _, _ = s.runner.Run(ctx, prg, os.Environ(), string(body)) + }() + err := json.NewEncoder(rw).Encode(map[string]any{ + "id": id, + }) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + } else { + out, err := s.runner.Run(ctx, prg, os.Environ(), string(body)) + if err == nil { + _, _ = rw.Write([]byte(out)) + } else { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + } +} + +func (s *Server) Start(ctx context.Context) error { + s.melody.HandleConnect(s.Connect) + go s.events.Start(ctx) + log.Infof("Listening on http://%s", s.listenAddress) + server := &http.Server{Addr: s.listenAddress, Handler: s} + context.AfterFunc(ctx, func() { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + _ = server.Shutdown(ctx) + }) + return server.ListenAndServe() +} + +func (s *Server) Connect(session *melody.Session) { + go func() { + sub := s.events.Subscribe() + defer sub.Close() + + for event := range sub.C { + data, err := json.Marshal(event) + if err != nil { + log.Errorf("error marshaling event: %v", err) + return + } + err = session.Write(data) + if err != nil { + log.Errorf("error writing event: %v", err) + return + } + } + }() +} + +func (s *Server) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + switch req.Method { + case http.MethodPost: + s.run(rw, req) + case http.MethodGet: + if strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { + err := s.melody.HandleRequest(rw, req) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + } else { + s.list(rw, req) + } + default: + http.NotFound(rw, req) + } +} + +type SessionFactory struct { + events *broadcaster.Broadcaster[Event] +} + +func (s SessionFactory) Start(ctx context.Context, prg *types.Program, env []string, input string) (runner.Monitor, error) { + id, _ := ctx.Value(execKey{}).(string) + + s.events.C <- Event{ + Event: runner.Event{ + Time: time.Now(), + Type: "runStart", + }, + RunID: id, + Program: prg, + } + + return &Session{ + id: id, + prj: prg, + env: env, + input: input, + events: s.events, + }, nil +} + +type Session struct { + id string + prj *types.Program + env []string + input string + events *broadcaster.Broadcaster[Event] +} + +func (s *Session) Event(event runner.Event) { + s.events.C <- Event{ + Event: event, + RunID: s.id, + Input: s.input, + } +} + +func (s *Session) Stop(output string, err error) { + e := Event{ + Event: runner.Event{ + Time: time.Now(), + Type: "runEnd", + }, + RunID: s.id, + Input: s.input, + Output: output, + } + if err != nil { + e.Err = err.Error() + } + s.events.C <- e +} From cbf8dcf5bac5f70c6ee81afe2f44a78b751d6836 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 6 Feb 2024 14:06:20 -0700 Subject: [PATCH 030/774] Add /sys and /*.gpt --- examples/search.gpt | 2 +- pkg/builtin/builtin.go | 10 ++++++++++ pkg/server/server.go | 25 +++++++++++++++++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/examples/search.gpt b/examples/search.gpt index b084f946..60dd2998 100644 --- a/examples/search.gpt +++ b/examples/search.gpt @@ -7,7 +7,7 @@ vacation spot give the name and description. name: search description: Searches the internet for content args: query: The query to search for -tools: sys.http.text? +tools: sys.http.html2text? First download the content of "https://html.duckduckgo.com/html/?q=${query}". Look for the first 5 search results. Download each search result and look for content diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index aecb2d7f..cd356117 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -82,6 +82,16 @@ var Tools = map[string]types.Tool{ }, } +func SysProgram() *types.Program { + result := &types.Program{ + ToolSet: types.ToolSet{}, + } + for _, tool := range ListTools() { + result.ToolSet[tool.ID] = tool + } + return result +} + func ListTools() (result []types.Tool) { var keys []string for k := range Tools { diff --git a/pkg/server/server.go b/pkg/server/server.go index 5c129e48..6981e244 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -15,6 +15,7 @@ import ( "time" "github.com/acorn-io/broadcaster" + "github.com/acorn-io/gptscript/pkg/builtin" "github.com/acorn-io/gptscript/pkg/loader" "github.com/acorn-io/gptscript/pkg/runner" "github.com/acorn-io/gptscript/pkg/types" @@ -85,12 +86,30 @@ var ( type execKey struct{} func (s *Server) list(rw http.ResponseWriter, req *http.Request) { + rw.Header().Set("Content-Type", "application/json") + enc := json.NewEncoder(rw) + enc.SetIndent("", " ") + path := filepath.Join(".", req.URL.Path) + if req.URL.Path == "/sys" { + _ = enc.Encode(builtin.SysProgram()) + return + } else if strings.HasSuffix(path, ".gpt") { + prg, err := loader.Program(req.Context(), path, "") + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + _ = enc.Encode(prg) + return + } + files, err := os.ReadDir(path) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } + var result []string for _, file := range files { if file.IsDir() && !strings.HasPrefix(file.Name(), ".") { @@ -100,8 +119,6 @@ func (s *Server) list(rw http.ResponseWriter, req *http.Request) { } } - enc := json.NewEncoder(rw) - enc.SetIndent("", " ") _ = enc.Encode(result) } @@ -186,7 +203,7 @@ func (s *Server) ServeHTTP(rw http.ResponseWriter, req *http.Request) { case http.MethodPost: s.run(rw, req) case http.MethodGet: - if strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { + if req.URL.Path == "/" && strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { err := s.melody.HandleRequest(rw, req) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) @@ -244,7 +261,7 @@ func (s *Session) Stop(output string, err error) { e := Event{ Event: runner.Event{ Time: time.Now(), - Type: "runEnd", + Type: "runFinish", }, RunID: s.id, Input: s.input, From 102ea13f4994d4eb71eb0a9f15cf8b69dc1085c3 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 6 Feb 2024 14:15:12 -0700 Subject: [PATCH 031/774] Clean up log output --- pkg/monitor/display.go | 48 ++++++++++++++++++++++++++++++------------ pkg/mvl/log.go | 2 +- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index fdbd6565..dbb4d0e4 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -8,6 +8,7 @@ import ( "os" "slices" "strings" + "sync" "sync/atomic" "time" @@ -33,7 +34,10 @@ type Console struct { displayProgress bool } -var runID int64 +var ( + runID int64 + prettyIDCounter int64 +) func (c *Console) Start(ctx context.Context, prg *types.Program, env []string, input string) (runner.Monitor, error) { id := atomic.AddInt64(&runID, 1) @@ -50,6 +54,8 @@ type display struct { dump dump livePrinter *livePrinter dumpState string + callIDMap map[string]string + callLock sync.Mutex } type livePrinter struct { @@ -83,6 +89,9 @@ func (l *livePrinter) print(event runner.Event, c call) { } func (d *display) Event(event runner.Event) { + d.callLock.Lock() + defer d.callLock.Unlock() + var ( currentIndex = -1 currentCall call @@ -111,10 +120,17 @@ func (d *display) Event(event runner.Event) { "parentID", currentCall.ParentID, "toolID", currentCall.ToolID) + prettyID, ok := d.callIDMap[currentCall.ID] + if !ok { + prettyID = fmt.Sprint(atomic.AddInt64(&prettyIDCounter, 1)) + d.callIDMap[currentCall.ID] = prettyID + } + callName := callName{ - call: ¤tCall, - prg: d.dump.Program, - calls: d.dump.Calls, + prettyID: prettyID, + call: ¤tCall, + prg: d.dump.Program, + calls: d.dump.Calls, } switch event.Type { @@ -122,12 +138,12 @@ func (d *display) Event(event runner.Event) { d.livePrinter.end() currentCall.Start = event.Time currentCall.Input = event.Content - log.Fields("input", event.Content).Infof("started [%s]", callName) + log.Fields("input", event.Content).Infof("started [%s]", callName) case runner.EventTypeCallProgress: d.livePrinter.print(event, currentCall) case runner.EventTypeCallContinue: d.livePrinter.end() - log.Fields("toolResults", event.ToolResults).Infof("continue [%s]", callName) + log.Fields("toolResults", event.ToolResults).Infof("continue [%s]", callName) case runner.EventTypeChat: d.livePrinter.end() if event.ChatRequest == nil { @@ -137,7 +153,7 @@ func (d *display) Event(event runner.Event) { "cached", event.ChatResponseCached, ) } else { - log.Infof("openai request sent [%s]", callName) + log.Infof("sent [%s]", callName) log = log.Fields( "completionID", event.ChatCompletionID, "request", toJSON(event.ChatRequest), @@ -154,7 +170,7 @@ func (d *display) Event(event runner.Event) { d.livePrinter.end() currentCall.End = event.Time currentCall.Output = event.Content - log.Fields("output", event.Content).Infof("ended [%s]", callName) + log.Fields("output", event.Content).Infof("ended [%s]", callName) } d.dump.Calls[currentIndex] = currentCall @@ -184,6 +200,7 @@ func NewConsole(opts ...Options) *Console { func newDisplay(dumpState string, progress bool) *display { display := &display{ dumpState: dumpState, + callIDMap: make(map[string]string), } if progress { display.livePrinter = &livePrinter{ @@ -220,9 +237,10 @@ func (j jsonDump) String() string { } type callName struct { - call *call - prg *types.Program - calls []call + prettyID string + call *call + prg *types.Program + calls []call } func (c callName) String() string { @@ -238,7 +256,7 @@ func (c callName) String() string { name = tool.Source.File } if currentCall.ID != "1" { - name += "(" + currentCall.ID + ")" + name += "(" + c.prettyID + ")" } msg = append(msg, name) found := false @@ -255,7 +273,11 @@ func (c callName) String() string { } slices.Reverse(msg) - return strings.Join(msg, "->") + result := strings.Join(msg[1:], "->") + if result == "" { + return "main" + } + return result } type dump struct { diff --git a/pkg/mvl/log.go b/pkg/mvl/log.go index e4a5c3da..ace857ec 100644 --- a/pkg/mvl/log.go +++ b/pkg/mvl/log.go @@ -29,7 +29,7 @@ func (f formatter) Format(entry *logrus.Entry) ([]byte, error) { msg += fmt.Sprintf(" [input=%s]", i) } return []byte(fmt.Sprintf("%s %s\n", - entry.Time.Format(time.RFC3339), + entry.Time.Format(time.TimeOnly), msg)), nil } From 3e094a7e62819a13b4612d9d62c00acf43a27f53 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 6 Feb 2024 17:05:53 -0700 Subject: [PATCH 032/774] Add temperature and non-modified env vars --- examples/search.gpt | 3 +++ go.mod | 11 +++++------ go.sum | 4 ++-- pkg/engine/engine.go | 8 ++++++++ pkg/openai/client.go | 7 ++++--- pkg/parser/parser.go | 14 ++++++++++++++ pkg/test/examples_test.go | 2 +- .../{fib.gpt.golden => fac.gpt.golden} | 0 pkg/types/completion.go | 1 + pkg/types/tool.go | 14 +++++++++----- 10 files changed, 47 insertions(+), 17 deletions(-) rename pkg/test/testdata/TestExamples/{fib.gpt.golden => fac.gpt.golden} (100%) diff --git a/examples/search.gpt b/examples/search.gpt index 60dd2998..a6781b2d 100644 --- a/examples/search.gpt +++ b/examples/search.gpt @@ -14,3 +14,6 @@ Look for the first 5 search results. Download each search result and look for co that would best answer the query ${query}. With all that information try your best to provide an answer or useful context to ${query}. + +If you can not retrieve a referenced URL then just skip that item and make a reference that +that URL was skipped. diff --git a/go.mod b/go.mod index 15796f4e..08a05c46 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/acorn-io/gptscript go 1.21.5 +replace github.com/sashabaranov/go-openai => github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a + require ( github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb @@ -20,12 +22,6 @@ require ( require ( github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd // indirect - github.com/kr/pretty v0.3.1 // indirect - github.com/onsi/ginkgo/v2 v2.13.0 // indirect - github.com/onsi/gomega v1.29.0 // indirect -) - -require ( github.com/bombsimon/logrusr/v4 v4.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.15.0 // indirect @@ -36,11 +32,14 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/hexops/valast v1.4.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/nightlyone/lockfile v1.0.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/onsi/ginkgo/v2 v2.13.0 // indirect + github.com/onsi/gomega v1.29.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/samber/lo v1.38.1 // indirect diff --git a/go.sum b/go.sum index 042e46be..8488bd12 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a h1:AdBbQ1ODOYK5AwCey4VFEmKeu9gG4PCzuO80pQmgupE= +github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/hexops/autogold v0.8.1/go.mod h1:97HLDXyG23akzAoRYJh/2OBs3kd80eHyKPvZw0S5ZBY= github.com/hexops/autogold v1.3.1 h1:YgxF9OHWbEIUjhDbpnLhgVsjUDsiHDTyDfy2lrfdlzo= github.com/hexops/autogold v1.3.1/go.mod h1:sQO+mQUCVfxOKPht+ipDSkJ2SCJ7BNJVHZexsXqWMx4= @@ -90,8 +92,6 @@ github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/samber/slog-logrus v1.0.0 h1:SsrN0p9akjCEaYd42Q5GtisMdHm0q11UD4fp4XCZi04= github.com/samber/slog-logrus v1.0.0/go.mod h1:ZTdPCmVWljwlfjz6XflKNvW4TcmYlexz4HMUOO/42bI= -github.com/sashabaranov/go-openai v1.18.3 h1:dspFGkmZbhjg1059KhqLYSV2GaCiRIn+bOu50TlXUq8= -github.com/sashabaranov/go-openai v1.18.3/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index e353e849..7ff29bae 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -182,17 +182,25 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) case string: envMap[envName] = val env = append(env, envName+"="+val) + envMap[k] = val + env = append(env, k+"="+val) case json.Number: envMap[envName] = string(val) env = append(env, envName+"="+string(val)) + envMap[k] = string(val) + env = append(env, k+"="+string(val)) case bool: envMap[envName] = fmt.Sprint(val) env = append(env, envName+"="+fmt.Sprint(val)) + envMap[k] = fmt.Sprint(val) + env = append(env, k+"="+fmt.Sprint(val)) default: data, err := json.Marshal(val) if err == nil { envMap[envName] = string(data) env = append(env, envName+"="+string(data)) + envMap[k] = string(data) + env = append(env, k+"="+string(data)) } } } diff --git a/pkg/openai/client.go b/pkg/openai/client.go index d95562a3..106a0a94 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -258,9 +258,10 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } request := openai.ChatCompletionRequest{ - Model: messageRequest.Model, - Messages: msgs, - MaxTokens: messageRequest.MaxToken, + Model: messageRequest.Model, + Messages: msgs, + MaxTokens: messageRequest.MaxToken, + Temperature: messageRequest.Temperature, } if messageRequest.JSONResponse { diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index efe65aff..a5782b22 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -23,6 +23,15 @@ func toBool(line string) (bool, error) { return false, nil } +func toFloatPtr(line string) (*float32, error) { + f, err := strconv.ParseFloat(line, 32) + if err != nil { + return nil, err + } + f32 := float32(f) + return &f32, nil +} + func csv(line string) (result []string) { for _, part := range strings.Split(line, ",") { result = append(result, strings.TrimSpace(part)) @@ -101,6 +110,11 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { if err != nil { return false, err } + case "temperature": + tool.Temperature, err = toFloatPtr(value) + if err != nil { + return false, err + } default: return false, nil } diff --git a/pkg/test/examples_test.go b/pkg/test/examples_test.go index 30bf8e29..ed2fddaa 100644 --- a/pkg/test/examples_test.go +++ b/pkg/test/examples_test.go @@ -20,7 +20,7 @@ func TestExamples(t *testing.T) { RequireOpenAPIKey(t) tests := []string{ - "fib.gpt", + "fac.gpt", "helloworld.gpt", } for _, entry := range tests { diff --git a/pkg/test/testdata/TestExamples/fib.gpt.golden b/pkg/test/testdata/TestExamples/fac.gpt.golden similarity index 100% rename from pkg/test/testdata/TestExamples/fib.gpt.golden rename to pkg/test/testdata/TestExamples/fac.gpt.golden diff --git a/pkg/types/completion.go b/pkg/types/completion.go index 715d7294..26375ca4 100644 --- a/pkg/types/completion.go +++ b/pkg/types/completion.go @@ -17,6 +17,7 @@ type CompletionRequest struct { Tools []CompletionTool Messages []CompletionMessage MaxToken int + Temperature *float32 JSONResponse bool Cache *bool } diff --git a/pkg/types/tool.go b/pkg/types/tool.go index d84ff6bd..35beff9d 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -26,11 +26,12 @@ type Tool struct { ToolMapping map[string]string `json:"toolMapping,omitempty"` BuiltinFunc BuiltinFunc `json:"-"` - Vision bool `json:"vision,omitempty"` - MaxTokens int `json:"maxTokens,omitempty"` - ModelName string `json:"modelName,omitempty"` - JSONResponse bool `json:"jsonResponse,omitempty"` - Cache *bool `json:"cache,omitempty"` + Vision bool `json:"vision,omitempty"` + MaxTokens int `json:"maxTokens,omitempty"` + ModelName string `json:"modelName,omitempty"` + JSONResponse bool `json:"jsonResponse,omitempty"` + Temperature *float32 `json:"temperature,omitempty"` + Cache *bool `json:"cache,omitempty"` Source ToolSource `json:"source,omitempty"` } @@ -61,6 +62,9 @@ func (t Tool) String() string { if t.Cache != nil && !*t.Cache { _, _ = fmt.Fprintln(buf, "Cache: false") } + if t.Temperature != nil { + _, _ = fmt.Fprintf(buf, "Temperature: %f", *t.Temperature) + } if t.Arguments != nil { var keys []string for k := range t.Arguments.Properties { From 8bd960db7155f28974b1af02db1314e94df9515f Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 6 Feb 2024 17:44:48 -0700 Subject: [PATCH 033/774] Default temperature to 0 --- pkg/engine/engine.go | 1 + pkg/openai/client.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 7ff29bae..a065bd0a 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -273,6 +273,7 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { MaxToken: tool.MaxTokens, JSONResponse: tool.JSONResponse, Cache: tool.Cache, + Temperature: tool.Temperature, } if InternalSystemPrompt != "" { diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 106a0a94..cbf45a1b 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -264,6 +264,10 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques Temperature: messageRequest.Temperature, } + if request.Temperature == nil { + request.Temperature = new(float32) + } + if messageRequest.JSONResponse { request.ResponseFormat = &openai.ChatCompletionResponseFormat{ Type: openai.ChatCompletionResponseFormatTypeJSONObject, From ae73de1f4155ff27f79e8b7eb3180b70a1b68dd4 Mon Sep 17 00:00:00 2001 From: Vincent Fiduccia Date: Wed, 7 Feb 2024 02:24:40 -0700 Subject: [PATCH 034/774] Default port is 9090 --- pkg/server/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/server/server.go b/pkg/server/server.go index 6981e244..57a3c3d4 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -37,7 +37,7 @@ func complete(opts []Options) (runnerOpts []runner.Options, result Options) { }) } if result.ListenAddress == "" { - result.ListenAddress = "127.0.0.1:89090" + result.ListenAddress = "127.0.0.1:9090" } return } From 727668c999082fc2e11fe416ed746201a94316ab Mon Sep 17 00:00:00 2001 From: Vincent Fiduccia Date: Wed, 7 Feb 2024 02:24:59 -0700 Subject: [PATCH 035/774] Async response is JSON --- pkg/server/server.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/server/server.go b/pkg/server/server.go index 57a3c3d4..94df1f4c 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -149,6 +149,7 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { go func() { _, _ = s.runner.Run(ctx, prg, os.Environ(), string(body)) }() + rw.Header().Set("Content-Type", "application/json") err := json.NewEncoder(rw).Encode(map[string]any{ "id": id, }) From 199a582b0b3efd3b8c269f70646edd94377e5c04 Mon Sep 17 00:00:00 2001 From: Vincent Fiduccia Date: Wed, 7 Feb 2024 02:25:09 -0700 Subject: [PATCH 036/774] CORS support --- go.mod | 1 + go.sum | 2 ++ pkg/server/server.go | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 08a05c46..00410e41 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/onsi/gomega v1.29.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rs/cors v1.10.1 // indirect github.com/samber/lo v1.38.1 // indirect github.com/samber/slog-logrus v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect diff --git a/go.sum b/go.sum index 8488bd12..b9e179d7 100644 --- a/go.sum +++ b/go.sum @@ -87,6 +87,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= diff --git a/pkg/server/server.go b/pkg/server/server.go index 94df1f4c..8d2a12df 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -20,6 +20,7 @@ import ( "github.com/acorn-io/gptscript/pkg/runner" "github.com/acorn-io/gptscript/pkg/types" "github.com/olahol/melody" + "github.com/rs/cors" ) type Options struct { @@ -170,12 +171,14 @@ func (s *Server) Start(ctx context.Context) error { s.melody.HandleConnect(s.Connect) go s.events.Start(ctx) log.Infof("Listening on http://%s", s.listenAddress) - server := &http.Server{Addr: s.listenAddress, Handler: s} + handler := cors.Default().Handler(s) + server := &http.Server{Addr: s.listenAddress, Handler: handler} context.AfterFunc(ctx, func() { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() _ = server.Shutdown(ctx) }) + return server.ListenAndServe() } From 5f51f2433b9a29bc15dc099abf25955902447c54 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:45:45 -0500 Subject: [PATCH 037/774] chore: transfer module ownership to gptscript-ai Update the go module path to reflect the change in ownership from `acorn-io` to `gptscript-ai`. Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- go.mod | 4 ++-- main.go | 2 +- pkg/assemble/assemble.go | 2 +- pkg/builtin/builtin.go | 2 +- pkg/builtin/log.go | 2 +- pkg/cache/cache.go | 4 ++-- pkg/cli/gptscript.go | 20 ++++++++++---------- pkg/engine/engine.go | 6 +++--- pkg/engine/log.go | 2 +- pkg/input/log.go | 2 +- pkg/loader/defaults.go | 4 ++-- pkg/loader/loader.go | 8 ++++---- pkg/loader/log.go | 2 +- pkg/monitor/display.go | 4 ++-- pkg/monitor/log.go | 2 +- pkg/openai/client.go | 8 ++++---- pkg/parser/parser.go | 2 +- pkg/runner/monitor.go | 2 +- pkg/runner/runner.go | 8 ++++---- pkg/server/log.go | 2 +- pkg/server/server.go | 8 ++++---- pkg/test/examples_test.go | 4 ++-- pkg/vision/image.go | 6 +++--- pkg/vision/schema.go | 2 +- 24 files changed, 54 insertions(+), 54 deletions(-) diff --git a/go.mod b/go.mod index 00410e41..e9dd6c3c 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/acorn-io/gptscript +module github.com/gptscript-ai/gptscript go 1.21.5 @@ -12,6 +12,7 @@ require ( github.com/hexops/autogold/v2 v2.1.0 github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 github.com/olahol/melody v1.1.4 + github.com/rs/cors v1.10.1 github.com/sashabaranov/go-openai v1.18.3 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 @@ -42,7 +43,6 @@ require ( github.com/onsi/gomega v1.29.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/rs/cors v1.10.1 // indirect github.com/samber/lo v1.38.1 // indirect github.com/samber/slog-logrus v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect diff --git a/main.go b/main.go index 953da23a..3ac87972 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,7 @@ package main import ( "github.com/acorn-io/cmd" - "github.com/acorn-io/gptscript/pkg/cli" + "github.com/gptscript-ai/gptscript/pkg/cli" ) func main() { diff --git a/pkg/assemble/assemble.go b/pkg/assemble/assemble.go index 1d1500f2..f5644eb1 100644 --- a/pkg/assemble/assemble.go +++ b/pkg/assemble/assemble.go @@ -5,7 +5,7 @@ import ( "encoding/json" "io" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/types" ) var Header = []byte("GPTSCRIPT!") diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index cd356117..6b5d4797 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -13,7 +13,7 @@ import ( "sort" "strings" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/types" "github.com/jaytaylor/html2text" ) diff --git a/pkg/builtin/log.go b/pkg/builtin/log.go index 8457cf2e..652dd6aa 100644 --- a/pkg/builtin/log.go +++ b/pkg/builtin/log.go @@ -1,5 +1,5 @@ package builtin -import "github.com/acorn-io/gptscript/pkg/mvl" +import "github.com/gptscript-ai/gptscript/pkg/mvl" var log = mvl.Package() diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index dface4dc..d3afc744 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -7,9 +7,9 @@ import ( "os" "path/filepath" - "github.com/acorn-io/gptscript/pkg/types" - "github.com/acorn-io/gptscript/pkg/version" "github.com/adrg/xdg" + "github.com/gptscript-ai/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/version" ) type Client struct { diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index e8344872..e75fe05e 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -8,16 +8,16 @@ import ( "strings" "github.com/acorn-io/cmd" - "github.com/acorn-io/gptscript/pkg/assemble" - "github.com/acorn-io/gptscript/pkg/builtin" - "github.com/acorn-io/gptscript/pkg/input" - "github.com/acorn-io/gptscript/pkg/loader" - "github.com/acorn-io/gptscript/pkg/monitor" - "github.com/acorn-io/gptscript/pkg/mvl" - "github.com/acorn-io/gptscript/pkg/openai" - "github.com/acorn-io/gptscript/pkg/runner" - "github.com/acorn-io/gptscript/pkg/server" - "github.com/acorn-io/gptscript/pkg/version" + "github.com/gptscript-ai/gptscript/pkg/assemble" + "github.com/gptscript-ai/gptscript/pkg/builtin" + "github.com/gptscript-ai/gptscript/pkg/input" + "github.com/gptscript-ai/gptscript/pkg/loader" + "github.com/gptscript-ai/gptscript/pkg/monitor" + "github.com/gptscript-ai/gptscript/pkg/mvl" + "github.com/gptscript-ai/gptscript/pkg/openai" + "github.com/gptscript-ai/gptscript/pkg/runner" + "github.com/gptscript-ai/gptscript/pkg/server" + "github.com/gptscript-ai/gptscript/pkg/version" "github.com/spf13/cobra" "golang.org/x/term" ) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index a065bd0a..22cc67d3 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -11,10 +11,10 @@ import ( "sync" "sync/atomic" - "github.com/acorn-io/gptscript/pkg/openai" - "github.com/acorn-io/gptscript/pkg/types" - "github.com/acorn-io/gptscript/pkg/version" "github.com/google/shlex" + "github.com/gptscript-ai/gptscript/pkg/openai" + "github.com/gptscript-ai/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/version" ) // InternalSystemPrompt is added to all threads. Changing this is very dangerous as it has a diff --git a/pkg/engine/log.go b/pkg/engine/log.go index 4a0f49ca..4aad890b 100644 --- a/pkg/engine/log.go +++ b/pkg/engine/log.go @@ -1,5 +1,5 @@ package engine -import "github.com/acorn-io/gptscript/pkg/mvl" +import "github.com/gptscript-ai/gptscript/pkg/mvl" var log = mvl.Package() diff --git a/pkg/input/log.go b/pkg/input/log.go index 7ffc0a4c..6abcc712 100644 --- a/pkg/input/log.go +++ b/pkg/input/log.go @@ -1,5 +1,5 @@ package input -import "github.com/acorn-io/gptscript/pkg/mvl" +import "github.com/gptscript-ai/gptscript/pkg/mvl" var log = mvl.Package() diff --git a/pkg/loader/defaults.go b/pkg/loader/defaults.go index 47390e32..7d41d0ad 100644 --- a/pkg/loader/defaults.go +++ b/pkg/loader/defaults.go @@ -1,8 +1,8 @@ package loader import ( - "github.com/acorn-io/gptscript/pkg/openai" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/openai" + "github.com/gptscript-ai/gptscript/pkg/types" ) var ( diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index ca459855..23155b84 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -18,10 +18,10 @@ import ( "regexp" "strings" - "github.com/acorn-io/gptscript/pkg/assemble" - "github.com/acorn-io/gptscript/pkg/builtin" - "github.com/acorn-io/gptscript/pkg/parser" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/assemble" + "github.com/gptscript-ai/gptscript/pkg/builtin" + "github.com/gptscript-ai/gptscript/pkg/parser" + "github.com/gptscript-ai/gptscript/pkg/types" ) const ( diff --git a/pkg/loader/log.go b/pkg/loader/log.go index c46464e7..96167d5a 100644 --- a/pkg/loader/log.go +++ b/pkg/loader/log.go @@ -1,5 +1,5 @@ package loader -import "github.com/acorn-io/gptscript/pkg/mvl" +import "github.com/gptscript-ai/gptscript/pkg/mvl" var log = mvl.Package() diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index dbb4d0e4..e4ababd4 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -12,8 +12,8 @@ import ( "sync/atomic" "time" - "github.com/acorn-io/gptscript/pkg/runner" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/runner" + "github.com/gptscript-ai/gptscript/pkg/types" ) type Options struct { diff --git a/pkg/monitor/log.go b/pkg/monitor/log.go index 36a8d5aa..778c8d36 100644 --- a/pkg/monitor/log.go +++ b/pkg/monitor/log.go @@ -1,5 +1,5 @@ package monitor -import "github.com/acorn-io/gptscript/pkg/mvl" +import "github.com/gptscript-ai/gptscript/pkg/mvl" var log = mvl.Package() diff --git a/pkg/openai/client.go b/pkg/openai/client.go index cbf45a1b..1e2d327e 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -13,10 +13,10 @@ import ( "strings" "sync/atomic" - "github.com/acorn-io/gptscript/pkg/cache" - "github.com/acorn-io/gptscript/pkg/hash" - "github.com/acorn-io/gptscript/pkg/types" - "github.com/acorn-io/gptscript/pkg/vision" + "github.com/gptscript-ai/gptscript/pkg/cache" + "github.com/gptscript-ai/gptscript/pkg/hash" + "github.com/gptscript-ai/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/vision" "github.com/sashabaranov/go-openai" ) diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index a5782b22..293427fb 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/types" ) func normalize(key string) string { diff --git a/pkg/runner/monitor.go b/pkg/runner/monitor.go index db228196..0a7eba25 100644 --- a/pkg/runner/monitor.go +++ b/pkg/runner/monitor.go @@ -3,7 +3,7 @@ package runner import ( "context" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/types" ) type noopFactory struct { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 7081db32..656f539d 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -5,10 +5,10 @@ import ( "sync" "time" - "github.com/acorn-io/gptscript/pkg/cache" - "github.com/acorn-io/gptscript/pkg/engine" - "github.com/acorn-io/gptscript/pkg/openai" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/cache" + "github.com/gptscript-ai/gptscript/pkg/engine" + "github.com/gptscript-ai/gptscript/pkg/openai" + "github.com/gptscript-ai/gptscript/pkg/types" "golang.org/x/sync/errgroup" ) diff --git a/pkg/server/log.go b/pkg/server/log.go index aa5ff9ac..e4502294 100644 --- a/pkg/server/log.go +++ b/pkg/server/log.go @@ -1,5 +1,5 @@ package server -import "github.com/acorn-io/gptscript/pkg/mvl" +import "github.com/gptscript-ai/gptscript/pkg/mvl" var log = mvl.Package() diff --git a/pkg/server/server.go b/pkg/server/server.go index 8d2a12df..68dc9a5e 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -15,10 +15,10 @@ import ( "time" "github.com/acorn-io/broadcaster" - "github.com/acorn-io/gptscript/pkg/builtin" - "github.com/acorn-io/gptscript/pkg/loader" - "github.com/acorn-io/gptscript/pkg/runner" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/builtin" + "github.com/gptscript-ai/gptscript/pkg/loader" + "github.com/gptscript-ai/gptscript/pkg/runner" + "github.com/gptscript-ai/gptscript/pkg/types" "github.com/olahol/melody" "github.com/rs/cors" ) diff --git a/pkg/test/examples_test.go b/pkg/test/examples_test.go index ed2fddaa..747144b4 100644 --- a/pkg/test/examples_test.go +++ b/pkg/test/examples_test.go @@ -6,8 +6,8 @@ import ( "path/filepath" "testing" - "github.com/acorn-io/gptscript/pkg/loader" - "github.com/acorn-io/gptscript/pkg/runner" + "github.com/gptscript-ai/gptscript/pkg/loader" + "github.com/gptscript-ai/gptscript/pkg/runner" "github.com/hexops/autogold/v2" "github.com/stretchr/testify/require" ) diff --git a/pkg/vision/image.go b/pkg/vision/image.go index f1068d61..a021723d 100644 --- a/pkg/vision/image.go +++ b/pkg/vision/image.go @@ -8,9 +8,9 @@ import ( "os" "strings" - "github.com/acorn-io/gptscript/pkg/cache" - "github.com/acorn-io/gptscript/pkg/hash" - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/cache" + "github.com/gptscript-ai/gptscript/pkg/hash" + "github.com/gptscript-ai/gptscript/pkg/types" ) var ( diff --git a/pkg/vision/schema.go b/pkg/vision/schema.go index 2225b039..1fb41d9e 100644 --- a/pkg/vision/schema.go +++ b/pkg/vision/schema.go @@ -1,7 +1,7 @@ package vision import ( - "github.com/acorn-io/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/types" ) var ( From 8b4029b761836661d63320e45a491c04ba364d99 Mon Sep 17 00:00:00 2001 From: Sheng Liang Date: Wed, 7 Feb 2024 14:45:10 -0800 Subject: [PATCH 038/774] Fix examples --- examples/fac.gpt | 5 ++++- examples/search.gpt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/fac.gpt b/examples/fac.gpt index 3551e4b7..582f8d14 100644 --- a/examples/fac.gpt +++ b/examples/fac.gpt @@ -8,7 +8,10 @@ description: A function taking an integer as argument and returns an integer args: number: An integer tools: myfunction -If ${number} is 0 return 1. Otherwise return myfunction(${number}-1) * ${number} +Do the following in strict order: +1. If ${number} is 0 skip the remaining steps and return 1 +2. Calculate the myfunction of (${number} - 1) +3. Return ${number} multiply the result of the previous step --- name: sub diff --git a/examples/search.gpt b/examples/search.gpt index b084f946..e65af954 100644 --- a/examples/search.gpt +++ b/examples/search.gpt @@ -7,7 +7,7 @@ vacation spot give the name and description. name: search description: Searches the internet for content args: query: The query to search for -tools: sys.http.text? +tools: sys.http.text2html? First download the content of "https://html.duckduckgo.com/html/?q=${query}". Look for the first 5 search results. Download each search result and look for content From aaba2799cda4c4f81685882c5946333b716b5027 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Wed, 7 Feb 2024 17:00:50 -0700 Subject: [PATCH 039/774] Support "-" in -o --- pkg/cli/gptscript.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index e75fe05e..2712f373 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -31,7 +31,7 @@ type GPTScript struct { DisplayOptions Debug bool `usage:"Enable debug logging"` Quiet bool `usage:"No output logging" short:"q"` - Output string `usage:"Save output to a file" short:"o"` + Output string `usage:"Save output to a file, or - for stdout" short:"o"` Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"` SubTool string `usage:"Use tool of this name, not the first tool in file"` Assemble bool `usage:"Assemble tool to a single artifact, saved to --output"` @@ -129,7 +129,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { if r.Assemble { var out io.Writer = os.Stdout - if r.Output != "" { + if r.Output != "" && r.Output != "-" { f, err := os.Create(r.Output) if err != nil { return fmt.Errorf("opening %s: %w", r.Output, err) From fa5634f0eff4f3f24ef7aa2dba5806ab384745b1 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Wed, 7 Feb 2024 17:01:09 -0700 Subject: [PATCH 040/774] Switch to go 1.22.0 --- go.mod | 2 +- pkg/runner/runner.go | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e9dd6c3c..0384242a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/gptscript-ai/gptscript -go 1.21.5 +go 1.22.0 replace github.com/sashabaranov/go-openai => github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 656f539d..f84cc46b 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -203,8 +203,6 @@ func (r *Runner) subCalls(callCtx engine.Context, monitor Monitor, env []string, eg, subCtx := errgroup.WithContext(callCtx.Ctx) for id, call := range lastReturn.Calls { - id := id - call := call eg.Go(func() error { callCtx, err := callCtx.SubCall(subCtx, call.ToolName, id) if err != nil { From 840ac9761d03e951829a549a0aa86fe4d1a3b227 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Wed, 7 Feb 2024 17:01:32 -0700 Subject: [PATCH 041/774] Allow embedding gptscripts in python files --- pkg/parser/parser.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 293427fb..71331918 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -11,7 +11,7 @@ import ( ) func normalize(key string) string { - return strings.ToLower(strings.ReplaceAll(key, " ", "")) + return strings.TrimSpace(strings.ToLower(strings.ReplaceAll(key, " ", ""))) } func toBool(line string) (bool, error) { @@ -156,6 +156,17 @@ func (c *context) finish(tools *[]types.Tool) { *c = context{} } +func commentEmbedded(line string) (string, bool) { + for _, i := range []string{"#", "# ", "//", "// "} { + prefix := i + "gptscript:" + cut, ok := strings.CutPrefix(line, prefix) + if ok { + return cut, ok + } + } + return line, false +} + func Parse(input io.Reader) ([]types.Tool, error) { scan := bufio.NewScanner(input) @@ -179,6 +190,16 @@ func Parse(input io.Reader) ([]types.Tool, error) { } if !context.inBody { + // Strip special comments to allow embedding the preamble in python or other interpreted languages + if newLine, ok := commentEmbedded(line); ok { + line = newLine + } + + // If the very first line is #! just skip because this is a unix interpreter declaration + if strings.HasPrefix(line, "#!") && lineNo == 1 { + continue + } + // This is a comment if strings.HasPrefix(line, "#") && !strings.HasPrefix(line, "#!") { continue From 78917b285bd6d0630b55f4fe0ed21abf6397e9d6 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Wed, 7 Feb 2024 17:08:48 -0700 Subject: [PATCH 042/774] Don't pass file to interpreter if it is zero length --- pkg/engine/engine.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 22cc67d3..1598a988 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -207,17 +207,6 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) } interpreter, rest, _ := strings.Cut(tool.Instructions, "\n") - f, err := os.CreateTemp("", version.ProgramName) - if err != nil { - return "", err - } - defer os.Remove(f.Name()) - - _, err = f.Write([]byte(rest)) - _ = f.Close() - if err != nil { - return "", err - } interpreter = strings.TrimSpace(interpreter)[2:] interpreter = os.Expand(interpreter, func(s string) string { @@ -238,8 +227,24 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) } output := &bytes.Buffer{} + cmdArgs := args[1:] + + if strings.TrimSpace(rest) != "" { + f, err := os.CreateTemp("", version.ProgramName) + if err != nil { + return "", err + } + defer os.Remove(f.Name()) + + _, err = f.Write([]byte(rest)) + _ = f.Close() + if err != nil { + return "", err + } + cmdArgs = append(cmdArgs, f.Name()) + } - cmd := exec.Command(args[0], append(args[1:], f.Name())...) + cmd := exec.Command(args[0], cmdArgs...) cmd.Env = env cmd.Stdin = strings.NewReader(input) cmd.Stderr = os.Stderr From 0b88314d5a2f35a4ab5f8de39d292a431dd0d27c Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 8 Feb 2024 09:11:57 -0700 Subject: [PATCH 043/774] Add initial http and daemon support. Add nocache flag --- go.mod | 16 ++--- go.sum | 35 +++++----- pkg/engine/cmd.go | 157 +++++++++++++++++++++++++++++++++++++++++++ pkg/engine/daemon.go | 99 +++++++++++++++++++++++++++ pkg/engine/engine.go | 130 +++-------------------------------- pkg/engine/http.go | 44 ++++++++++++ pkg/server/server.go | 21 +++++- pkg/types/tool.go | 9 +++ 8 files changed, 365 insertions(+), 146 deletions(-) create mode 100644 pkg/engine/cmd.go create mode 100644 pkg/engine/daemon.go create mode 100644 pkg/engine/http.go diff --git a/go.mod b/go.mod index 0384242a..c6923139 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 - golang.org/x/sync v0.5.0 + golang.org/x/sync v0.6.0 golang.org/x/term v0.16.0 ) @@ -25,7 +25,7 @@ require ( github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd // indirect github.com/bombsimon/logrusr/v4 v4.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect @@ -33,27 +33,25 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/hexops/valast v1.4.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/kr/pretty v0.3.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/nightlyone/lockfile v1.0.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo/v2 v2.13.0 // indirect github.com/onsi/gomega v1.29.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/samber/lo v1.38.1 // indirect github.com/samber/slog-logrus v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.19.0 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.20.0 // indirect golang.org/x/sys v0.16.0 // indirect - golang.org/x/tools v0.16.0 // indirect + golang.org/x/tools v0.17.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect - mvdan.cc/gofumpt v0.4.0 // indirect + mvdan.cc/gofumpt v0.6.0 // indirect sigs.k8s.io/controller-runtime v0.16.3 // indirect ) diff --git a/go.sum b/go.sum index b9e179d7..50f4659b 100644 --- a/go.sum +++ b/go.sum @@ -14,10 +14,11 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -66,8 +67,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/nightlyone/lockfile v1.0.0 h1:RHep2cFKK4PonZJDdEl4GmkabuhbsRMgk/k3uAmxBiA= @@ -85,8 +86,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -113,20 +114,20 @@ golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcH golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -140,6 +141,7 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -157,8 +159,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -171,7 +173,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM= mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= +mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= +mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= diff --git a/pkg/engine/cmd.go b/pkg/engine/cmd.go new file mode 100644 index 00000000..ca4de79b --- /dev/null +++ b/pkg/engine/cmd.go @@ -0,0 +1,157 @@ +package engine + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "os" + "os/exec" + "strings" + "sync/atomic" + + "github.com/google/shlex" + "github.com/gptscript-ai/gptscript/pkg/openai" + "github.com/gptscript-ai/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/pkg/version" +) + +func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) (cmdOut string, cmdErr error) { + id := fmt.Sprint(atomic.AddInt64(&completionID, 1)) + + defer func() { + e.Progress <- openai.Status{ + CompletionID: id, + Response: map[string]any{ + "output": cmdOut, + "err": cmdErr, + }, + } + }() + + if tool.BuiltinFunc != nil { + e.Progress <- openai.Status{ + CompletionID: id, + Request: map[string]any{ + "command": []string{tool.ID}, + "input": input, + }, + } + return tool.BuiltinFunc(ctx, e.Env, input) + } + + cmd, close, err := e.newCommand(ctx, nil, tool.Instructions, input) + if err != nil { + return "", err + } + defer close() + + e.Progress <- openai.Status{ + CompletionID: id, + Request: map[string]any{ + "command": cmd.Args, + "input": input, + }, + } + + output := &bytes.Buffer{} + cmd.Stdin = strings.NewReader(input) + cmd.Stderr = os.Stderr + cmd.Stdout = output + + if err := cmd.Run(); err != nil { + _, _ = os.Stderr.Write(output.Bytes()) + log.Errorf("failed to run tool [%s] cmd %v: %v", tool.Name, cmd.Args, err) + return "", err + } + + return output.String(), nil +} + +func (e *Engine) newCommand(ctx context.Context, extraEnv []string, instructions, input string) (*exec.Cmd, func(), error) { + env := append(e.Env[:], extraEnv...) + data := map[string]any{} + + dec := json.NewDecoder(bytes.NewReader([]byte(input))) + dec.UseNumber() + + envMap := map[string]string{} + for _, env := range env { + key, value, ok := strings.Cut(env, "=") + key, ok = strings.CutPrefix(key, "GPTSCRIPT_VAR_") + if !ok { + continue + } + envMap[key] = value + } + + if err := json.Unmarshal([]byte(input), &data); err == nil { + for k, v := range data { + envName := strings.ToUpper(strings.ReplaceAll(k, "-", "_")) + switch val := v.(type) { + case string: + envMap[envName] = val + env = append(env, envName+"="+val) + envMap[k] = val + env = append(env, k+"="+val) + case json.Number: + envMap[envName] = string(val) + env = append(env, envName+"="+string(val)) + envMap[k] = string(val) + env = append(env, k+"="+string(val)) + case bool: + envMap[envName] = fmt.Sprint(val) + env = append(env, envName+"="+fmt.Sprint(val)) + envMap[k] = fmt.Sprint(val) + env = append(env, k+"="+fmt.Sprint(val)) + default: + data, err := json.Marshal(val) + if err == nil { + envMap[envName] = string(data) + env = append(env, envName+"="+string(data)) + envMap[k] = string(data) + env = append(env, k+"="+string(data)) + } + } + } + } + + interpreter, rest, _ := strings.Cut(instructions, "\n") + interpreter = strings.TrimSpace(interpreter)[2:] + + interpreter = os.Expand(interpreter, func(s string) string { + return envMap[s] + }) + + args, err := shlex.Split(interpreter) + if err != nil { + return nil, nil, err + } + + var ( + cmdArgs = args[1:] + close func() + ) + + if strings.TrimSpace(rest) != "" { + f, err := os.CreateTemp("", version.ProgramName) + if err != nil { + return nil, nil, err + } + close = func() { + os.Remove(f.Name()) + } + + _, err = f.Write([]byte(rest)) + _ = f.Close() + if err != nil { + close() + return nil, nil, err + } + cmdArgs = append(cmdArgs, f.Name()) + } + + cmd := exec.CommandContext(ctx, args[0], cmdArgs...) + cmd.Env = env + return cmd, close, nil +} diff --git a/pkg/engine/daemon.go b/pkg/engine/daemon.go new file mode 100644 index 00000000..6055cf26 --- /dev/null +++ b/pkg/engine/daemon.go @@ -0,0 +1,99 @@ +package engine + +import ( + "context" + "fmt" + "io" + "net/http" + "os" + "strings" + "time" + + "github.com/gptscript-ai/gptscript/pkg/types" +) + +func (e *Engine) getNextPort() int64 { + count := e.endPort - e.startPort + e.nextPort++ + e.nextPort = e.nextPort % count + return e.startPort + e.nextPort +} + +func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, error) { + e.daemonLock.Lock() + defer e.daemonLock.Unlock() + + port, ok := e.daemonPorts[tool.ID] + url := fmt.Sprintf("http://127.0.0.1:%d", port) + if ok { + return url, nil + } + + port = e.getNextPort() + + instructions := strings.TrimPrefix(tool.Instructions, "#!daemon ") + cmd, close, err := e.newCommand(ctx, []string{ + fmt.Sprintf("PORT=%d", port), + }, + instructions, + "{}", + ) + if err != nil { + return url, err + } + + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + log.Infof("launching [%s] port [%d] %v", tool.Name, port, cmd.Args) + if err := cmd.Start(); err != nil { + close() + return url, err + } + + go func() { + if err := cmd.Wait(); err != nil { + log.Errorf("daemon exited tool [%s] %v: %v", tool.Name, cmd.Args, err) + } + + close() + e.daemonLock.Lock() + defer e.daemonLock.Unlock() + + delete(e.daemonPorts, tool.ID) + }() + + context.AfterFunc(ctx, func() { + cmd.Process.Kill() + }) + + for range 20 { + resp, err := http.Get(url) + if err == nil && resp.StatusCode == http.StatusOK { + defer func() { + _ = resp.Body.Close() + }() + go func() { + _, _ = io.ReadAll(resp.Body) + }() + return url, nil + } + select { + case <-ctx.Done(): + return url, ctx.Err() + case <-time.After(time.Second): + } + } + + return url, fmt.Errorf("timeout waiting for 200 response from GET %s", url) +} + +func (e *Engine) runDaemon(ctx context.Context, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { + url, err := e.startDaemon(ctx, tool) + if err != nil { + return nil, err + } + + tool.Instructions = strings.Join(append([]string{url}, + strings.Split(tool.Instructions, "\n")[1:]...), "\n") + return e.runHTTP(ctx, tool, input) +} diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 1598a988..e3a76ef9 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -1,17 +1,13 @@ package engine import ( - "bytes" "context" "encoding/json" "fmt" "os" - "os/exec" - "strings" "sync" "sync/atomic" - "github.com/google/shlex" "github.com/gptscript-ai/gptscript/pkg/openai" "github.com/gptscript-ai/gptscript/pkg/types" "github.com/gptscript-ai/gptscript/pkg/version" @@ -47,6 +43,12 @@ type Engine struct { Client *openai.Client Env []string Progress chan<- openai.Status + + daemonPorts map[string]int64 + daemonLock sync.Mutex + + startPort, endPort int64 + nextPort int64 } type State struct { @@ -144,125 +146,15 @@ func (c *Context) getTool(name string) (types.Tool, error) { return tool, nil } -func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) (cmdOut string, cmdErr error) { - id := fmt.Sprint(atomic.AddInt64(&completionID, 1)) - - defer func() { - e.Progress <- openai.Status{ - CompletionID: id, - Response: map[string]any{ - "output": cmdOut, - "err": cmdErr, - }, - } - }() - - if tool.BuiltinFunc != nil { - e.Progress <- openai.Status{ - CompletionID: id, - Request: map[string]any{ - "command": []string{tool.ID}, - "input": input, - }, - } - return tool.BuiltinFunc(ctx, e.Env, input) - } - - env := e.Env[:] - data := map[string]any{} - - dec := json.NewDecoder(bytes.NewReader([]byte(input))) - dec.UseNumber() - - envMap := map[string]string{} - if err := json.Unmarshal([]byte(input), &data); err == nil { - for k, v := range data { - envName := strings.ToUpper(strings.ReplaceAll(k, "-", "_")) - switch val := v.(type) { - case string: - envMap[envName] = val - env = append(env, envName+"="+val) - envMap[k] = val - env = append(env, k+"="+val) - case json.Number: - envMap[envName] = string(val) - env = append(env, envName+"="+string(val)) - envMap[k] = string(val) - env = append(env, k+"="+string(val)) - case bool: - envMap[envName] = fmt.Sprint(val) - env = append(env, envName+"="+fmt.Sprint(val)) - envMap[k] = fmt.Sprint(val) - env = append(env, k+"="+fmt.Sprint(val)) - default: - data, err := json.Marshal(val) - if err == nil { - envMap[envName] = string(data) - env = append(env, envName+"="+string(data)) - envMap[k] = string(data) - env = append(env, k+"="+string(data)) - } - } - } - } - - interpreter, rest, _ := strings.Cut(tool.Instructions, "\n") - interpreter = strings.TrimSpace(interpreter)[2:] - - interpreter = os.Expand(interpreter, func(s string) string { - return envMap[s] - }) - - args, err := shlex.Split(interpreter) - if err != nil { - return "", err - } - - e.Progress <- openai.Status{ - CompletionID: id, - Request: map[string]any{ - "command": args, - "input": input, - }, - } - - output := &bytes.Buffer{} - cmdArgs := args[1:] - - if strings.TrimSpace(rest) != "" { - f, err := os.CreateTemp("", version.ProgramName) - if err != nil { - return "", err - } - defer os.Remove(f.Name()) - - _, err = f.Write([]byte(rest)) - _ = f.Close() - if err != nil { - return "", err - } - cmdArgs = append(cmdArgs, f.Name()) - } - - cmd := exec.Command(args[0], cmdArgs...) - cmd.Env = env - cmd.Stdin = strings.NewReader(input) - cmd.Stderr = os.Stderr - cmd.Stdout = output - - if err := cmd.Run(); err != nil { - _, _ = os.Stderr.Write(output.Bytes()) - log.Errorf("failed to run tool [%s] cmd [%s]: %v", tool.Name, interpreter, err) - return "", err - } - - return output.String(), nil -} - func (e *Engine) Start(ctx Context, input string) (*Return, error) { tool := ctx.Tool if tool.IsCommand() { + if tool.IsHTTP() { + return e.runHTTP(ctx.Ctx, tool, input) + } else if tool.IsDaemon() { + return e.runDaemon(ctx.Ctx, tool, input) + } s, err := e.runCommand(ctx.Ctx, tool, input) if err != nil { return nil, err diff --git a/pkg/engine/http.go b/pkg/engine/http.go new file mode 100644 index 00000000..b36d7097 --- /dev/null +++ b/pkg/engine/http.go @@ -0,0 +1,44 @@ +package engine + +import ( + "context" + "fmt" + "io" + "net/http" + "strings" + + "github.com/gptscript-ai/gptscript/pkg/types" +) + +func (e *Engine) runHTTP(ctx context.Context, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { + url := strings.Split(tool.Instructions, "\n")[0][2:] + + req, err := http.NewRequestWithContext(ctx, url, http.MethodPost, strings.NewReader(input)) + if err != nil { + return + } + + req.Header.Set("X-GPTScript-Tool-Name", tool.Name) + req.Header.Set("Content-Type", "text/plain") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode > 299 { + _, _ = io.ReadAll(resp.Body) + return nil, fmt.Errorf("error in request to [%s] [%d]: %s", url, resp.StatusCode, resp.Status) + } + + content, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + s := string(content) + return &Return{ + Result: &s, + }, nil +} diff --git a/pkg/server/server.go b/pkg/server/server.go index 68dc9a5e..d770b65b 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -52,6 +52,14 @@ func New(opts ...Options) (*Server, error) { events: events, }, })...) + noCacheRunner, err := runner.New(append(runnerOpts, runner.Options{ + CacheOptions: runner.CacheOptions{ + Cache: new(bool), + }, + MonitorFactory: &SessionFactory{ + events: events, + }, + })...) if err != nil { return nil, err } @@ -60,6 +68,7 @@ func New(opts ...Options) (*Server, error) { melody: melody.New(), events: events, runner: r, + noCacheRunner: noCacheRunner, listenAddress: opt.ListenAddress, }, nil } @@ -74,8 +83,10 @@ type Event struct { } type Server struct { + ctx context.Context melody *melody.Melody runner *runner.Runner + noCacheRunner *runner.Runner events *broadcaster.Broadcaster[Event] listenAddress string } @@ -144,11 +155,16 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { return } + runner := s.runner + if req.URL.Query().Has("nocache") { + runner = s.noCacheRunner + } + id := fmt.Sprint(atomic.AddInt64(&execID, 1)) ctx := context.WithValue(req.Context(), execKey{}, id) if req.URL.Query().Has("async") { go func() { - _, _ = s.runner.Run(ctx, prg, os.Environ(), string(body)) + _, _ = runner.Run(s.ctx, prg, os.Environ(), string(body)) }() rw.Header().Set("Content-Type", "application/json") err := json.NewEncoder(rw).Encode(map[string]any{ @@ -158,7 +174,7 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { http.Error(rw, err.Error(), http.StatusInternalServerError) } } else { - out, err := s.runner.Run(ctx, prg, os.Environ(), string(body)) + out, err := runner.Run(ctx, prg, os.Environ(), string(body)) if err == nil { _, _ = rw.Write([]byte(out)) } else { @@ -168,6 +184,7 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { } func (s *Server) Start(ctx context.Context) error { + s.ctx = ctx s.melody.HandleConnect(s.Connect) go s.events.Start(ctx) log.Infof("Listening on http://%s", s.listenAddress) diff --git a/pkg/types/tool.go b/pkg/types/tool.go index 35beff9d..b65e5687 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -97,6 +97,15 @@ func (t Tool) IsCommand() bool { return strings.HasPrefix(t.Instructions, "#!") } +func (t Tool) IsDaemon() bool { + return strings.HasPrefix(t.Instructions, "#!sys.daemon") +} + +func (t Tool) IsHTTP() bool { + return strings.HasPrefix(t.Instructions, "#!http://") || + strings.HasPrefix(t.Instructions, "#!https://") +} + func FirstSet[T comparable](in ...T) (result T) { for _, i := range in { if i != result { From 853c4c78f2837cff11bc6957f45b86b6448e34c5 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 8 Feb 2024 09:28:08 -0700 Subject: [PATCH 044/774] Make http list call recurse --- pkg/server/server.go | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/pkg/server/server.go b/pkg/server/server.go index d770b65b..ec2f5af2 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -116,21 +116,29 @@ func (s *Server) list(rw http.ResponseWriter, req *http.Request) { return } - files, err := os.ReadDir(path) + var result []string + err := fs.WalkDir(os.DirFS(path), ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if strings.HasPrefix(d.Name(), ".") { + if d.IsDir() && d.Name() != "." { + return fs.SkipDir + } + return nil + } + + if !d.IsDir() && strings.HasSuffix(d.Name(), ".gpt") { + result = append(result, path) + } + + return nil + }) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } - var result []string - for _, file := range files { - if file.IsDir() && !strings.HasPrefix(file.Name(), ".") { - result = append(result, filepath.Join(path, file.Name())+"/") - } else if strings.HasSuffix(file.Name(), ".gpt") { - result = append(result, filepath.Join(path, file.Name())) - } - } - _ = enc.Encode(result) } From 912d1b493ba89abec097bb34bfa1a210cfae9817 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 8 Feb 2024 09:51:57 -0700 Subject: [PATCH 045/774] Don't set default prompt param anymore --- pkg/builtin/builtin.go | 8 ++++---- pkg/builtin/defaults.go | 22 ++++++++++++++++++++++ pkg/engine/engine.go | 19 ++++++++++++++++++- pkg/loader/defaults.go | 37 ------------------------------------- pkg/loader/loader.go | 5 +++-- 5 files changed, 47 insertions(+), 44 deletions(-) create mode 100644 pkg/builtin/defaults.go delete mode 100644 pkg/loader/defaults.go diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 6b5d4797..7b132605 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -17,7 +17,7 @@ import ( "github.com/jaytaylor/html2text" ) -var Tools = map[string]types.Tool{ +var tools = map[string]types.Tool{ "sys.read": { Description: "Reads the contents of a file", Arguments: types.ObjectSchema( @@ -94,7 +94,7 @@ func SysProgram() *types.Program { func ListTools() (result []types.Tool) { var keys []string - for k := range Tools { + for k := range tools { keys = append(keys, k) } @@ -109,7 +109,7 @@ func ListTools() (result []types.Tool) { func Builtin(name string) (types.Tool, bool) { name, dontFail := strings.CutSuffix(name, "?") - t, ok := Tools[name] + t, ok := tools[name] t.Name = name t.ID = name t.Instructions = "#!" + name @@ -123,7 +123,7 @@ func Builtin(name string) (types.Tool, bool) { return s, err } } - return t, ok + return SetDefaults(t), ok } func SysFind(ctx context.Context, env []string, input string) (string, error) { diff --git a/pkg/builtin/defaults.go b/pkg/builtin/defaults.go new file mode 100644 index 00000000..5121bdd0 --- /dev/null +++ b/pkg/builtin/defaults.go @@ -0,0 +1,22 @@ +package builtin + +import ( + "github.com/gptscript-ai/gptscript/pkg/openai" + "github.com/gptscript-ai/gptscript/pkg/types" +) + +var ( + DefaultModel = openai.DefaultModel + DefaultVisionModel = openai.DefaultVisionModel +) + +func SetDefaults(tool types.Tool) types.Tool { + if tool.ModelName == "" { + if tool.Vision { + tool.ModelName = DefaultVisionModel + } else { + tool.ModelName = DefaultModel + } + } + return tool +} diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index e3a76ef9..710a5105 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -23,6 +23,19 @@ You do not need to explain the steps taken, only provide the result to the given You are referred to as a tool. ` +var DefaultToolSchema = types.JSONSchema{ + Property: types.Property{ + Type: "object", + }, + Properties: map[string]types.Property{ + openai.DefaultPromptParameter: { + Description: "Prompt to send to the tool or assistant. This may be instructions or question.", + Type: "string", + }, + }, + Required: []string{openai.DefaultPromptParameter}, +} + var completionID int64 func init() { @@ -185,12 +198,16 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { if err != nil { return nil, err } + args := subTool.Arguments + if args == nil && !subTool.IsCommand() { + args = &DefaultToolSchema + } completion.Tools = append(completion.Tools, types.CompletionTool{ Type: types.CompletionToolTypeFunction, Function: types.CompletionFunctionDefinition{ Name: subToolName, Description: subTool.Description, - Parameters: subTool.Arguments, + Parameters: args, }, }) } diff --git a/pkg/loader/defaults.go b/pkg/loader/defaults.go deleted file mode 100644 index 7d41d0ad..00000000 --- a/pkg/loader/defaults.go +++ /dev/null @@ -1,37 +0,0 @@ -package loader - -import ( - "github.com/gptscript-ai/gptscript/pkg/openai" - "github.com/gptscript-ai/gptscript/pkg/types" -) - -var ( - DefaultModel = openai.DefaultModel - DefaultVisionModel = openai.DefaultVisionModel - DefaultToolSchema = types.JSONSchema{ - Property: types.Property{ - Type: "object", - }, - Properties: map[string]types.Property{ - openai.DefaultPromptParameter: { - Description: "Prompt to send to the tool or assistant. This may be instructions or question.", - Type: "string", - }, - }, - Required: []string{openai.DefaultPromptParameter}, - } -) - -func SetDefaults(tool types.Tool) types.Tool { - if !tool.IsCommand() && tool.Arguments == nil { - tool.Arguments = &DefaultToolSchema - } - if tool.ModelName == "" { - if tool.Vision { - tool.ModelName = DefaultVisionModel - } else { - tool.ModelName = DefaultModel - } - } - return tool -} diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 23155b84..6b574154 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -154,7 +154,8 @@ func loadProgram(data []byte, into *types.Program) (types.Tool, error) { for tk, tv := range v.ToolMapping { v.ToolMapping[tk] = tv + id } - into.ToolSet[k+id] = v + v.ID = k + id + into.ToolSet[v.ID] = v } return into.ToolSet[ext.EntryToolID+id], nil @@ -314,7 +315,7 @@ func link(ctx context.Context, prg *types.Program, base *Source, tool types.Tool tool.Tools[i] = newToolName } - tool = SetDefaults(tool) + tool = builtin.SetDefaults(tool) prg.ToolSet[tool.ID] = tool return tool, nil From 01273d58cfdbe90661b203906208ee68fe432033 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 8 Feb 2024 12:20:08 -0700 Subject: [PATCH 046/774] Fix missing context --- pkg/server/server.go | 18 ++++++++++++++++-- static/fs.go | 9 +++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 static/fs.go diff --git a/pkg/server/server.go b/pkg/server/server.go index ec2f5af2..6b8cacf2 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -19,6 +19,7 @@ import ( "github.com/gptscript-ai/gptscript/pkg/loader" "github.com/gptscript-ai/gptscript/pkg/runner" "github.com/gptscript-ai/gptscript/pkg/types" + "github.com/gptscript-ai/gptscript/static" "github.com/olahol/melody" "github.com/rs/cors" ) @@ -169,10 +170,10 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { } id := fmt.Sprint(atomic.AddInt64(&execID, 1)) - ctx := context.WithValue(req.Context(), execKey{}, id) if req.URL.Query().Has("async") { + ctx := context.WithValue(s.ctx, execKey{}, id) go func() { - _, _ = runner.Run(s.ctx, prg, os.Environ(), string(body)) + _, _ = runner.Run(ctx, prg, os.Environ(), string(body)) }() rw.Header().Set("Content-Type", "application/json") err := json.NewEncoder(rw).Encode(map[string]any{ @@ -182,6 +183,7 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { http.Error(rw, err.Error(), http.StatusInternalServerError) } } else { + ctx := context.WithValue(req.Context(), execKey{}, id) out, err := runner.Run(ctx, prg, os.Environ(), string(body)) if err == nil { _, _ = rw.Write([]byte(out)) @@ -228,6 +230,18 @@ func (s *Server) Connect(session *melody.Session) { } func (s *Server) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + if strings.HasPrefix(req.URL.Path, "/ui") { + path := req.URL.Path + if path == "/ui" || path == "/ui/" { + path = "/ui/index.html" + } + if _, err := fs.Stat(static.UI, path[1:]); errors.Is(err, fs.ErrNotExist) { + path = "/ui/index.html" + } + http.ServeFileFS(rw, req, static.UI, path) + return + } + switch req.Method { case http.MethodPost: s.run(rw, req) diff --git a/static/fs.go b/static/fs.go new file mode 100644 index 00000000..dbd49129 --- /dev/null +++ b/static/fs.go @@ -0,0 +1,9 @@ +package static + +import ( + "embed" + _ "embed" +) + +// /go:embed ui/** ui/**/_* +var UI embed.FS From ed39111acdd44ce3ad634c258a9e8295d015304b Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 8 Feb 2024 22:15:47 -0700 Subject: [PATCH 047/774] Add support for serving UI --- pkg/engine/daemon.go | 58 +++++++++++++++++++++++++----------- pkg/engine/engine.go | 6 ---- pkg/engine/http.go | 4 +-- pkg/types/tool.go | 9 ++++-- static/fs.go | 2 +- static/ui/_nuxt/_placeholder | 0 static/ui/placeholder | 0 7 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 static/ui/_nuxt/_placeholder create mode 100644 static/ui/placeholder diff --git a/pkg/engine/daemon.go b/pkg/engine/daemon.go index 6055cf26..6b9162fb 100644 --- a/pkg/engine/daemon.go +++ b/pkg/engine/daemon.go @@ -7,31 +7,45 @@ import ( "net/http" "os" "strings" + "sync" "time" "github.com/gptscript-ai/gptscript/pkg/types" ) +var ( + daemonPorts map[string]int64 + daemonLock sync.Mutex + + startPort, endPort int64 + nextPort int64 +) + func (e *Engine) getNextPort() int64 { - count := e.endPort - e.startPort - e.nextPort++ - e.nextPort = e.nextPort % count - return e.startPort + e.nextPort + if startPort == 0 { + startPort = 10240 + endPort = 11240 + } + count := endPort - startPort + nextPort++ + nextPort = nextPort % count + return startPort + nextPort } func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, error) { - e.daemonLock.Lock() - defer e.daemonLock.Unlock() + daemonLock.Lock() + defer daemonLock.Unlock() - port, ok := e.daemonPorts[tool.ID] + port, ok := daemonPorts[tool.ID] url := fmt.Sprintf("http://127.0.0.1:%d", port) if ok { return url, nil } port = e.getNextPort() + url = fmt.Sprintf("http://127.0.0.1:%d", port) - instructions := strings.TrimPrefix(tool.Instructions, "#!daemon ") + instructions := types.CommandPrefix + strings.TrimPrefix(tool.Instructions, types.DaemonPrefix) cmd, close, err := e.newCommand(ctx, []string{ fmt.Sprintf("PORT=%d", port), }, @@ -44,22 +58,31 @@ func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, erro cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout - log.Infof("launching [%s] port [%d] %v", tool.Name, port, cmd.Args) + log.Infof("launched [%s] port [%d] %v", tool.Name, port, cmd.Args) if err := cmd.Start(); err != nil { close() return url, err } + if daemonPorts == nil { + daemonPorts = map[string]int64{} + } + + killedCtx, cancel := context.WithCancelCause(ctx) + defer cancel(nil) + go func() { - if err := cmd.Wait(); err != nil { + err := cmd.Wait() + if err != nil { log.Errorf("daemon exited tool [%s] %v: %v", tool.Name, cmd.Args, err) } + cancel(err) close() - e.daemonLock.Lock() - defer e.daemonLock.Unlock() + daemonLock.Lock() + defer daemonLock.Unlock() - delete(e.daemonPorts, tool.ID) + delete(daemonPorts, tool.ID) }() context.AfterFunc(ctx, func() { @@ -78,8 +101,8 @@ func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, erro return url, nil } select { - case <-ctx.Done(): - return url, ctx.Err() + case <-killedCtx.Done(): + return url, fmt.Errorf("daemon failed to start: %w", context.Cause(killedCtx)) case <-time.After(time.Second): } } @@ -93,7 +116,8 @@ func (e *Engine) runDaemon(ctx context.Context, tool types.Tool, input string) ( return nil, err } - tool.Instructions = strings.Join(append([]string{url}, - strings.Split(tool.Instructions, "\n")[1:]...), "\n") + tool.Instructions = strings.Join(append([]string{ + types.CommandPrefix + url, + }, strings.Split(tool.Instructions, "\n")[1:]...), "\n") return e.runHTTP(ctx, tool, input) } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 710a5105..4d10e299 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -56,12 +56,6 @@ type Engine struct { Client *openai.Client Env []string Progress chan<- openai.Status - - daemonPorts map[string]int64 - daemonLock sync.Mutex - - startPort, endPort int64 - nextPort int64 } type State struct { diff --git a/pkg/engine/http.go b/pkg/engine/http.go index b36d7097..08cab5e1 100644 --- a/pkg/engine/http.go +++ b/pkg/engine/http.go @@ -13,9 +13,9 @@ import ( func (e *Engine) runHTTP(ctx context.Context, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { url := strings.Split(tool.Instructions, "\n")[0][2:] - req, err := http.NewRequestWithContext(ctx, url, http.MethodPost, strings.NewReader(input)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, strings.NewReader(input)) if err != nil { - return + return nil, err } req.Header.Set("X-GPTScript-Tool-Name", tool.Name) diff --git a/pkg/types/tool.go b/pkg/types/tool.go index b65e5687..d10e8013 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -7,6 +7,11 @@ import ( "strings" ) +const ( + DaemonPrefix = "#!sys.daemon " + CommandPrefix = "#!" +) + type ToolSet map[string]Tool type Program struct { @@ -94,11 +99,11 @@ func (t ToolSource) String() string { } func (t Tool) IsCommand() bool { - return strings.HasPrefix(t.Instructions, "#!") + return strings.HasPrefix(t.Instructions, CommandPrefix) } func (t Tool) IsDaemon() bool { - return strings.HasPrefix(t.Instructions, "#!sys.daemon") + return strings.HasPrefix(t.Instructions, DaemonPrefix) } func (t Tool) IsHTTP() bool { diff --git a/static/fs.go b/static/fs.go index dbd49129..88e5f4ec 100644 --- a/static/fs.go +++ b/static/fs.go @@ -5,5 +5,5 @@ import ( _ "embed" ) -// /go:embed ui/** ui/**/_* +//go:embed * ui/_nuxt/* var UI embed.FS diff --git a/static/ui/_nuxt/_placeholder b/static/ui/_nuxt/_placeholder new file mode 100644 index 00000000..e69de29b diff --git a/static/ui/placeholder b/static/ui/placeholder new file mode 100644 index 00000000..e69de29b From 4c8085ac58ef8394d86168790842da225a9a959e Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 8 Feb 2024 22:55:27 -0700 Subject: [PATCH 048/774] Add ?tool param --- pkg/loader/loader.go | 24 +++++++++++++++++++++--- pkg/server/server.go | 4 ++-- pkg/types/tool.go | 6 ++++-- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 6b574154..b21dbc03 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -20,6 +20,7 @@ import ( "github.com/gptscript-ai/gptscript/pkg/assemble" "github.com/gptscript-ai/gptscript/pkg/builtin" + "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/parser" "github.com/gptscript-ai/gptscript/pkg/types" ) @@ -137,7 +138,7 @@ func loadURL(ctx context.Context, base *Source, name string) (*Source, bool, err }, true, nil } -func loadProgram(data []byte, into *types.Program) (types.Tool, error) { +func loadProgram(data []byte, into *types.Program, targetToolName string) (types.Tool, error) { var ( ext types.Program id string @@ -158,7 +159,19 @@ func loadProgram(data []byte, into *types.Program) (types.Tool, error) { into.ToolSet[v.ID] = v } - return into.ToolSet[ext.EntryToolID+id], nil + tool := into.ToolSet[ext.EntryToolID+id] + if targetToolName == "" { + return tool, nil + } + + tool, ok := into.ToolSet[tool.LocalTools[targetToolName]] + if !ok { + return tool, &engine.ErrToolNotFound{ + ToolName: targetToolName, + } + } + + return tool, nil } func ReadTool(ctx context.Context, prg *types.Program, base *Source, targetToolName string) (types.Tool, error) { @@ -169,7 +182,7 @@ func ReadTool(ctx context.Context, prg *types.Program, base *Source, targetToolN _ = base.Content.Close() if bytes.HasPrefix(data, assemble.Header) { - return loadProgram(data, prg) + return loadProgram(data, prg, targetToolName) } tools, err := parser.Parse(bytes.NewReader(data)) @@ -263,6 +276,7 @@ func link(ctx context.Context, prg *types.Program, base *Source, tool types.Tool } tool.ToolMapping = map[string]string{} + tool.LocalTools = map[string]string{} toolNames := map[string]struct{}{} // Add now to break circular loops, but later we will update this tool and copy the new @@ -315,6 +329,10 @@ func link(ctx context.Context, prg *types.Program, base *Source, tool types.Tool tool.Tools[i] = newToolName } + for _, localTool := range localTools { + tool.LocalTools[localTool.Name] = localTool.ID + } + tool = builtin.SetDefaults(tool) prg.ToolSet[tool.ID] = tool diff --git a/pkg/server/server.go b/pkg/server/server.go index 6b8cacf2..b28d6e23 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -108,7 +108,7 @@ func (s *Server) list(rw http.ResponseWriter, req *http.Request) { _ = enc.Encode(builtin.SysProgram()) return } else if strings.HasSuffix(path, ".gpt") { - prg, err := loader.Program(req.Context(), path, "") + prg, err := loader.Program(req.Context(), path, req.URL.Query().Get("tool")) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return @@ -149,7 +149,7 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { path += ".gpt" } - prg, err := loader.Program(req.Context(), path, "") + prg, err := loader.Program(req.Context(), path, req.URL.Query().Get("tool")) if errors.Is(err, fs.ErrNotExist) { http.NotFound(rw, req) return diff --git a/pkg/types/tool.go b/pkg/types/tool.go index d10e8013..78b9907d 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -15,8 +15,9 @@ const ( type ToolSet map[string]Tool type Program struct { - EntryToolID string `json:"entryToolId,omitempty"` - ToolSet ToolSet `json:"toolSet,omitempty"` + EntryToolID string `json:"entryToolId,omitempty"` + ToolSet ToolSet `json:"toolSet,omitempty"` + Exports map[string]string `json:"exports,omitempty"` } type BuiltinFunc func(ctx context.Context, env []string, input string) (string, error) @@ -29,6 +30,7 @@ type Tool struct { Instructions string `json:"instructions,omitempty"` Tools []string `json:"tools,omitempty"` ToolMapping map[string]string `json:"toolMapping,omitempty"` + LocalTools map[string]string `json:"localTools,omitempty"` BuiltinFunc BuiltinFunc `json:"-"` Vision bool `json:"vision,omitempty"` From 16575f61de6c7fbf1bf8cd6494876b4940df1c5e Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:40:05 -0500 Subject: [PATCH 049/774] chore: add basic build, test, and release actions Add basic github actions to build, test, and generate release artifacts for `gptscript`. Includes goreleaser configuration to publish homebrew Formulas to our [tap repository](https://github.com/gptscript-ai/homebrew-tap/). Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- .github/workflows/main.yaml | 36 ++++++++++++++++++ .github/workflows/release.yaml | 33 +++++++++++++++++ .github/workflows/test.yaml | 26 +++++++++++++ .goreleaser.yml | 67 ++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 .github/workflows/main.yaml create mode 100644 .github/workflows/release.yaml create mode 100644 .github/workflows/test.yaml create mode 100644 .goreleaser.yml diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 00000000..bf95f9d4 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,36 @@ +name: main + +concurrency: + group: main + cancel-in-progress: true + +on: + push: + branches: + - main + +permissions: + contents: write + +jobs: + release-snapshot: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v4 + with: + cache: false + go-version: "1.21" + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v4 + with: + distribution: goreleaser + version: v1.23.0 + args: release --clean --snapshot + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_PROJECT_TOKEN: ${{ secrets.GH_PROJECT_TOKEN }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000..1ad22624 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,33 @@ +name: release + +on: + push: + tags: + - "v*" + +permissions: + contents: write + +jobs: + release-tag: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v4 + with: + cache: false + go-version: "1.21" + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v4 + with: + distribution: goreleaser + version: v1.23.0 + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_PROJECT_TOKEN: ${{ secrets.GH_PROJECT_TOKEN }} + GORELEASER_CURRENT_TAG: ${{ github.ref_name }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 00000000..310c4f2f --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,26 @@ +name: test +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + test: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 1 + - uses: actions/setup-go@v4 + with: + cache: false + go-version: "1.21" + - name: Validate + run: make validate + - name: Build + run: make build + - name: Run Tests + run: make test diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 00000000..c1bc4d2f --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,67 @@ +dist: releases +snapshot: + name_template: '{{ trimprefix .Summary "v" }}' + +builds: + - id: default + binary: gptscript + env: + - CGO_ENABLED=0 + goarch: + - amd64 + - arm64 + ignore: + - goos: windows + goarch: arm64 + flags: + - -trimpath + ldflags: + - -s + - -w + - -X "github.com/gptscript-ai/gptscript/pkg/version.Tag=v{{ .Version }}" + +universal_binaries: + - id: mac + ids: + - default + replace: true + +archives: + - id: default + builds: + - default + - mac + name_template: '{{.Project}}-v{{ .Version }}-{{ if eq .Os "darwin" }}macOS-universal{{ else }}{{ .Os }}-{{ .Arch }}{{ .Arm }}{{ end }}' + format_overrides: + - goos: windows + format: zip + +checksum: + name_template: "checksums.txt" + +changelog: + use: github + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" + - "^Merge pull request" + +release: + github: + owner: gptscript-ai + name: gptscript + prerelease: auto + +brews: + - description: "GPTScript CLI" + install: | + bin.install "gptscript" + homepage: "https://github.com/gptscript-ai/gptscript" + skip_upload: false + folder: "Formula" + repository: + owner: gptscript-ai + name: homebrew-tap + token: "{{ .Env.GH_PROJECT_TOKEN }}" From dffe7542912f636594297f4daabef30e475bc2d0 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 9 Feb 2024 09:17:47 -0700 Subject: [PATCH 050/774] Make some APIs private --- pkg/loader/loader.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index b21dbc03..c3eebad6 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -30,7 +30,7 @@ const ( githubRawURL = "https://raw.githubusercontent.com/" ) -type Source struct { +type source struct { Content io.ReadCloser Remote bool Path string @@ -38,7 +38,7 @@ type Source struct { File string } -func (s *Source) String() string { +func (s *source) String() string { if s.Path == "" && s.Name == "" { return "" } @@ -55,7 +55,7 @@ func openFile(path string) (io.ReadCloser, bool, error) { return f, true, nil } -func loadLocal(base *Source, name string) (*Source, bool, error) { +func loadLocal(base *source, name string) (*source, bool, error) { path := filepath.Join(base.Path, name) content, ok, err := openFile(path) @@ -66,7 +66,7 @@ func loadLocal(base *Source, name string) (*Source, bool, error) { } log.Debugf("opened %s", path) - return &Source{ + return &source{ Content: content, Remote: false, Path: filepath.Dir(path), @@ -95,7 +95,7 @@ func githubURL(urlName string) (string, bool) { return url, true } -func loadURL(ctx context.Context, base *Source, name string) (*Source, bool, error) { +func loadURL(ctx context.Context, base *source, name string) (*source, bool, error) { url := name if base.Path != "" { url = base.Path + "/" + name @@ -129,7 +129,7 @@ func loadURL(ctx context.Context, base *Source, name string) (*Source, bool, err pathURL := *parsed pathURL.Path = filepath.Dir(parsed.Path) - return &Source{ + return &source{ Content: resp.Body, Remote: true, Path: pathURL.String(), @@ -174,7 +174,7 @@ func loadProgram(data []byte, into *types.Program, targetToolName string) (types return tool, nil } -func ReadTool(ctx context.Context, prg *types.Program, base *Source, targetToolName string) (types.Tool, error) { +func readTool(ctx context.Context, prg *types.Program, base *source, targetToolName string) (types.Tool, error) { data, err := io.ReadAll(base.Content) if err != nil { return types.Tool{}, err @@ -270,7 +270,7 @@ func pickToolName(toolName string, existing map[string]struct{}) string { } } -func link(ctx context.Context, prg *types.Program, base *Source, tool types.Tool, localTools types.ToolSet) (types.Tool, error) { +func link(ctx context.Context, prg *types.Program, base *source, tool types.Tool, localTools types.ToolSet) (types.Tool, error) { if existing, ok := prg.ToolSet[tool.ID]; ok { return existing, nil } @@ -319,7 +319,7 @@ func link(ctx context.Context, prg *types.Program, base *Source, tool types.Tool subTool = strings.TrimSpace(subTool) } - resolvedTool, err := Resolve(ctx, prg, base, toolName, subTool) + resolvedTool, err := resolve(ctx, prg, base, toolName, subTool) if err != nil { return types.Tool{}, fmt.Errorf("failed resolving %s at %s: %w", targetToolName, base, err) } @@ -343,7 +343,7 @@ func Program(ctx context.Context, name, subToolName string) (types.Program, erro prg := types.Program{ ToolSet: types.ToolSet{}, } - tool, err := Resolve(ctx, &prg, &Source{}, name, subToolName) + tool, err := resolve(ctx, &prg, &source{}, name, subToolName) if err != nil { return types.Program{}, err } @@ -351,7 +351,7 @@ func Program(ctx context.Context, name, subToolName string) (types.Program, erro return prg, nil } -func Resolve(ctx context.Context, prg *types.Program, base *Source, name, subTool string) (types.Tool, error) { +func resolve(ctx context.Context, prg *types.Program, base *source, name, subTool string) (types.Tool, error) { if subTool == "" { t, ok := builtin.Builtin(name) if ok { @@ -360,15 +360,15 @@ func Resolve(ctx context.Context, prg *types.Program, base *Source, name, subToo } } - s, err := Input(ctx, base, name) + s, err := input(ctx, base, name) if err != nil { return types.Tool{}, err } - return ReadTool(ctx, prg, s, subTool) + return readTool(ctx, prg, s, subTool) } -func Input(ctx context.Context, base *Source, name string) (*Source, error) { +func input(ctx context.Context, base *source, name string) (*source, error) { if !base.Remote { s, ok, err := loadLocal(base, name) if err != nil || ok { From 1a6057719dd70084a3ce9bf9781bb5246698d1fc Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 9 Feb 2024 09:31:12 -0700 Subject: [PATCH 051/774] Remove renovate --- renovate.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 renovate.json diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 5db72dd6..00000000 --- a/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ] -} From afdf236c808fcb0fee10f290ab5380b67d52c359 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Fri, 9 Feb 2024 05:13:32 -0500 Subject: [PATCH 052/774] fix: goreleaser templating and linting - Fix broken goreleaser templating - Fix validation and improve linting - Correct pre-existing linting errors Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- .golangci.yml | 22 ++++++++++++++++++++++ .goreleaser.yml | 2 +- Makefile | 22 ++++++++++++++++++++-- pkg/engine/cmd.go | 4 ++-- pkg/engine/daemon.go | 4 +++- pkg/server/server.go | 4 ++++ pkg/test/examples_test.go | 1 + 7 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 .golangci.yml diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..889ceba6 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,22 @@ +run: + timeout: 5m + +output: + format: github-actions + +linters: + disable-all: true + enable: + - errcheck + - gofmt + - gosimple + - govet + - ineffassign + - staticcheck + - typecheck + - thelper + - unused + - goimports + - whitespace + fast: false + max-same-issues: 50 diff --git a/.goreleaser.yml b/.goreleaser.yml index c1bc4d2f..99b892f5 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -31,7 +31,7 @@ archives: builds: - default - mac - name_template: '{{.Project}}-v{{ .Version }}-{{ if eq .Os "darwin" }}macOS-universal{{ else }}{{ .Os }}-{{ .Arch }}{{ .Arm }}{{ end }}' + name_template: 'gptscript-v{{ .Version }}-{{ if eq .Os "darwin" }}macOS-universal{{ else }}{{ .Os }}-{{ .Arch }}{{ .Arm }}{{ end }}' format_overrides: - goos: windows format: zip diff --git a/Makefile b/Makefile index 42f78b01..c05db3b2 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,30 @@ build: CGO_ENABLED=0 go build -o bin/gptscript -tags "${GO_TAGS}" -ldflags "-s -w" . +tidy: + go mod tidy + test: go test -v ./... -validate: - go vet ./... +GOLANGCI_LINT_VERSION ?= v1.56.1 +lint: + if ! command -v golangci-lint &> /dev/null; then \ + echo "Could not find golangci-lint, installing version $(GOLANGCI_LINT_VERSION)."; \ + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin $(GOLANGCI_LINT_VERSION); \ + fi + golangci-lint run + +validate: tidy lint + if [ -n "$$(git status --porcelain)" ]; then \ + git status --porcelain; \ + echo "Encountered dirty repo!"; \ + git diff; \ + exit 1 \ + ;fi + ci: build ./bin/gptscript ./scripts/ci.gpt + diff --git a/pkg/engine/cmd.go b/pkg/engine/cmd.go index ca4de79b..ceeda580 100644 --- a/pkg/engine/cmd.go +++ b/pkg/engine/cmd.go @@ -77,8 +77,8 @@ func (e *Engine) newCommand(ctx context.Context, extraEnv []string, instructions envMap := map[string]string{} for _, env := range env { - key, value, ok := strings.Cut(env, "=") - key, ok = strings.CutPrefix(key, "GPTSCRIPT_VAR_") + key, value, _ := strings.Cut(env, "=") + key, ok := strings.CutPrefix(key, "GPTSCRIPT_VAR_") if !ok { continue } diff --git a/pkg/engine/daemon.go b/pkg/engine/daemon.go index 6b9162fb..884c02c6 100644 --- a/pkg/engine/daemon.go +++ b/pkg/engine/daemon.go @@ -86,7 +86,9 @@ func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, erro }() context.AfterFunc(ctx, func() { - cmd.Process.Kill() + if err := cmd.Process.Kill(); err != nil { + log.Errorf("daemon failed to kill tool [%s] process: %v", tool.Name, err) + } }) for range 20 { diff --git a/pkg/server/server.go b/pkg/server/server.go index b28d6e23..ad56e6b3 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -53,6 +53,10 @@ func New(opts ...Options) (*Server, error) { events: events, }, })...) + if err != nil { + return nil, err + } + noCacheRunner, err := runner.New(append(runnerOpts, runner.Options{ CacheOptions: runner.CacheOptions{ Cache: new(bool), diff --git a/pkg/test/examples_test.go b/pkg/test/examples_test.go index 747144b4..2a02507a 100644 --- a/pkg/test/examples_test.go +++ b/pkg/test/examples_test.go @@ -55,6 +55,7 @@ func TestEcho(t *testing.T) { } func RequireOpenAPIKey(t *testing.T) { + t.Helper() if os.Getenv("OPENAI_API_KEY") == "" { t.Skip() } From 51d17ef40f2a2bc99ff5cb3572c02bdc2b332862 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 9 Feb 2024 17:32:52 -0700 Subject: [PATCH 053/774] Fix daemon support and don't default to 1024 tokens --- pkg/cli/gptscript.go | 5 +++- pkg/engine/daemon.go | 62 ++++++++++++++++++++++++++++++++++++++------ pkg/engine/engine.go | 4 +-- pkg/engine/http.go | 56 +++++++++++++++++++++++++++++++++++---- pkg/loader/loader.go | 9 ++++--- pkg/openai/client.go | 5 ---- pkg/parser/parser.go | 22 +++++++++------- pkg/types/tool.go | 2 +- 8 files changed, 131 insertions(+), 34 deletions(-) diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 2712f373..4c09d0fa 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -10,6 +10,7 @@ import ( "github.com/acorn-io/cmd" "github.com/gptscript-ai/gptscript/pkg/assemble" "github.com/gptscript-ai/gptscript/pkg/builtin" + "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/input" "github.com/gptscript-ai/gptscript/pkg/loader" "github.com/gptscript-ai/gptscript/pkg/monitor" @@ -98,6 +99,8 @@ func (r *GPTScript) Pre(cmd *cobra.Command, args []string) error { } func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { + defer engine.CloseDaemons() + if r.ListModels { return r.listModels(cmd.Context()) } @@ -119,7 +122,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { } if len(args) == 0 { - return fmt.Errorf("scripts argument required") + return cmd.Help() } prg, err := loader.Program(cmd.Context(), args[0], r.SubTool) diff --git a/pkg/engine/daemon.go b/pkg/engine/daemon.go index 884c02c6..a232c1cf 100644 --- a/pkg/engine/daemon.go +++ b/pkg/engine/daemon.go @@ -19,8 +19,23 @@ var ( startPort, endPort int64 nextPort int64 + daemonCtx context.Context + daemonClose func() + daemonWG sync.WaitGroup ) +func CloseDaemons() { + daemonLock.Lock() + if daemonCtx == nil { + daemonLock.Unlock() + return + } + daemonLock.Unlock() + + daemonClose() + daemonWG.Wait() +} + func (e *Engine) getNextPort() int64 { if startPort == 0 { startPort = 10240 @@ -32,24 +47,52 @@ func (e *Engine) getNextPort() int64 { return startPort + nextPort } +func getPath(instructions string) (string, string) { + instructions = strings.TrimSpace(instructions) + line := strings.TrimSpace(instructions) + + if !strings.HasPrefix(line, "(") { + return instructions, "" + } + + line, rest, ok := strings.Cut(line[1:], ")") + if !ok { + return instructions, "" + } + + path, value, ok := strings.Cut(strings.TrimSpace(line), "=") + if !ok || strings.TrimSpace(path) != "path" { + return instructions, "" + } + + return strings.TrimSpace(rest), strings.TrimSpace(value) +} + func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, error) { daemonLock.Lock() defer daemonLock.Unlock() + instructions := strings.TrimPrefix(tool.Instructions, types.DaemonPrefix) + instructions, path := getPath(instructions) + port, ok := daemonPorts[tool.ID] - url := fmt.Sprintf("http://127.0.0.1:%d", port) + url := fmt.Sprintf("http://127.0.0.1:%d%s", port, path) if ok { return url, nil } + if daemonCtx == nil { + daemonCtx, daemonClose = context.WithCancel(context.Background()) + } + + ctx = daemonCtx port = e.getNextPort() - url = fmt.Sprintf("http://127.0.0.1:%d", port) + url = fmt.Sprintf("http://127.0.0.1:%d%s", port, path) - instructions := types.CommandPrefix + strings.TrimPrefix(tool.Instructions, types.DaemonPrefix) cmd, close, err := e.newCommand(ctx, []string{ fmt.Sprintf("PORT=%d", port), }, - instructions, + types.CommandPrefix+instructions, "{}", ) if err != nil { @@ -58,7 +101,7 @@ func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, erro cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout - log.Infof("launched [%s] port [%d] %v", tool.Name, port, cmd.Args) + log.Infof("launched [%s][%s] port [%d] %v", tool.Name, tool.ID, port, cmd.Args) if err := cmd.Start(); err != nil { close() return url, err @@ -67,6 +110,7 @@ func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, erro if daemonPorts == nil { daemonPorts = map[string]int64{} } + daemonPorts[tool.ID] = port killedCtx, cancel := context.WithCancelCause(ctx) defer cancel(nil) @@ -85,13 +129,15 @@ func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, erro delete(daemonPorts, tool.ID) }() + daemonWG.Add(1) context.AfterFunc(ctx, func() { if err := cmd.Process.Kill(); err != nil { log.Errorf("daemon failed to kill tool [%s] process: %v", tool.Name, err) } + daemonWG.Done() }) - for range 20 { + for i := 0; i < 20; i++ { resp, err := http.Get(url) if err == nil && resp.StatusCode == http.StatusOK { defer func() { @@ -112,7 +158,7 @@ func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, erro return url, fmt.Errorf("timeout waiting for 200 response from GET %s", url) } -func (e *Engine) runDaemon(ctx context.Context, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { +func (e *Engine) runDaemon(ctx context.Context, prg *types.Program, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { url, err := e.startDaemon(ctx, tool) if err != nil { return nil, err @@ -121,5 +167,5 @@ func (e *Engine) runDaemon(ctx context.Context, tool types.Tool, input string) ( tool.Instructions = strings.Join(append([]string{ types.CommandPrefix + url, }, strings.Split(tool.Instructions, "\n")[1:]...), "\n") - return e.runHTTP(ctx, tool, input) + return e.runHTTP(ctx, prg, tool, input) } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 4d10e299..5077cfa2 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -158,9 +158,9 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { if tool.IsCommand() { if tool.IsHTTP() { - return e.runHTTP(ctx.Ctx, tool, input) + return e.runHTTP(ctx.Ctx, ctx.Program, tool, input) } else if tool.IsDaemon() { - return e.runDaemon(ctx.Ctx, tool, input) + return e.runDaemon(ctx.Ctx, ctx.Program, tool, input) } s, err := e.runCommand(ctx.Ctx, tool, input) if err != nil { diff --git a/pkg/engine/http.go b/pkg/engine/http.go index 08cab5e1..a1221b3a 100644 --- a/pkg/engine/http.go +++ b/pkg/engine/http.go @@ -2,24 +2,60 @@ package engine import ( "context" + "encoding/json" "fmt" "io" "net/http" + "net/url" "strings" "github.com/gptscript-ai/gptscript/pkg/types" ) -func (e *Engine) runHTTP(ctx context.Context, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { - url := strings.Split(tool.Instructions, "\n")[0][2:] +const DaemonURLSuffix = ".daemon.gpt.local" - req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, strings.NewReader(input)) +func (e *Engine) runHTTP(ctx context.Context, prg *types.Program, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { + toolURL := strings.Split(tool.Instructions, "\n")[0][2:] + + parsed, err := url.Parse(toolURL) + if err != nil { + return nil, err + } + + if strings.HasSuffix(parsed.Hostname(), DaemonURLSuffix) { + referencedToolName := strings.TrimSuffix(parsed.Hostname(), DaemonURLSuffix) + referencedToolID, ok := tool.ToolMapping[referencedToolName] + if !ok { + return nil, fmt.Errorf("invalid reference [%s] to tool [%s] from [%s], missing \"tools: %s\" parameter", toolURL, referencedToolName, tool.Source, referencedToolName) + } + referencedTool, ok := prg.ToolSet[referencedToolID] + if !ok { + return nil, fmt.Errorf("failed to find tool [%s] for [%s]", referencedToolName, parsed.Hostname()) + } + toolURL, err = e.startDaemon(ctx, referencedTool) + if err != nil { + return nil, err + } + toolURLParsed, err := url.Parse(toolURL) + if err != nil { + return nil, err + } + parsed.Host = toolURLParsed.Host + toolURL = parsed.String() + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, toolURL, strings.NewReader(input)) if err != nil { return nil, err } req.Header.Set("X-GPTScript-Tool-Name", tool.Name) - req.Header.Set("Content-Type", "text/plain") + + if err := json.Unmarshal([]byte(input), &map[string]any{}); err == nil { + req.Header.Set("Content-Type", "application/json") + } else { + req.Header.Set("Content-Type", "text/plain") + } resp, err := http.DefaultClient.Do(req) if err != nil { @@ -29,7 +65,7 @@ func (e *Engine) runHTTP(ctx context.Context, tool types.Tool, input string) (cm if resp.StatusCode > 299 { _, _ = io.ReadAll(resp.Body) - return nil, fmt.Errorf("error in request to [%s] [%d]: %s", url, resp.StatusCode, resp.Status) + return nil, fmt.Errorf("error in request to [%s] [%d]: %s", toolURL, resp.StatusCode, resp.Status) } content, err := io.ReadAll(resp.Body) @@ -37,6 +73,16 @@ func (e *Engine) runHTTP(ctx context.Context, tool types.Tool, input string) (cm return nil, err } + if resp.Header.Get("Content-Type") == "application/json" && strings.HasPrefix(string(content), "\"") { + // This is dumb hack when something returns a string in JSON format, just decode it to a string + var s string + if err := json.Unmarshal(content, &s); err == nil { + return &Return{ + Result: &s, + }, nil + } + } + s := string(content) return &Return{ Result: &s, diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index c3eebad6..31b8ac9a 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -210,7 +210,7 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN } if i != 0 && tool.Name == "" { - return types.Tool{}, parser.NewErrLine(tool.Source.LineNo, fmt.Errorf("only the first tool in a file can have no name")) + return types.Tool{}, parser.NewErrLine(tool.Source.File, tool.Source.LineNo, fmt.Errorf("only the first tool in a file can have no name")) } if targetToolName != "" && tool.Name == targetToolName { @@ -218,7 +218,7 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN } if existing, ok := localTools[tool.Name]; ok { - return types.Tool{}, parser.NewErrLine(tool.Source.LineNo, + return types.Tool{}, parser.NewErrLine(tool.Source.File, tool.Source.LineNo, fmt.Errorf("duplicate tool name [%s] in %s found at lines %d and %d", tool.Name, tool.Source.File, tool.Source.LineNo, existing.Source.LineNo)) } @@ -313,10 +313,13 @@ func link(ctx context.Context, prg *types.Program, base *source, tool types.Tool continue } - toolName, subTool, ok := strings.Cut(targetToolName, " from ") + subTool, toolName, ok := strings.Cut(targetToolName, " from ") if ok { toolName = strings.TrimSpace(toolName) subTool = strings.TrimSpace(subTool) + } else { + toolName = targetToolName + subTool = "" } resolvedTool, err := resolve(ctx, prg, base, toolName, subTool) diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 1e2d327e..fddb4500 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -23,7 +23,6 @@ import ( const ( DefaultVisionModel = openai.GPT4VisionPreview DefaultModel = openai.GPT4TurboPreview - DefaultMaxTokens = 1024 DefaultPromptParameter = "defaultPromptParameter" ) @@ -274,10 +273,6 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } } - if request.MaxTokens == 0 { - request.MaxTokens = DefaultMaxTokens - } - if !messageRequest.Vision { for _, tool := range messageRequest.Tools { params := tool.Function.Parameters diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 71331918..d8e3877a 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -123,6 +123,7 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { } type ErrLine struct { + Path string Line int Err error } @@ -132,11 +133,15 @@ func (e *ErrLine) Unwrap() error { } func (e *ErrLine) Error() string { - return fmt.Sprintf("line %d: %v", e.Line, e.Err) + if e.Path == "" { + return fmt.Sprintf("line %d: %v", e.Line, e.Err) + } + return fmt.Sprintf("line %s:%d: %v", e.Path, e.Line, e.Err) } -func NewErrLine(lineNo int, err error) error { +func NewErrLine(path string, lineNo int, err error) error { return &ErrLine{ + Path: path, Line: lineNo, Err: err, } @@ -161,7 +166,7 @@ func commentEmbedded(line string) (string, bool) { prefix := i + "gptscript:" cut, ok := strings.CutPrefix(line, prefix) if ok { - return cut, ok + return strings.TrimSpace(cut) + "\n", ok } } return line, false @@ -183,6 +188,10 @@ func Parse(input io.Reader) ([]types.Tool, error) { } line := scan.Text() + "\n" + if embeddedLine, ok := commentEmbedded(line); ok { + // Strip special comments to allow embedding the preamble in python or other interpreted languages + line = embeddedLine + } if line == "---\n" { context.finish(&tools) @@ -190,11 +199,6 @@ func Parse(input io.Reader) ([]types.Tool, error) { } if !context.inBody { - // Strip special comments to allow embedding the preamble in python or other interpreted languages - if newLine, ok := commentEmbedded(line); ok { - line = newLine - } - // If the very first line is #! just skip because this is a unix interpreter declaration if strings.HasPrefix(line, "#!") && lineNo == 1 { continue @@ -212,7 +216,7 @@ func Parse(input io.Reader) ([]types.Tool, error) { // Look for params if isParam, err := isParam(line, &context.tool); err != nil { - return nil, NewErrLine(lineNo, err) + return nil, NewErrLine("", lineNo, err) } else if isParam { continue } diff --git a/pkg/types/tool.go b/pkg/types/tool.go index 78b9907d..e54a1865 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -8,7 +8,7 @@ import ( ) const ( - DaemonPrefix = "#!sys.daemon " + DaemonPrefix = "#!sys.daemon" CommandPrefix = "#!" ) From 5174792790f8ce2f0aa67133fc534fcbf4ab30a6 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 9 Feb 2024 17:51:28 -0700 Subject: [PATCH 054/774] Fix linting issue --- pkg/engine/daemon.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/engine/daemon.go b/pkg/engine/daemon.go index a232c1cf..2e408798 100644 --- a/pkg/engine/daemon.go +++ b/pkg/engine/daemon.go @@ -68,7 +68,7 @@ func getPath(instructions string) (string, string) { return strings.TrimSpace(rest), strings.TrimSpace(value) } -func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, error) { +func (e *Engine) startDaemon(_ context.Context, tool types.Tool) (string, error) { daemonLock.Lock() defer daemonLock.Unlock() @@ -85,7 +85,7 @@ func (e *Engine) startDaemon(ctx context.Context, tool types.Tool) (string, erro daemonCtx, daemonClose = context.WithCancel(context.Background()) } - ctx = daemonCtx + ctx := daemonCtx port = e.getNextPort() url = fmt.Sprintf("http://127.0.0.1:%d%s", port, path) From 7f7ef6363e3d4b150b72ca3e5ffe0590c44bf611 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 9 Feb 2024 18:31:29 -0700 Subject: [PATCH 055/774] Allow internal prompt to be skipped --- pkg/engine/engine.go | 2 +- pkg/monitor/display.go | 4 ++-- pkg/parser/parser.go | 6 ++++++ pkg/types/tool.go | 19 ++++++++++--------- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 5077cfa2..55e499ea 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -180,7 +180,7 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { Temperature: tool.Temperature, } - if InternalSystemPrompt != "" { + if InternalSystemPrompt != "" && (tool.InternalPrompt == nil || *tool.InternalPrompt) { completion.Messages = append(completion.Messages, types.CompletionMessage{ Role: types.CompletionMessageRoleTypeSystem, Content: types.Text(InternalSystemPrompt), diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index e4ababd4..965c0173 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -68,7 +68,7 @@ func (l *livePrinter) end() { return } if l.needsNewline { - fmt.Println() + _, _ = fmt.Fprintln(os.Stderr) } l.needsNewline = false } @@ -83,7 +83,7 @@ func (l *livePrinter) print(event runner.Event, c call) { last := l.lastLines[c.ID] line := strings.TrimPrefix(event.Content, last) - fmt.Print(line) + _, _ = fmt.Fprint(os.Stderr, line) l.needsNewline = !strings.HasSuffix(line, "\n") l.lastLines[c.ID] = event.Content } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index d8e3877a..51b635f1 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -79,6 +79,12 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { tool.ModelName = value case "description": tool.Description = value + case "internalprompt": + v, err := toBool(value) + if err != nil { + return false, err + } + tool.InternalPrompt = &v case "tools": tool.Tools = append(tool.Tools, csv(strings.ToLower(value))...) case "args": diff --git a/pkg/types/tool.go b/pkg/types/tool.go index e54a1865..0db773ea 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -23,15 +23,16 @@ type Program struct { type BuiltinFunc func(ctx context.Context, env []string, input string) (string, error) type Tool struct { - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Arguments *JSONSchema `json:"arguments,omitempty"` - Instructions string `json:"instructions,omitempty"` - Tools []string `json:"tools,omitempty"` - ToolMapping map[string]string `json:"toolMapping,omitempty"` - LocalTools map[string]string `json:"localTools,omitempty"` - BuiltinFunc BuiltinFunc `json:"-"` + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + InternalPrompt *bool `json:"internalPrompt"` + Arguments *JSONSchema `json:"arguments,omitempty"` + Instructions string `json:"instructions,omitempty"` + Tools []string `json:"tools,omitempty"` + ToolMapping map[string]string `json:"toolMapping,omitempty"` + LocalTools map[string]string `json:"localTools,omitempty"` + BuiltinFunc BuiltinFunc `json:"-"` Vision bool `json:"vision,omitempty"` MaxTokens int `json:"maxTokens,omitempty"` From fdd9404fb519479684cbe3378b0bcb2af7312126 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 9 Feb 2024 19:17:45 -0700 Subject: [PATCH 056/774] Allow reading script from stdin using "gptscript -" --- pkg/cli/gptscript.go | 23 ++++++++++++++++++++--- pkg/loader/loader.go | 15 +++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 4c09d0fa..1a206ca9 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -18,6 +18,7 @@ import ( "github.com/gptscript-ai/gptscript/pkg/openai" "github.com/gptscript-ai/gptscript/pkg/runner" "github.com/gptscript-ai/gptscript/pkg/server" + "github.com/gptscript-ai/gptscript/pkg/types" "github.com/gptscript-ai/gptscript/pkg/version" "github.com/spf13/cobra" "golang.org/x/term" @@ -125,9 +126,25 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - prg, err := loader.Program(cmd.Context(), args[0], r.SubTool) - if err != nil { - return err + var ( + prg types.Program + err error + ) + + if args[0] == "-" { + data, err := io.ReadAll(os.Stdin) + if err != nil { + return err + } + prg, err = loader.ProgramFromSource(cmd.Context(), string(data), r.SubTool) + if err != nil { + return err + } + } else { + prg, err = loader.Program(cmd.Context(), args[0], r.SubTool) + if err != nil { + return err + } } if r.Assemble { diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 31b8ac9a..fcb68d26 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -342,6 +342,21 @@ func link(ctx context.Context, prg *types.Program, base *source, tool types.Tool return tool, nil } +func ProgramFromSource(ctx context.Context, content, subToolName string) (types.Program, error) { + prg := types.Program{ + ToolSet: types.ToolSet{}, + } + tool, err := readTool(ctx, &prg, &source{ + Content: io.NopCloser(strings.NewReader(content)), + File: "inline", + }, subToolName) + if err != nil { + return types.Program{}, err + } + prg.EntryToolID = tool.ID + return prg, nil +} + func Program(ctx context.Context, name, subToolName string) (types.Program, error) { prg := types.Program{ ToolSet: types.ToolSet{}, From 90a63c44f426467cd47c45e0eb7999ded57d1e92 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 9 Feb 2024 21:58:04 -0700 Subject: [PATCH 057/774] Add sys.download --- examples/bob.gpt | 9 +++++ examples/sqlite-download.gpt | 9 +++++ pkg/builtin/builtin.go | 65 ++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 examples/bob.gpt create mode 100644 examples/sqlite-download.gpt diff --git a/examples/bob.gpt b/examples/bob.gpt new file mode 100644 index 00000000..6f828e97 --- /dev/null +++ b/examples/bob.gpt @@ -0,0 +1,9 @@ +tools: bob + +Ask Bob how he is doing and let me know exactly what he said. + +--- +name: bob +description: I'm Bob, a friendly guy. + +When asked how I am doing, respond with "I'm doing great fellow friendly AI tool!" diff --git a/examples/sqlite-download.gpt b/examples/sqlite-download.gpt new file mode 100644 index 00000000..6364bc35 --- /dev/null +++ b/examples/sqlite-download.gpt @@ -0,0 +1,9 @@ +tools: sys.download, sys.exec + +Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to the +local directory. Expand the archive as there is a sqlite database in it. + +First inspect the schema of the database to understand the table structure. + +Form and run a SQL query to find the artist with the most number of albums and output +the result of that. diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 7b132605..c20aace9 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -3,6 +3,7 @@ package builtin import ( "context" "encoding/json" + "errors" "fmt" "io" "io/fs" @@ -80,6 +81,13 @@ var tools = map[string]types.Tool{ "name", "The environment variable name to lookup"), BuiltinFunc: SysGetenv, }, + "sys.download": { + Description: "Downloads a URL, saving the contents to disk at a given location", + Arguments: types.ObjectSchema( + "url", "The URL to download, either http or https.", + "location", "(optional) The on disk location to store the file. If no location is specified a temp location will be used. If the target file already exists it will not be overwritten and will fail."), + BuiltinFunc: SysDownload, + }, } func SysProgram() *types.Program { @@ -308,3 +316,60 @@ func SysAbort(ctx context.Context, env []string, input string) (string, error) { } return "", fmt.Errorf("ABORT: %s", params.Message) } + +func SysDownload(ctx context.Context, env []string, input string) (string, error) { + var params struct { + URL string `json:"url,omitempty"` + Location string `json:"location,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + checkExists := true + if params.Location == "" { + f, err := os.CreateTemp("", "gpt-download") + if err != nil { + return "", err + } + if err := f.Close(); err != nil { + return "", err + } + checkExists = false + params.Location = f.Name() + } + + if checkExists { + if _, err := os.Stat(params.Location); err == nil { + return "", fmt.Errorf("file %s already exists and can not be overwritten: %w", params.Location, err) + } else if err != nil && !errors.Is(err, fs.ErrNotExist) { + return "", err + } + } + + log.Infof("download [%s] to [%s]", params.URL, params.Location) + resp, err := http.Get(params.URL) + if err != nil { + return "", err + } + defer func() { + _, _ = io.ReadAll(resp.Body) + _ = resp.Body.Close() + }() + + if resp.StatusCode > 299 { + return "", fmt.Errorf("invalid status code [%d] downloading [%s]: %s", resp.StatusCode, params.URL, resp.Status) + } + + f, err := os.Create(params.Location) + if err != nil { + return "", fmt.Errorf("failed to create [%s]: %w", params.Location, err) + } + defer f.Close() + + if _, err := io.Copy(f, resp.Body); err != nil { + return "", fmt.Errorf("failed copying data from [%s] to [%s]: %w", params.URL, params.Location, err) + } + + return params.Location, nil +} From c558ca5299cdea231a7b333711666ba144454627 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 9 Feb 2024 22:38:56 -0700 Subject: [PATCH 058/774] Add sys.remove --- examples/sqlite-download.gpt | 9 ++++++--- pkg/builtin/builtin.go | 26 +++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/examples/sqlite-download.gpt b/examples/sqlite-download.gpt index 6364bc35..53166545 100644 --- a/examples/sqlite-download.gpt +++ b/examples/sqlite-download.gpt @@ -1,9 +1,12 @@ -tools: sys.download, sys.exec +tools: sys.download, sys.exec, sys.remove -Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to the -local directory. Expand the archive as there is a sqlite database in it. +Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to a +random file. Then expand the archive to a temporary location as there is a sqlite +database in it. First inspect the schema of the database to understand the table structure. Form and run a SQL query to find the artist with the most number of albums and output the result of that. + +When done remove the database file and the downloaded content. diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index c20aace9..b10e101a 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -85,9 +85,16 @@ var tools = map[string]types.Tool{ Description: "Downloads a URL, saving the contents to disk at a given location", Arguments: types.ObjectSchema( "url", "The URL to download, either http or https.", - "location", "(optional) The on disk location to store the file. If no location is specified a temp location will be used. If the target file already exists it will not be overwritten and will fail."), + "location", "(optional) The on disk location to store the file. If no location is specified a temp location will be used. If the target file already exists it will fail unless override is set to true.", + "override", "If true and a file at the location exists, the file will be overwritten, otherwise fail. Default is false"), BuiltinFunc: SysDownload, }, + "sys.remove": { + Description: "Removes the specified files", + Arguments: types.ObjectSchema( + "location", "The file to remove"), + BuiltinFunc: SysRemove, + }, } func SysProgram() *types.Program { @@ -317,10 +324,22 @@ func SysAbort(ctx context.Context, env []string, input string) (string, error) { return "", fmt.Errorf("ABORT: %s", params.Message) } +func SysRemove(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Location string `json:"location,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + return fmt.Sprintf("Removed file: %s", params.Location), os.Remove(params.Location) +} + func SysDownload(ctx context.Context, env []string, input string) (string, error) { var params struct { URL string `json:"url,omitempty"` Location string `json:"location,omitempty"` + Override bool `json:"override,omitempty"` } if err := json.Unmarshal([]byte(input), ¶ms); err != nil { return "", err @@ -339,9 +358,9 @@ func SysDownload(ctx context.Context, env []string, input string) (string, error params.Location = f.Name() } - if checkExists { + if checkExists && !params.Override { if _, err := os.Stat(params.Location); err == nil { - return "", fmt.Errorf("file %s already exists and can not be overwritten: %w", params.Location, err) + return "", fmt.Errorf("file %s already exists and can not be overwritten", params.Location) } else if err != nil && !errors.Is(err, fs.ErrNotExist) { return "", err } @@ -361,6 +380,7 @@ func SysDownload(ctx context.Context, env []string, input string) (string, error return "", fmt.Errorf("invalid status code [%d] downloading [%s]: %s", resp.StatusCode, params.URL, resp.Status) } + _ = os.Remove(params.Location) f, err := os.Create(params.Location) if err != nil { return "", fmt.Errorf("failed to create [%s]: %w", params.Location, err) From a73140f18c9ac23e78e97b13dd59e39cf8527386 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 10 Feb 2024 00:51:39 -0700 Subject: [PATCH 059/774] Initial README.md --- README.md | 211 +++++++++++++++++++++++++++++++------- examples/bob-as-shell.gpt | 12 +++ examples/bob.gpt | 3 +- 3 files changed, 187 insertions(+), 39 deletions(-) create mode 100644 examples/bob-as-shell.gpt diff --git a/README.md b/README.md index 1ffe9893..9286b2a9 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,190 @@ -# README.md for GPTscript Project +# GPTScript -## Project Description +## Overview -This project utilizes `GPTscript`, a powerful scripting tool that leverages OpenAI's GPT plugins to execute tasks specified in `.gpt` files. These scripts can combine traditional scripting with GPT's AI capabilities to automate complex workflows, parse information, and more. +GPTScript is a new scripting language to automate your interaction with a Large Language Model (LLM), namely OpenAI. +The syntax of GPTScript is largely natural language, making it very easy to learn and use. +Natural language prompts can be mixed with traditional scripts such as bash and python or even external HTTP service +calls. -## Usage +```yaml +Tools: sys.download, sys.exec, sys.remove -The primary command used to run GPT scripts is `gptscript`, which can be invoked with various flags to control the script execution. A typical usage pattern looks like this: +Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to a +random file. Then expand the archive to a temporary location as there is a sqlite +database in it. -```bash -gptscript [flags] PROGRAM_FILE [INPUT...] +First inspect the schema of the database to understand the table structure. + +Form and run a SQL query to find the artist with the most number of albums and output +the result of that. + +When done remove the database file and the downloaded content. +``` + +## Quick Start + +1. Install with brew (or from [releases](https://github.com/gptscript-ai/gptscript/releases/latest)) +```shell +brew install gptscript-ai/tap/gptscript +``` +2. Get an API key from [OpenAI](https://platform.openai.com/api-keys). +```shell +export OPENAI_API_KEY="your-api-key" +``` +3. Run Hello World: +```shell +gptscript https://gptscript.ai/echo.gpt --input "Hello, World!" +``` + +## How it works + +***GPTScript is composed of tools.*** Each tool performs a series of actions similar to a function. Tools have available +to them other tools that can be invoked similar to a function call. While similar to a function, the tools are +implemented with a natural language and not code. ***The interaction of the tools is determined by the AI model***, +the model determines if the tool needs to be invoked and what arguments to pass. Tools are intended to be implemented +with a natural language prompt but can also be implemented with a command or HTTP call. + +### Example +Below are two tool definitions, separated by `---`. The first tool does not require a name or description, but +every tool after name and description are required. The first tool, has the parameter `tools: bob` meaning that the tool named `bob` is available to be called if needed. + +```yaml +tools: bob + +Ask Bob how he is doing and let me know exactly what he said. + +--- +name: bob +description: I'm Bob, a friendly guy. +args: question: The question to ask Bob. + +When asked how I am doing, respond with "Thanks for asking "${question}", I'm doing great fellow friendly AI tool!" +``` +Put the above content in a file named `bob.gpt` and run the following command: +```shell +$ gptscript bob.gpt + +OUTPUT: + +Bob said, "I'm doing great fellow friendly AI tool!" +``` +Tools can be implemented by invoking a program instead of a natural language prompt. The below +example is the same as the previous example but implements Bob using bash. + +```yaml +Tools: bob + +Ask Bob how he is doing and let me know exactly what he said. + +--- +Name: bob +Description: I'm Bob, a friendly guy. +Args: question: The question to ask Bob. + +#!/bin/bash + +echo "Thanks for asking ${question}, I'm doing great fellow friendly AI tool!" +``` + +With these basic building blocks you can create complex scripts with AI interacting with, your local system, data, +or external services. + +## GPT File Reference + +### Extension +GPTScript files use the `.gpt` extension by convention. + +### File Structure +A GPTScript file has one or more tools in the file. Each tool is separated by three dashes `---` alone on a line. + +```yaml +Name: tool1 +Description: This is tool1 + +Do sample tool stuff. + +--- +Name: tool2 +Description: This is tool2 + +Do more sample tool stuff. +``` + +### Tool Definition + +A tool starts with a preamble that defines the tool's name, description, args, available tools and additional parameters. +The preamble is followed by the tool's body, which contains the instructions for the tool. Comments in +the preamble are lines starting with `#` and are ignored by the parser. Comments are not really encouraged +as the text is typically more useful in the description, argument descriptions or instructions. + +```yaml +Name: tool-name +# This is a comment in the preamble. Comments don't typically provide much value +Description: Tool description +# This tool can invoke tool1 or tool2 if needed +Tools: tool1, tool2 +Args: arg1: The description of arg1 + +Tool instructions go here. ``` +#### Tool Parameters -Where `PROGRAM_FILE` is the script to be executed, optionally followed by `INPUT` arguments to pass into the script. +Tool parameters are key-value pairs defined at the beginning of a tool block, before any instructional text. They are specified in the format `key: value`. The parser recognizes the following keys (case-insensitive and spaces are ignored): -## GPT File Syntax +`Name`: The name of the tool. -GPT script files (`*.gpt`) follow a syntax which allows for defining tools, their descriptions, arguments, and embedded traditional scripting codes. Here's a breakdown of the syntax: +`Model Name`: The OpenAI model to use, by default it uses "gpt-4-turbo-preview" -- `tools:` Followed by the tool names to be used. -- `name:` Defines the tool's name. -- `description:` Describes what the tool does. -- `args:` Lists arguments the tool accepts, describing the expected input. -- `tools:` Below the main tool definition, you can specify other tools used by this tool. -- A line containing `---` signifies the separation between tool metadata and the script code itself. +`Description`: The description of the tool. It is important that the properly describes the tool's purpose as the +description is used by the LLM to determine if the tool is to be invoked. -## Example `.gpt` Files and Their Syntax +`Internal Prompt`: Setting this to `false` will disable the built in system prompt for this tool. GPTScript includes a +default system prompt to instruct the AI to behave more like a script engine and not a "helpful assistant." -The repository contains several example `.gpt` files, such as: +`Tools`: A comma-separated list of tools that are available to be called by this tool. A tool can only call the tools +that are defined here. -- `describe.gpt`: Provides functionalities for working with Go files, with tools like `ls`, `count`, `summarize`, and `compare`. -- `echo.gpt`: A simple script that echoes the provided input. -- `fib.gpt`: An example demonstrating a recursive function `myfunction`. -- `git-commit.gpt`: Automates the creation of a well-formed git commit message. -- `helloworld.gpt`: A basic script outputs the traditional "hello world" message. -- `summarize-syntax.gpt`: Meta-script for generating documentation based on `.gpt` files in a directory. -- `tables.gpt`: Using SQLite, identifies the table in a database with the most rows. +`Args`: Arguments for the tool. Each argument is defined in the format `arg-name: description`. All arguments are essentially +strings. No other type really exists as all input and output to tools is text based. + +`Vision`: If set to true this model will use vision capabilities. Vision models currently do not support the `Args` or `Tools` parameters. + +`Max Tokens`: Set to a number if you wish to limit the maximum number of tokens that can be generated by the LLM. + +`JSON Response`: Setting to `true` will cause the LLM to respond in a JSON format. If you set true you must also include instructions in the tool +to inform the LLM to respond in some JSON structure. + +`Temperature`: A floating-point number representing the temperature parameter. By default the temperature is 0. Set to a higher number to make the LLM more creative. + +#### Tool Body + +The tool body contains the instructions for the tool which can be a natural language prompt or +a command to execute. Commands must start with `#!` followed by the interpreter (e.g. `#!/bin/bash`, `#!python3`) +a text that will be placed in a file and passed to the interpreter. Arguments can be references in the instructions +using the format `${arg1}`. + +```yaml +name: echo-ai +description: A tool that echos the input +args: input: The input + +Just return only "${input}" + +--- +name: echo-command +description: A tool that echos the input +args: input: The input + +#!/bin/bash + +echo "${input}" +``` -## gptscript Command Help +## Examples -The help output for `gptscript` provides vital information on how to use the command along with the available flags. Here's an abbreviated listing of the flags: +For more examples check out the [examples](examples) directory. -- `--assemble`: Assemble tool to a single artifact, with output specified by `--output`. -- `--cache`, `--cache-dir`: Controls caching behavior and cache directory location. -- `--debug`: Enable debug logging. -- `--help`: Displays help information for `gptscript`. -- `--input`: Specify an input file or stdin. -- `--list-models`, `--list-tools`: Lists available models or built-in tools. -- `--openai-api-key`: Specifies the OpenAI API key to use. -- `--output`: Saves output to a specified file. -- `--quiet`: Suppresses output logging. -- `--sub-tool`: Selects a specific sub-tool to use from the `.gpt` file. +## License -For a detailed description and more options, refer to the `gptscript --help` command. +GPTScript is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text. \ No newline at end of file diff --git a/examples/bob-as-shell.gpt b/examples/bob-as-shell.gpt new file mode 100644 index 00000000..a1d10cb3 --- /dev/null +++ b/examples/bob-as-shell.gpt @@ -0,0 +1,12 @@ +tools: bob + +Ask Bob how he is doing and let me know exactly what he said. + +--- +name: bob +description: I'm Bob, a friendly guy. +args: question: The question to ask Bob. + +#!/bin/bash + +echo "Thanks for asking ${question}, I'm doing great fellow friendly AI tool!" diff --git a/examples/bob.gpt b/examples/bob.gpt index 6f828e97..2391b615 100644 --- a/examples/bob.gpt +++ b/examples/bob.gpt @@ -5,5 +5,6 @@ Ask Bob how he is doing and let me know exactly what he said. --- name: bob description: I'm Bob, a friendly guy. +args: question: The question to ask Bob. -When asked how I am doing, respond with "I'm doing great fellow friendly AI tool!" +When asked how I am doing, respond with "Thanks for asking "${question}", I'm doing great fellow friendly AI tool!" From 8e9efff0b078cec03c2939253e034b3dd93a7a1e Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 10 Feb 2024 00:54:22 -0700 Subject: [PATCH 060/774] Add command for first example --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9286b2a9..122066c7 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ Natural language prompts can be mixed with traditional scripts such as bash and calls. ```yaml +# example.gpt + Tools: sys.download, sys.exec, sys.remove Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to a @@ -21,6 +23,14 @@ the result of that. When done remove the database file and the downloaded content. ``` +``` +$ gptscript ./example.gpt + +OUTPUT: + +The artist with the most number of albums in the database is Iron Maiden, with a total +of 21 albums. +``` ## Quick Start @@ -187,4 +197,4 @@ For more examples check out the [examples](examples) directory. ## License -GPTScript is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text. \ No newline at end of file +GPTScript is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text. From 3f6076b89cac68b573b73209e4f381ae58d36457 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 10 Feb 2024 01:01:26 -0700 Subject: [PATCH 061/774] Small readme updates --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 122066c7..b16c0797 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ gptscript https://gptscript.ai/echo.gpt --input "Hello, World!" ***GPTScript is composed of tools.*** Each tool performs a series of actions similar to a function. Tools have available to them other tools that can be invoked similar to a function call. While similar to a function, the tools are -implemented with a natural language and not code. ***The interaction of the tools is determined by the AI model***, +primarily implemented with a natural language prompt. ***The interaction of the tools is determined by the AI model***, the model determines if the tool needs to be invoked and what arguments to pass. Tools are intended to be implemented with a natural language prompt but can also be implemented with a command or HTTP call. @@ -77,7 +77,7 @@ $ gptscript bob.gpt OUTPUT: -Bob said, "I'm doing great fellow friendly AI tool!" +Bob said, "Thanks for asking 'How are you doing?', I'm doing great fellow friendly AI tool!" ``` Tools can be implemented by invoking a program instead of a natural language prompt. The below example is the same as the previous example but implements Bob using bash. @@ -97,7 +97,7 @@ Args: question: The question to ask Bob. echo "Thanks for asking ${question}, I'm doing great fellow friendly AI tool!" ``` -With these basic building blocks you can create complex scripts with AI interacting with, your local system, data, +With these basic building blocks you can create complex scripts with AI interacting with AI, your local system, data, or external services. ## GPT File Reference From c2bdae94a271fd3fa4510a8cddefe1edff605033 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 10 Feb 2024 01:05:01 -0700 Subject: [PATCH 062/774] Update LICENSE copyright --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b16c0797..3e2bcb70 100644 --- a/README.md +++ b/README.md @@ -197,4 +197,16 @@ For more examples check out the [examples](examples) directory. ## License -GPTScript is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text. +Copyright (c) 2023 [Acorn Labs, Inc.](http://acorn.io) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. From a136e12aeec2649ac90de5400b2ff86f69a2f625 Mon Sep 17 00:00:00 2001 From: sheng-liang Date: Sat, 10 Feb 2024 21:11:41 -0800 Subject: [PATCH 063/774] Delete examples/tables.gpt It is superceded by sqlite-download.gpt Signed-off-by: sheng-liang --- examples/tables.gpt | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 examples/tables.gpt diff --git a/examples/tables.gpt b/examples/tables.gpt deleted file mode 100644 index edb2e4b8..00000000 --- a/examples/tables.gpt +++ /dev/null @@ -1,15 +0,0 @@ -Tools: sqlite - -I have the file sqlite database file /home/darren/src/openai-cookbook/examples/data/Chinook.db. - -What is the table with the most amount of rows in it? - ---- -Name: sqlite -Description: The sqlite command line program. This tool is used to run sqlite command or SQL statements against a database. The result of this tool will be the output of the executed command or statement. -Arg: databaseFile: The filename of the database to open -Arg: cmd: The sqlite command or sql statement to run. - -#!/bin/bash - -sqlite3 ${DATABASEFILE} -cmd "${CMD}" Date: Sat, 10 Feb 2024 04:02:14 -0700 Subject: [PATCH 064/774] Print status of subcalls --- go.mod | 1 + go.sum | 4 +- pkg/cli/gptscript.go | 14 +++--- pkg/monitor/display.go | 108 +++++++++++++++++++++++++++++++++++++---- pkg/openai/client.go | 10 +--- pkg/runner/runner.go | 27 +++++++---- 6 files changed, 127 insertions(+), 37 deletions(-) diff --git a/go.mod b/go.mod index c6923139..49acb47b 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/go-logr/logr v1.4.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect + github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/hexops/valast v1.4.3 // indirect diff --git a/go.sum b/go.sum index 50f4659b..f8d6702e 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ= github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index 1a206ca9..f8078629 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -32,7 +32,7 @@ type GPTScript struct { runner.Options DisplayOptions Debug bool `usage:"Enable debug logging"` - Quiet bool `usage:"No output logging" short:"q"` + Quiet *bool `usage:"No output logging" short:"q"` Output string `usage:"Save output to a file, or - for stdout" short:"o"` Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"` SubTool string `usage:"Use tool of this name, not the first tool in file"` @@ -80,11 +80,11 @@ func (r *GPTScript) listModels(ctx context.Context) error { } func (r *GPTScript) Pre(cmd *cobra.Command, args []string) error { - if r.Quiet { + if r.Quiet == nil { if term.IsTerminal(int(os.Stdout.Fd())) { - r.Quiet = false + r.Quiet = new(bool) } else { - r.Quiet = true + r.Quiet = &[]bool{true}[0] } } @@ -92,7 +92,7 @@ func (r *GPTScript) Pre(cmd *cobra.Command, args []string) error { mvl.SetDebug() } else { mvl.SetSimpleFormat() - if r.Quiet { + if *r.Quiet { mvl.SetError() } } @@ -165,7 +165,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { CacheOptions: r.CacheOptions, OpenAIOptions: r.OpenAIOptions, MonitorFactory: monitor.NewConsole(monitor.Options(r.DisplayOptions), monitor.Options{ - DisplayProgress: !r.Quiet, + DisplayProgress: !*r.Quiet, }), }) if err != nil { @@ -188,7 +188,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return err } } else { - if !r.Quiet { + if !*r.Quiet { if toolInput != "" { _, _ = fmt.Fprint(os.Stderr, "\nINPUT:\n\n") _, _ = fmt.Fprintln(os.Stderr, toolInput) diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index 965c0173..84837b54 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -59,8 +59,11 @@ type display struct { } type livePrinter struct { - lastLines map[string]string - needsNewline bool + lastContent map[string]string + callIDMap map[string]string + activePrinters []string + toPrint []string + needsNewline bool } func (l *livePrinter) end() { @@ -71,21 +74,100 @@ func (l *livePrinter) end() { _, _ = fmt.Fprintln(os.Stderr) } l.needsNewline = false + if len(l.activePrinters) > 0 { + delete(l.lastContent, l.activePrinters[0]) + } } -func (l *livePrinter) print(event runner.Event, c call) { +func (l *livePrinter) progressStart(event runner.Event, c call) { + if l == nil { + return + } + if !slices.Contains(l.activePrinters, c.ID) { + l.activePrinters = append(l.activePrinters, c.ID) + } + l.toPrint = slices.DeleteFunc(l.toPrint, func(s string) bool { + return s == c.ID + }) +} + +func (l *livePrinter) progressEnd(event runner.Event, c call) { if l == nil { return } - if c.ParentID != "" { + var result []string + for i, id := range l.activePrinters { + if id != c.ID { + result = append(result, id) + continue + } + + if i != 0 { + if !slices.Contains(l.toPrint, id) { + l.toPrint = append(l.toPrint, id) + } + continue + } + + for _, toPrintID := range l.toPrint { + content := l.lastContent[toPrintID] + delete(l.lastContent, toPrintID) + if content != "" { + _, _ = fmt.Fprint(os.Stderr, content) + if !strings.HasSuffix(content, "\n") { + _, _ = fmt.Fprintln(os.Stderr) + } + } + } + + l.toPrint = nil + result = l.activePrinters[1:] + if len(result) > 0 { + content := l.lastContent[result[0]] + if content != "" { + _, _ = fmt.Fprint(os.Stderr, content) + l.needsNewline = !strings.HasSuffix(content, "\n") + } + } + break + } + l.activePrinters = result +} + +func (l *livePrinter) formatContent(event runner.Event, c call) string { + if event.Content == "" { + return event.Content + } + prefix := fmt.Sprintf(" content [%s] content | ", l.callIDMap[c.ID]) + var lines []string + for _, line := range strings.Split(event.Content, "\n") { + if len(line) > 100 { + line = line[:100] + " ..." + } + lines = append(lines, prefix+line) + } + return strings.Join(lines, "\n") +} + +func (l *livePrinter) print(event runner.Event, c call) { + if l == nil { return } - last := l.lastLines[c.ID] - line := strings.TrimPrefix(event.Content, last) - _, _ = fmt.Fprint(os.Stderr, line) - l.needsNewline = !strings.HasSuffix(line, "\n") - l.lastLines[c.ID] = event.Content + content := l.formatContent(event, c) + last := l.lastContent[c.ID] + l.lastContent[c.ID] = content + + if len(l.activePrinters) > 0 && l.activePrinters[0] == c.ID && content != "" { + line, ok := strings.CutPrefix(content, last) + if !ok && last != "" { + _, _ = fmt.Fprintln(os.Stderr) + } + if line != "" { + _, _ = fmt.Fprint(os.Stderr, line) + l.needsNewline = !strings.HasSuffix(line, "\n") + } + } } func (d *display) Event(event runner.Event) { @@ -135,13 +217,17 @@ func (d *display) Event(event runner.Event) { switch event.Type { case runner.EventTypeCallStart: + d.livePrinter.progressStart(event, currentCall) d.livePrinter.end() currentCall.Start = event.Time currentCall.Input = event.Content log.Fields("input", event.Content).Infof("started [%s]", callName) + case runner.EventTypeCallSubCalls: + d.livePrinter.progressEnd(event, currentCall) case runner.EventTypeCallProgress: d.livePrinter.print(event, currentCall) case runner.EventTypeCallContinue: + d.livePrinter.progressStart(event, currentCall) d.livePrinter.end() log.Fields("toolResults", event.ToolResults).Infof("continue [%s]", callName) case runner.EventTypeChat: @@ -167,6 +253,7 @@ func (d *display) Event(event runner.Event) { Cached: event.ChatResponseCached, }) case runner.EventTypeCallFinish: + d.livePrinter.progressEnd(event, currentCall) d.livePrinter.end() currentCall.End = event.Time currentCall.Output = event.Content @@ -204,7 +291,8 @@ func newDisplay(dumpState string, progress bool) *display { } if progress { display.livePrinter = &livePrinter{ - lastLines: map[string]string{}, + lastContent: map[string]string{}, + callIDMap: display.callIDMap, } } return display diff --git a/pkg/openai/client.go b/pkg/openai/client.go index fddb4500..071d10ee 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -407,19 +407,11 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, cacheKey := c.cacheKey(request) request.Stream = true - msg := "" - if len(request.Messages) > 0 { - msg = request.Messages[len(request.Messages)-1].Content - if msg != "" { - msg = "Sent content:\n\n" + msg + "\n" - } - } - partial <- Status{ CompletionID: transactionID, PartialResponse: &types.CompletionMessage{ Role: types.CompletionMessageRoleTypeAssistant, - Content: types.Text(msg + "Waiting for model response...\n"), + Content: types.Text("Waiting for model response..."), }, } diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index f84cc46b..d277ff4f 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -83,15 +83,16 @@ func (r *Runner) Run(ctx context.Context, prg types.Program, env []string, input } type Event struct { - Time time.Time `json:"time,omitempty"` - CallContext *engine.Context `json:"callContext,omitempty"` - ToolResults int `json:"toolResults,omitempty"` - Type EventType `json:"type,omitempty"` - ChatCompletionID string `json:"chatCompletionId,omitempty"` - ChatRequest any `json:"chatRequest,omitempty"` - ChatResponse any `json:"chatResponse,omitempty"` - ChatResponseCached bool `json:"chatResponseCached,omitempty"` - Content string `json:"content,omitempty"` + Time time.Time `json:"time,omitempty"` + CallContext *engine.Context `json:"callContext,omitempty"` + ToolSubCalls map[string]engine.Call `json:"toolSubCalls,omitempty"` + ToolResults int `json:"toolResults,omitempty"` + Type EventType `json:"type,omitempty"` + ChatCompletionID string `json:"chatCompletionId,omitempty"` + ChatRequest any `json:"chatRequest,omitempty"` + ChatResponse any `json:"chatResponse,omitempty"` + ChatResponseCached bool `json:"chatResponseCached,omitempty"` + Content string `json:"content,omitempty"` } type EventType string @@ -99,6 +100,7 @@ type EventType string var ( EventTypeCallStart = EventType("callStart") EventTypeCallContinue = EventType("callContinue") + EventTypeCallSubCalls = EventType("callSubCalls") EventTypeCallProgress = EventType("callProgress") EventTypeChat = EventType("callChat") EventTypeCallFinish = EventType("callFinish") @@ -138,6 +140,13 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp return *result.Result, nil } + monitor.Event(Event{ + Time: time.Now(), + CallContext: &callCtx, + Type: EventTypeCallSubCalls, + ToolSubCalls: result.Calls, + }) + callResults, err := r.subCalls(callCtx, monitor, env, result) if err != nil { return "", err From fa863df58af91c3f6eaa03ab4c4919521e71338b Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Mon, 12 Feb 2024 01:00:38 -0500 Subject: [PATCH 065/774] enhance: enable shell completions Enable basic shell completions for `bash`, `zsh`, `fish`, and `powershell` by exposing the `completion` command automatically generated by Cobra. The command is hidden, so it doesn't show up in the help text or completions. ```zsh $ source <(gptscript completion zsh) $ gptscript --[tab] -- completions -- --assemble -- Assemble tool to a single artifact, saved to --output ($GPTSCRIPT_ASSEMBLE) --cache -- Disable caching ($GPTSCRIPT_CACHE) --cache-dir -- Directory to store cache (default: $XDG_CACHE_HOME/gptscript) ($GPTSCRIPT_CACHE_DIR) --debug -- Enable debug logging ($GPTSCRIPT_DEBUG) --dump-state -- Dump the internal execution state to a file ($GPTSCRIPT_DUMP_STATE) --help -- help for gptscript --input -- Read input from a file ("-" for stdin) ($GPTSCRIPT_INPUT) --list-models -- List the models available and exit ($GPTSCRIPT_LIST_MODELS) --list-tools -- List built-in tools and exit ($GPTSCRIPT_LIST_TOOLS) --listen-address -- Server listen address ($GPTSCRIPT_LISTEN_ADDRESS) --openai-api-key -- OpenAI API KEY ($OPENAI_API_KEY) --openai-api-type -- OpenAI API Type (valid: OPEN_AI, AZURE, AZURE_AD) ($OPENAI_API_TYPE) --openai-api-version -- OpenAI API Version (for Azure) ($OPENAI_API_VERSION) --openai-base-url -- OpenAI base URL ($OPENAI_BASE_URL) --openai-org-id -- OpenAI organization ID ($OPENAI_ORG_ID) --output -- Save output to a file, or - for stdout ($GPTSCRIPT_OUTPUT) --quiet -- No output logging ($GPTSCRIPT_QUIET) --server -- Start server ($GPTSCRIPT_SERVER) --sub-tool -- Use tool of this name, not the first tool in file ($GPTSCRIPT_SUB_TOOL) --version -- version for gptscript ``` This implementation produces file path completions for ALL positional and flag args. Support for customizing completions for individual arguments will require new features in `github.com/acorn-io/cmd` and should be addressed in a followup. Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- pkg/cli/gptscript.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index f8078629..cf570d70 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -48,8 +48,23 @@ func New() *cobra.Command { } func (r *GPTScript) Customize(cmd *cobra.Command) { - cmd.Use = version.ProgramName + " [flags] PROGRAM_FILE [INPUT...]" cmd.Flags().SetInterspersed(false) + cmd.Use = version.ProgramName + " [flags] PROGRAM_FILE [INPUT...]" + cmd.Version = version.Get().String() + cmd.CompletionOptions.HiddenDefaultCmd = true + cmd.TraverseChildren = true + + // Enable shell completion for the gptscript command. + // Note: The gptscript command doesn't have any subcommands, but Cobra requires that at least one is defined before + // it will generate the completion command automatically. To work around this, define a hidden no-op subcommand. + cmd.AddCommand(&cobra.Command{Hidden: true}) + cmd.SetHelpCommand(&cobra.Command{Hidden: true}) + + // Override arg completion to prevent the hidden subcommands from masking default completion for positional args. + // Note: This should be removed if the gptscript command supports subcommands in the future. + cmd.ValidArgsFunction = func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) { + return nil, cobra.ShellCompDirectiveDefault + } } func (r *GPTScript) listTools(ctx context.Context) error { From 8c6394bf6b098b27967bbc428ba2f95a966df3e6 Mon Sep 17 00:00:00 2001 From: Donnie Adams Date: Mon, 12 Feb 2024 10:40:40 -0500 Subject: [PATCH 066/774] fix: add revive lint and fix related issues Signed-off-by: Donnie Adams --- .golangci.yml | 1 + pkg/assemble/assemble.go | 3 +-- pkg/cache/cache.go | 5 ++--- pkg/cli/gptscript.go | 8 ++++---- pkg/engine/cmd.go | 14 +++++++------- pkg/engine/daemon.go | 10 ++++------ pkg/engine/engine.go | 2 +- pkg/loader/loader_test.go | 2 +- pkg/monitor/display.go | 14 +++++++------- pkg/openai/client.go | 20 ++++++++++---------- pkg/runner/monitor.go | 7 +++---- pkg/vision/image.go | 13 ++++++------- 12 files changed, 47 insertions(+), 52 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 889ceba6..b4bf06fd 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -18,5 +18,6 @@ linters: - unused - goimports - whitespace + - revive fast: false max-same-issues: 50 diff --git a/pkg/assemble/assemble.go b/pkg/assemble/assemble.go index f5644eb1..ad44d1dd 100644 --- a/pkg/assemble/assemble.go +++ b/pkg/assemble/assemble.go @@ -1,7 +1,6 @@ package assemble import ( - "context" "encoding/json" "io" @@ -10,7 +9,7 @@ import ( var Header = []byte("GPTSCRIPT!") -func Assemble(ctx context.Context, prg types.Program, output io.Writer) error { +func Assemble(prg types.Program, output io.Writer) error { if _, err := output.Write(Header); err != nil { return err } diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index d3afc744..3c23673d 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -1,7 +1,6 @@ package cache import ( - "context" "errors" "io/fs" "os" @@ -47,14 +46,14 @@ func New(opts ...Options) (*Client, error) { }, nil } -func (c *Client) Store(ctx context.Context, key string, content []byte) error { +func (c *Client) Store(key string, content []byte) error { if c == nil || c.noop { return nil } return os.WriteFile(filepath.Join(c.dir, key), content, 0644) } -func (c *Client) Get(ctx context.Context, key string) ([]byte, bool, error) { +func (c *Client) Get(key string) ([]byte, bool, error) { if c == nil || c.noop { return nil, false, nil } diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index f8078629..19569673 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -52,7 +52,7 @@ func (r *GPTScript) Customize(cmd *cobra.Command) { cmd.Flags().SetInterspersed(false) } -func (r *GPTScript) listTools(ctx context.Context) error { +func (r *GPTScript) listTools() error { var lines []string for _, tool := range builtin.ListTools() { lines = append(lines, tool.String()) @@ -79,7 +79,7 @@ func (r *GPTScript) listModels(ctx context.Context) error { return nil } -func (r *GPTScript) Pre(cmd *cobra.Command, args []string) error { +func (r *GPTScript) Pre(*cobra.Command, []string) error { if r.Quiet == nil { if term.IsTerminal(int(os.Stdout.Fd())) { r.Quiet = new(bool) @@ -107,7 +107,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { } if r.ListTools { - return r.listTools(cmd.Context()) + return r.listTools() } if r.Server { @@ -158,7 +158,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { out = f } - return assemble.Assemble(cmd.Context(), prg, out) + return assemble.Assemble(prg, out) } runner, err := runner.New(r.Options, runner.Options{ diff --git a/pkg/engine/cmd.go b/pkg/engine/cmd.go index ceeda580..04969333 100644 --- a/pkg/engine/cmd.go +++ b/pkg/engine/cmd.go @@ -40,11 +40,11 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) return tool.BuiltinFunc(ctx, e.Env, input) } - cmd, close, err := e.newCommand(ctx, nil, tool.Instructions, input) + cmd, stop, err := e.newCommand(ctx, nil, tool.Instructions, input) if err != nil { return "", err } - defer close() + defer stop() e.Progress <- openai.Status{ CompletionID: id, @@ -130,7 +130,7 @@ func (e *Engine) newCommand(ctx context.Context, extraEnv []string, instructions var ( cmdArgs = args[1:] - close func() + stop func() ) if strings.TrimSpace(rest) != "" { @@ -138,14 +138,14 @@ func (e *Engine) newCommand(ctx context.Context, extraEnv []string, instructions if err != nil { return nil, nil, err } - close = func() { - os.Remove(f.Name()) + stop = func() { + _ = os.Remove(f.Name()) } _, err = f.Write([]byte(rest)) _ = f.Close() if err != nil { - close() + stop() return nil, nil, err } cmdArgs = append(cmdArgs, f.Name()) @@ -153,5 +153,5 @@ func (e *Engine) newCommand(ctx context.Context, extraEnv []string, instructions cmd := exec.CommandContext(ctx, args[0], cmdArgs...) cmd.Env = env - return cmd, close, nil + return cmd, stop, nil } diff --git a/pkg/engine/daemon.go b/pkg/engine/daemon.go index 2e408798..391f1611 100644 --- a/pkg/engine/daemon.go +++ b/pkg/engine/daemon.go @@ -89,7 +89,7 @@ func (e *Engine) startDaemon(_ context.Context, tool types.Tool) (string, error) port = e.getNextPort() url = fmt.Sprintf("http://127.0.0.1:%d%s", port, path) - cmd, close, err := e.newCommand(ctx, []string{ + cmd, stop, err := e.newCommand(ctx, []string{ fmt.Sprintf("PORT=%d", port), }, types.CommandPrefix+instructions, @@ -103,7 +103,7 @@ func (e *Engine) startDaemon(_ context.Context, tool types.Tool) (string, error) cmd.Stdout = os.Stdout log.Infof("launched [%s][%s] port [%d] %v", tool.Name, tool.ID, port, cmd.Args) if err := cmd.Start(); err != nil { - close() + stop() return url, err } @@ -122,7 +122,7 @@ func (e *Engine) startDaemon(_ context.Context, tool types.Tool) (string, error) } cancel(err) - close() + stop() daemonLock.Lock() defer daemonLock.Unlock() @@ -140,11 +140,9 @@ func (e *Engine) startDaemon(_ context.Context, tool types.Tool) (string, error) for i := 0; i < 20; i++ { resp, err := http.Get(url) if err == nil && resp.StatusCode == http.StatusOK { - defer func() { - _ = resp.Body.Close() - }() go func() { _, _ = io.ReadAll(resp.Body) + _ = resp.Body.Close() }() return url, nil } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 55e499ea..54e82e4b 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -95,7 +95,7 @@ func (c *Context) ParentID() string { return c.Parent.ID } -func (c *Context) UnmarshalJSON(data []byte) error { +func (c *Context) UnmarshalJSON([]byte) error { panic("this data struct is circular by design and can not be read from json") } diff --git a/pkg/loader/loader_test.go b/pkg/loader/loader_test.go index dcfe0d43..6377c44e 100644 --- a/pkg/loader/loader_test.go +++ b/pkg/loader/loader_test.go @@ -2,5 +2,5 @@ package loader import "testing" -func TestLoader(t *testing.T) { +func TestLoader(*testing.T) { } diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index 84837b54..361f212a 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -39,7 +39,7 @@ var ( prettyIDCounter int64 ) -func (c *Console) Start(ctx context.Context, prg *types.Program, env []string, input string) (runner.Monitor, error) { +func (c *Console) Start(_ context.Context, prg *types.Program, _ []string, input string) (runner.Monitor, error) { id := atomic.AddInt64(&runID, 1) mon := newDisplay(c.dumpState, c.displayProgress) mon.dump.ID = fmt.Sprint(id) @@ -79,7 +79,7 @@ func (l *livePrinter) end() { } } -func (l *livePrinter) progressStart(event runner.Event, c call) { +func (l *livePrinter) progressStart(c call) { if l == nil { return } @@ -91,7 +91,7 @@ func (l *livePrinter) progressStart(event runner.Event, c call) { }) } -func (l *livePrinter) progressEnd(event runner.Event, c call) { +func (l *livePrinter) progressEnd(c call) { if l == nil { return } @@ -217,17 +217,17 @@ func (d *display) Event(event runner.Event) { switch event.Type { case runner.EventTypeCallStart: - d.livePrinter.progressStart(event, currentCall) + d.livePrinter.progressStart(currentCall) d.livePrinter.end() currentCall.Start = event.Time currentCall.Input = event.Content log.Fields("input", event.Content).Infof("started [%s]", callName) case runner.EventTypeCallSubCalls: - d.livePrinter.progressEnd(event, currentCall) + d.livePrinter.progressEnd(currentCall) case runner.EventTypeCallProgress: d.livePrinter.print(event, currentCall) case runner.EventTypeCallContinue: - d.livePrinter.progressStart(event, currentCall) + d.livePrinter.progressStart(currentCall) d.livePrinter.end() log.Fields("toolResults", event.ToolResults).Infof("continue [%s]", callName) case runner.EventTypeChat: @@ -253,7 +253,7 @@ func (d *display) Event(event runner.Event) { Cached: event.ChatResponseCached, }) case runner.EventTypeCallFinish: - d.livePrinter.progressEnd(event, currentCall) + d.livePrinter.progressEnd(currentCall) d.livePrinter.end() currentCall.End = event.Time currentCall.Output = event.Content diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 071d10ee..6ee8b1bd 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -136,12 +136,12 @@ func (c *Client) seed(request openai.ChatCompletionRequest) int { return hash.Seed(newRequest) } -func (c *Client) fromCache(ctx context.Context, messageRequest types.CompletionRequest, request openai.ChatCompletionRequest) (result []openai.ChatCompletionStreamResponse, _ bool, _ error) { +func (c *Client) fromCache(messageRequest types.CompletionRequest, request openai.ChatCompletionRequest) (result []openai.ChatCompletionStreamResponse, _ bool, _ error) { if messageRequest.Cache != nil && !*messageRequest.Cache { return nil, false, nil } - cache, found, err := c.cache.Get(ctx, c.cacheKey(request)) + cache, found, err := c.cache.Get(c.cacheKey(request)) if err != nil { return nil, false, err } else if !found { @@ -167,10 +167,10 @@ func toToolCall(call types.CompletionToolCall) openai.ToolCall { } } -func toMessages(ctx context.Context, cache *cache.Client, request types.CompletionRequest) (result []openai.ChatCompletionMessage, err error) { +func toMessages(cache *cache.Client, request types.CompletionRequest) (result []openai.ChatCompletionMessage, err error) { for _, message := range request.Messages { if request.Vision { - message, err = vision.ToVisionMessage(ctx, cache, message) + message, err = vision.ToVisionMessage(cache, message) if err != nil { return nil, err } @@ -189,7 +189,7 @@ func toMessages(ctx context.Context, cache *cache.Client, request types.Completi chatMessage.ToolCalls = append(chatMessage.ToolCalls, toToolCall(*content.ToolCall)) } if content.Image != nil { - url, err := vision.ImageToURL(ctx, cache, request.Vision, *content.Image) + url, err := vision.ImageToURL(cache, request.Vision, *content.Image) if err != nil { return nil, err } @@ -247,7 +247,7 @@ type Status struct { } func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- Status) (*types.CompletionMessage, error) { - msgs, err := toMessages(ctx, c.cache, messageRequest) + msgs, err := toMessages(c.cache, messageRequest) if err != nil { return nil, err } @@ -298,7 +298,7 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques var cacheResponse bool request.Seed = ptr(c.seed(request)) - response, ok, err := c.fromCache(ctx, messageRequest, request) + response, ok, err := c.fromCache(messageRequest, request) if err != nil { return nil, err } else if !ok { @@ -390,7 +390,7 @@ func override(left, right string) string { return left } -func (c *Client) store(ctx context.Context, key string, responses []openai.ChatCompletionStreamResponse) error { +func (c *Client) store(key string, responses []openai.ChatCompletionStreamResponse) error { buf := &bytes.Buffer{} gz := gzip.NewWriter(buf) err := json.NewEncoder(gz).Encode(responses) @@ -400,7 +400,7 @@ func (c *Client) store(ctx context.Context, key string, responses []openai.ChatC if err := gz.Close(); err != nil { return err } - return c.cache.Store(ctx, key, buf.Bytes()) + return c.cache.Store(key, buf.Bytes()) } func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, transactionID string, partial chan<- Status) (responses []openai.ChatCompletionStreamResponse, _ error) { @@ -426,7 +426,7 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, for { response, err := stream.Recv() if err == io.EOF { - return responses, c.store(ctx, cacheKey, responses) + return responses, c.store(cacheKey, responses) } else if err != nil { return nil, err } diff --git a/pkg/runner/monitor.go b/pkg/runner/monitor.go index 0a7eba25..99aafb1f 100644 --- a/pkg/runner/monitor.go +++ b/pkg/runner/monitor.go @@ -9,15 +9,14 @@ import ( type noopFactory struct { } -func (n noopFactory) Start(ctx context.Context, prg *types.Program, env []string, input string) (Monitor, error) { +func (n noopFactory) Start(context.Context, *types.Program, []string, string) (Monitor, error) { return noopMonitor{}, nil } type noopMonitor struct { } -func (n noopMonitor) Event(event Event) { +func (n noopMonitor) Event(Event) { } -func (n noopMonitor) Stop(output string, err error) { -} +func (n noopMonitor) Stop(string, error) {} diff --git a/pkg/vision/image.go b/pkg/vision/image.go index a021723d..055178d4 100644 --- a/pkg/vision/image.go +++ b/pkg/vision/image.go @@ -1,7 +1,6 @@ package vision import ( - "context" "encoding/base64" "encoding/json" "fmt" @@ -17,7 +16,7 @@ var ( urlBase = os.Getenv("cached://") ) -func ToVisionMessage(ctx context.Context, c *cache.Client, message types.CompletionMessage) (types.CompletionMessage, error) { +func ToVisionMessage(c *cache.Client, message types.CompletionMessage) (types.CompletionMessage, error) { if len(message.Content) != 1 || !strings.HasPrefix(message.Content[0].Text, "{") { return message, nil } @@ -33,7 +32,7 @@ func ToVisionMessage(ctx context.Context, c *cache.Client, message types.Complet content.Text = input.Text if input.URL != "" { - b64, ok, err := Base64FromStored(ctx, c, input.URL) + b64, ok, err := Base64FromStored(c, input.URL) if err != nil { return message, err } @@ -60,7 +59,7 @@ func ToVisionMessage(ctx context.Context, c *cache.Client, message types.Complet return message, nil } -func Base64FromStored(ctx context.Context, cache *cache.Client, url string) (string, bool, error) { +func Base64FromStored(cache *cache.Client, url string) (string, bool, error) { if !strings.HasPrefix(url, urlBase) { return "", false, nil } @@ -70,7 +69,7 @@ func Base64FromStored(ctx context.Context, cache *cache.Client, url string) (str } name := parts[len(parts)-1] - cached, ok, err := cache.Get(ctx, name) + cached, ok, err := cache.Get(name) if err != nil || !ok { return "", ok, err } @@ -78,7 +77,7 @@ func Base64FromStored(ctx context.Context, cache *cache.Client, url string) (str return base64.StdEncoding.EncodeToString(cached), true, nil } -func ImageToURL(ctx context.Context, c *cache.Client, vision bool, message types.ImageURL) (string, error) { +func ImageToURL(c *cache.Client, vision bool, message types.ImageURL) (string, error) { if message.URL != "" { return message.URL, nil } @@ -93,7 +92,7 @@ func ImageToURL(ctx context.Context, c *cache.Client, vision bool, message types } id := "i" + hash.Encode(message)[:12] - if err := c.Store(ctx, id, data); err != nil { + if err := c.Store(id, data); err != nil { return "", err } return fmt.Sprintf("%s/%s", urlBase, id), nil From 90011f7260bb973918979465a71661580e697504 Mon Sep 17 00:00:00 2001 From: tylerslaton Date: Mon, 12 Feb 2024 13:30:52 -0500 Subject: [PATCH 067/774] feat: add travel-agent example Signed-off-by: tylerslaton --- examples/travel-agent.gpt | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 examples/travel-agent.gpt diff --git a/examples/travel-agent.gpt b/examples/travel-agent.gpt new file mode 100644 index 00000000..0af1f4c8 --- /dev/null +++ b/examples/travel-agent.gpt @@ -0,0 +1,34 @@ +tools: search, sys.write +arg: destination: Destination to plan the vacation for +arg: start: Date to start the vacation on +arg: end: Date to end the vacation on + +You are a very experienced travel agent with a focus on affordable vacations for your clients. + +Before starting your job, do a quick search (just one search call) to refresh your knowledge on +what it means to be a travel agent. Use this context to guide how you evaluate the following steps. + +Based on the input, do the following in order: +1. Search the web for typical vacation routes in the $destination. +2. Based on the results build an initial outline of locations to include. +3. For each location you determine, search for essential things to do in that location (maximum of one search per location). Include at + least 5 activities per day and 20 per location. +4. With all of the activities and locations, build out an itenerary that outlines each day and each hour in that day for the trip. +5. Reevaluate the plan and move dates around such that it is optimized for effecient travel +6. Look over the entire thing one more time and ask yourself if its missing anything. If it is, make your edits now. +7. Write all of this into a vacation.md document. + +--- +name: search +description: Searches the internet for content +args: query: The query to search for +tools: sys.http.html2text? + +First download the content of "https://www.google.com/q=${encoded_query}". +Look for the first 3 search results. Download each search result and look for content +that would best answer the query ${query}. + +With all that information try your best to provide an answer or useful context to ${query}. + +If you can not retrieve a referenced URL then just skip that item and make a reference that +that URL was skipped. From 96cb5ad9918fd8dfc8b7e48b03ebaca1e7ba29e5 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Mon, 12 Feb 2024 14:06:07 -0500 Subject: [PATCH 068/774] Add a couple examples Signed-off-by: Grant Linville --- examples/generate-gptscript.gpt | 11 +++++++++ examples/hacker-news-headlines.gpt | 36 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 examples/generate-gptscript.gpt create mode 100644 examples/hacker-news-headlines.gpt diff --git a/examples/generate-gptscript.gpt b/examples/generate-gptscript.gpt new file mode 100644 index 00000000..934035f9 --- /dev/null +++ b/examples/generate-gptscript.gpt @@ -0,0 +1,11 @@ +tools: sys.find, sys.read, sys.write, sys.exec + +I have a new tool called gptscript. You can find information about it here in this folder +by looking at *.gpt files and the README.md file. The examples folder should be particularly helpful. + +Do the following: + +1. Search through the *.gpt files and README.md in order to learn how gptscript works. +2. Write a new gptscript file called myfile.gpt that uses the sys.write tool to write the first 10 + numbers in the Fibonacci sequence to a file called fibonacci.txt. +3. Execute the myfile.gpt script by running the following command: gptscript myfile.gpt \ No newline at end of file diff --git a/examples/hacker-news-headlines.gpt b/examples/hacker-news-headlines.gpt new file mode 100644 index 00000000..d8c5123d --- /dev/null +++ b/examples/hacker-news-headlines.gpt @@ -0,0 +1,36 @@ +tools: sys.http.get, sys.http.html2text, sys.find, sys.write, mongo_run, mongo_command, init_flask_project + +Perform the following actions in this order: + +1. Start the MongoDB database. +2. Create a collection in the Mongo instance called `headlines`. +3. Visit https://hackernews.com and get the top ten headlines. +4. Call the init_flask_project tool to set up the directories you will need. +5. Write each headline into the MongoDB collection that you created earlier called `headlines`. Write each one using a separate call to the mongo_command tool. The name of the database in Mongo that these will be written to is `headlines`. Don't forget to escape any quotation marks or apostrophes that appear in the headlines. +6. Generate a simple webserver in Python using Flask that will connect to the database and serve a single page listing all the headlines. Create it in the `headline` directory. Embed a link to the article in each headline displayed on the page. +7. Add some basic CSS styling to make the page look cool and modern. I want it to be dark themed. Style the links to be a light gray color. Make sure the page has a neat header with red accents. + +--- +name: mongo_run +description: starts a MongoDB database + +#!/usr/bin/env bash + +docker run -d -p 27017:27017 --name mongodb mongo:latest + +--- +name: mongo_command +description: run a command in the MongoDB database +args: command: the command to run in mongodb + +#!/usr/bin/env bash + +mongosh mongodb://localhost:27017/headlines --eval "$COMMAND" + +--- +name: init_flask_project +description: sets up initial directory structure needed for the flask project + +#!/usr/bin/env bash + +mkdir -p headline/{templates,static} From e033668ae804c44de946aca6aa5b0892a6a4cdd7 Mon Sep 17 00:00:00 2001 From: Vincent Fiduccia Date: Mon, 12 Feb 2024 14:27:42 -0700 Subject: [PATCH 069/774] Initial UI --- .gitignore | 1 + .vscode/launch.json | 16 + Makefile | 5 + ui/.ackrc | 14 + ui/.dockerignore | 8 + ui/.gitignore | 24 + ui/.vscode/settings.json | 58 + ui/Acornfile | 25 + ui/Dockerfile | 19 + ui/Makefile | 8 + ui/README.md | 25 + ui/app.config.ts | 6 + ui/app.vue | 54 + ui/components/arguments.vue | 77 + ui/components/call.vue | 112 + ui/components/chat-input.vue | 60 + ui/components/left-nav.vue | 73 + ui/components/message.vue | 66 + ui/components/relative-date.vue | 41 + ui/components/theme-toggle.vue | 28 + ui/config/server.ts | 10 + ui/config/types.d.ts | 180 + ui/eslint.config.js | 140 + ui/middleware/setup.global.ts | 8 + ui/nuxt.config.ts | 54 + ui/package.json | 39 + ui/pages/gpt/[...gpt].vue | 123 + ui/pages/index.vue | 7 + ui/pages/run/[run].vue | 115 + ui/plugins/dayjs.ts | 10 + ui/plugins/lookup.ts | 33 + ui/public/favicon.ico | Bin 0 -> 4286 bytes ui/scripts/clean | 6 + ui/stores/context.ts | 35 + ui/stores/gpts.ts | 34 + ui/stores/prefs.ts | 61 + ui/stores/runs.ts | 59 + ui/stores/socket.ts | 139 + ui/styles/_base.scss | 9 + ui/styles/app.scss | 1 + ui/tailwind.config.ts | 26 + ui/tsconfig.json | 17 + ui/utils/array.ts | 176 + ui/utils/object.ts | 141 + ui/utils/platform.ts | 66 + ui/utils/promise.ts | 7 + ui/utils/sort.ts | 292 ++ ui/utils/state.ts | 39 + ui/utils/string.ts | 397 ++ ui/utils/url.ts | 192 + ui/yarn.lock | 8331 +++++++++++++++++++++++++++++++ 51 files changed, 11467 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 ui/.ackrc create mode 100644 ui/.dockerignore create mode 100644 ui/.gitignore create mode 100644 ui/.vscode/settings.json create mode 100644 ui/Acornfile create mode 100644 ui/Dockerfile create mode 100644 ui/Makefile create mode 100644 ui/README.md create mode 100644 ui/app.config.ts create mode 100644 ui/app.vue create mode 100644 ui/components/arguments.vue create mode 100644 ui/components/call.vue create mode 100644 ui/components/chat-input.vue create mode 100644 ui/components/left-nav.vue create mode 100644 ui/components/message.vue create mode 100644 ui/components/relative-date.vue create mode 100644 ui/components/theme-toggle.vue create mode 100644 ui/config/server.ts create mode 100644 ui/config/types.d.ts create mode 100644 ui/eslint.config.js create mode 100644 ui/middleware/setup.global.ts create mode 100644 ui/nuxt.config.ts create mode 100644 ui/package.json create mode 100644 ui/pages/gpt/[...gpt].vue create mode 100644 ui/pages/index.vue create mode 100644 ui/pages/run/[run].vue create mode 100644 ui/plugins/dayjs.ts create mode 100644 ui/plugins/lookup.ts create mode 100644 ui/public/favicon.ico create mode 100755 ui/scripts/clean create mode 100644 ui/stores/context.ts create mode 100644 ui/stores/gpts.ts create mode 100644 ui/stores/prefs.ts create mode 100644 ui/stores/runs.ts create mode 100644 ui/stores/socket.ts create mode 100644 ui/styles/_base.scss create mode 100644 ui/styles/app.scss create mode 100644 ui/tailwind.config.ts create mode 100644 ui/tsconfig.json create mode 100644 ui/utils/array.ts create mode 100644 ui/utils/object.ts create mode 100644 ui/utils/platform.ts create mode 100644 ui/utils/promise.ts create mode 100644 ui/utils/sort.ts create mode 100644 ui/utils/state.ts create mode 100644 ui/utils/string.ts create mode 100644 ui/utils/url.ts create mode 100644 ui/yarn.lock diff --git a/.gitignore b/.gitignore index 9eb30257..53eee279 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /bin /.idea +/static/ui diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..f6453535 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch file", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "main.go", + "args": ["--server"] + } + ] +} diff --git a/Makefile b/Makefile index c05db3b2..72cea724 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,8 @@ +all: build-ui build + +build-ui: + $(MAKE) -C ui + build: CGO_ENABLED=0 go build -o bin/gptscript -tags "${GO_TAGS}" -ldflags "-s -w" . diff --git a/ui/.ackrc b/ui/.ackrc new file mode 100644 index 00000000..4399a80b --- /dev/null +++ b/ui/.ackrc @@ -0,0 +1,14 @@ +--ignore-dir=.git +--ignore-dir=.nuxt +--ignore-dir=.nuxt-prod +--ignore-dir=.nyc_output +--ignore-dir=.output +--ignore-dir=.vscode +--ignore-dir=coverage +--ignore-dir=dist +--ignore-dir=node_modules +--ignore-dir=tmp +--ignore-dir=vendor +--ignore-file=ext:svg +--ignore-file=is:selection.json +--ignore-file=is:yarn.lock diff --git a/ui/.dockerignore b/ui/.dockerignore new file mode 100644 index 00000000..ca4e990e --- /dev/null +++ b/ui/.dockerignore @@ -0,0 +1,8 @@ +node_modules +.nuxt +.nuxt-prod +.env +.nuxt +.nyc_output +coverage +node_modules diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 00000000..4a7f73a2 --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/ui/.vscode/settings.json b/ui/.vscode/settings.json new file mode 100644 index 00000000..365b5883 --- /dev/null +++ b/ui/.vscode/settings.json @@ -0,0 +1,58 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "editor.detectIndentation": false, + "editor.insertSpaces": true, + "editor.quickSuggestions": { + "strings": true + }, + "editor.tabSize": 2, + "eslint.format.enable": true, + "eslint.run": "onSave", + "eslint.validate": [ + "vue", + "html", + "javascript", + "typescript" + ], + "files.associations": { + "*.css": "tailwindcss" + }, + "files.exclude": { + ".ackrc": true, + ".dockerignore": true, + ".drone.yml": true, + ".editorconfig": true, + ".eslintcache": true, + ".eslintignore": true, + ".eslintrc.js": true, + ".gitignore": true, + ".nuxt*": true, + ".nyc_output": true, + "babel.config.js": true, + "coverage": true, + "jsconfig.json": true, + "LICENSE": true, + "yarn-error.log": true + }, + "javascript.preferences.importModuleSpecifier": "non-relative", + "prettier.enable": false, + "tailwindCSS.classAttributes": [ + "class", + "className", + "ui" + ], + "tailwindCSS.experimental.classRegex": [ + [ + "ui:\\s*{([^)]*)\\s*}", + "[\"'`]([^\"'`]*).*?[\"'`]" + ], + [ + "/\\*ui\\*/\\s*{([^;]*)}", + ":\\s*[\"'`]([^\"'`]*).*?[\"'`]" + ] + ], + "tailwindCSS.experimental.configFile": "tailwind.config.ts", + "typescript.preferences.importModuleSpecifier": "non-relative" +} diff --git a/ui/Acornfile b/ui/Acornfile new file mode 100644 index 00000000..3c896df0 --- /dev/null +++ b/ui/Acornfile @@ -0,0 +1,25 @@ +args: { + // Number of replicas + replicas: 1 + + // API Endpoint + api: "https://localhost:9090/v1" +} + +services: default: { + default: true + ports: ["80/http"] + container: "ui" +} + +containers: ui: { + scale: args.replicas + build: context: "." + + env: { + NUXT_PUBLIC_API: args.api + } + + ports: publish: "80/http" + probes: "http://localhost/healthz" +} diff --git a/ui/Dockerfile b/ui/Dockerfile new file mode 100644 index 00000000..e8c12434 --- /dev/null +++ b/ui/Dockerfile @@ -0,0 +1,19 @@ +FROM node:18-alpine as builder +ENV NODE_OPTIONS --max_old_space_size=8192 +WORKDIR /src +COPY package.json . +COPY yarn.lock . +RUN yarn --pure-lockfile install +COPY . . +ENV NUXT_PUBLIC_APP_VERSION=${NUXT_PUBLIC_APP_VERSION:-dev} +RUN yarn build + +FROM node:18-alpine +ENV HOST 0.0.0.0 +ENV PORT 80 +EXPOSE 80 +WORKDIR /src +COPY package.json . +COPY --from=builder /src/.output /src/.output +ENV NUXT_PUBLIC_APP_VERSION=${NUXT_PUBLIC_APP_VERSION:-dev} +CMD ["yarn","start"] diff --git a/ui/Makefile b/ui/Makefile new file mode 100644 index 00000000..0e70cf24 --- /dev/null +++ b/ui/Makefile @@ -0,0 +1,8 @@ +build: clean + yarn + yarn generate + rm -rf ../static/ui/_nuxt + cp -rp .output/public/* ../static/ui/ + +clean: + yarn clean diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 00000000..a406e071 --- /dev/null +++ b/ui/README.md @@ -0,0 +1,25 @@ +# GPTScript UI + +Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. + +## Setup + +```bash +yarn install +``` + +## Development Server + +Start the development server on `http://localhost:9091`: + +```bash +yarn dev +``` + +## Production + +Build the application for embedding into GPTScript: + +```bash +yarn run generate +``` diff --git a/ui/app.config.ts b/ui/app.config.ts new file mode 100644 index 00000000..884a7b76 --- /dev/null +++ b/ui/app.config.ts @@ -0,0 +1,6 @@ +export default defineAppConfig({ + ui: { + primary: 'slate', + gray: 'cool', + }, +}) diff --git a/ui/app.vue b/ui/app.vue new file mode 100644 index 00000000..cb24eaf3 --- /dev/null +++ b/ui/app.vue @@ -0,0 +1,54 @@ + + + + diff --git a/ui/components/arguments.vue b/ui/components/arguments.vue new file mode 100644 index 00000000..42e66845 --- /dev/null +++ b/ui/components/arguments.vue @@ -0,0 +1,77 @@ + + + diff --git a/ui/components/call.vue b/ui/components/call.vue new file mode 100644 index 00000000..83067e0b --- /dev/null +++ b/ui/components/call.vue @@ -0,0 +1,112 @@ + + diff --git a/ui/components/chat-input.vue b/ui/components/chat-input.vue new file mode 100644 index 00000000..b297aa6e --- /dev/null +++ b/ui/components/chat-input.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/ui/components/left-nav.vue b/ui/components/left-nav.vue new file mode 100644 index 00000000..2b9d7da6 --- /dev/null +++ b/ui/components/left-nav.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/ui/components/message.vue b/ui/components/message.vue new file mode 100644 index 00000000..574c1a02 --- /dev/null +++ b/ui/components/message.vue @@ -0,0 +1,66 @@ + + + diff --git a/ui/components/relative-date.vue b/ui/components/relative-date.vue new file mode 100644 index 00000000..5d823061 --- /dev/null +++ b/ui/components/relative-date.vue @@ -0,0 +1,41 @@ + + + diff --git a/ui/components/theme-toggle.vue b/ui/components/theme-toggle.vue new file mode 100644 index 00000000..fa6978fb --- /dev/null +++ b/ui/components/theme-toggle.vue @@ -0,0 +1,28 @@ + + + diff --git a/ui/config/server.ts b/ui/config/server.ts new file mode 100644 index 00000000..bb14bb88 --- /dev/null +++ b/ui/config/server.ts @@ -0,0 +1,10 @@ +import dotenv from 'dotenv' + +dotenv.config() + +export const api = cleanUrl(process.env.NUXT_PUBLIC_API || process.env.API || 'http://localhost:9090') +export const isDev = process.env.NODE_ENV === 'development' + +export function cleanUrl(url: string) { + return (url || '').trim().replace(/\/+$/, '') +} diff --git a/ui/config/types.d.ts b/ui/config/types.d.ts new file mode 100644 index 00000000..31bbd063 --- /dev/null +++ b/ui/config/types.d.ts @@ -0,0 +1,180 @@ +import type { Component } from 'vue' +import type { JsonDict, JsonValue } from '@/utils/object' + +declare global { + type MapBool = Record + + interface SelectOption { + label: string + value: string + } + + interface Gpt { + entryToolId: string + toolSet: Record + } + + interface Property { + type: "string" + description: string + default?: string + } + + interface ArgSchema { + type: 'object' + properties: Record + required: string[] + } + + type Args = string | Record + + interface Tool { + id: string + name?: string + description: string + arguments: ArgSchema + instructions: string + tools: string[] + toolMapping: Record + modelName: string + source: { + file: string + lineNo: number + } + } + + type State = 'creating'|'running'|'finished'|'error' + + interface Run { + id: string + state: State + calls: Call[] + err?: string + output?: string + program? : Gpt + } + + interface Call { + id: string + parentID?: string + chatCompletionId?: string + state: State + messages: ChatMessage[] + tool?: Tool + chatRequest?: JsonDict + input?: Args + output?: string + } + + interface BaseFrame { + type: string + time: string + runID: string + } + + interface RunStartFrame extends BaseFrame { + type: "runStart" + program: Gpt + } + + interface RunFinishFrame extends BaseFrame { + type: "runFinish" + input: Args + + err?: string + output?: string + } + + interface CallFrame extends BaseFrame { + callContext: Call + input: Args + } + + interface CallStartFrame extends CallFrame { + type: "callStart" + } + + interface CallChatFrame extends CallFrame { + type: "callChat" + chatCompletionId: string + chatRequest?: ChatRequest + chatResponse?: ChatMessage + chatResponseCached?: boolean + } + + interface CallProgressFrame extends CallFrame { + type: "callProgress" + chatCompletionId: string + content: string + } + + interface CallContinueFrame extends CallFrame { + type: "callContinue" + toolResults: number + } + + interface CallFinishFrame extends CallFrame { + type: "callFinish" + content: string + } + + type Frame = RunStartFrame | RunFinishFrame | CallStartFrame | CallChatFrame | CallProgressFrame | CallContinueFrame | CallFinishFrame + + interface ChatRequest { + max_tokens: number + messages: ChatMessage[] + model: string + temperature: string + tools?: ChatTool[] + } + + interface ChatText { + text: string + } + + interface ChatToolCall { + toolCall: { + id: string + index: number + type: "function" + function: { + name: string, + arguments: string + } + } + } + + interface ChatToolMessage { + role: "system"|"assistant"|"user" + content: string | (ChatToolCall|ChatText)[] + } + + interface ChatErrorMessage { + err: string + } + + interface ChatOutputMessage { + output: string + } + + type ChatMessage = ChatToolMessage | ChatOutputMessage | ChatErrorMessage + + interface ChatToolFunction { + type: "function" + function: { + name: string + description: string + parameters: { + type: "object" + properties: Record + } + } + } + + type ChatTool = ChatToolFunction + + interface ChatProperty { + type: string + description: string + } +} diff --git a/ui/eslint.config.js b/ui/eslint.config.js new file mode 100644 index 00000000..96306bc6 --- /dev/null +++ b/ui/eslint.config.js @@ -0,0 +1,140 @@ +import antfu from '@antfu/eslint-config' +import { FlatCompat } from '@eslint/eslintrc' + +const compat = new FlatCompat() + +export default antfu({ + ...compat.config({ + env: { + node: true, + commonjs: true, + browser: true, + es6: true, + }, + rules: { + 'n/prefer-global/process': 'off', + '@stylistic/ts/brace-style': 'off', + '@stylistic/js/key-spacing': 'off', + '@stylistic/js/space-in-parens': 'off', + '@stylistic/js/template-curly-spacing': 'off', + '@typescript-eslint/brace-style': ['warn', '1tbs'], + '@typescript-eslint/consistent-type-definitions': 'off', + 'array-bracket-spacing': 'warn', + 'arrow-parens': 'warn', + 'arrow-spacing': ['warn', { before: true, after: true }], + 'block-spacing': ['warn', 'always'], + 'brace-style': 'off', + 'comma-dangle': ['warn', 'only-multiline'], + 'comma-spacing': 'warn', + 'curly': ['warn', 'all'], + 'func-call-spacing': ['warn', 'never'], + 'implicit-arrow-linebreak': 'warn', + 'keyword-spacing': 'warn', + 'lines-between-class-members': ['warn', 'always', { exceptAfterSingleLine: true }], + 'multiline-ternary': ['warn', 'never'], + 'newline-per-chained-call': ['warn', { ignoreChainWithDepth: 4 }], + 'no-caller': 'warn', + 'no-cond-assign': ['warn', 'except-parens'], + 'no-console': ['warn', { allow: ['debug', 'info', 'warn', 'error'] }], + 'no-debugger': 'warn', + 'no-eq-null': 'warn', + 'no-eval': 'warn', + 'no-trailing-spaces': 'warn', + 'no-unused-vars': 'warn', + 'no-whitespace-before-property': 'warn', + 'object-curly-spacing': ['warn', 'always'], + 'object-property-newline': 'off', + 'object-shorthand': 'warn', + 'padded-blocks': ['warn', 'never'], + 'prefer-arrow-callback': 'warn', + 'prefer-template': 'warn', + 'quote-props': 'warn', + 'react/display-name': 'off', + 'react/no-unknown-property': 'off', + 'rest-spread-spacing': 'warn', + 'space-before-function-paren': 'off', + 'space-in-parens': 'off', + 'space-infix-ops': 'warn', + 'spaced-comment': 'warn', + 'switch-colon-spacing': 'warn', + 'template-curly-spacing': ['warn', 'always'], + 'yield-star-spacing': ['warn', 'both'], + + 'key-spacing': ['warn', { + align: { + beforeColon: false, + afterColon: true, + on: 'value', + mode: 'minimum', + }, + multiLine: { + beforeColon: false, + afterColon: true, + }, + }], + + 'object-curly-newline': ['warn', { + ObjectExpression: { + multiline: true, + minProperties: 4, + }, + ObjectPattern: { + multiline: true, + minProperties: 4, + }, + ImportDeclaration: { + multiline: true, + minProperties: 5, + }, + ExportDeclaration: { + multiline: true, + minProperties: 3, + }, + }], + + 'padding-line-between-statements': [ + 'warn', + { + blankLine: 'always', + prev: '*', + next: 'return', + }, + { + blankLine: 'always', + prev: 'function', + next: 'function', + }, + { + blankLine: 'always', + prev: ['const', 'let', 'var'], + next: '*', + }, + { + blankLine: 'any', + prev: ['const', 'let', 'var'], + next: ['const', 'let', 'var'], + }, + ], + + '@typescript-eslint/quotes': [ + 'warn', + 'single', + { + avoidEscape: true, + allowTemplateLiterals: true, + }, + ], + + 'quotes': [ + 'warn', + 'single', + { + avoidEscape: true, + allowTemplateLiterals: true, + }, + ], + + 'vue/component-options-name-casing': ['warn', 'kebab-case'], + }, + }), +}) diff --git a/ui/middleware/setup.global.ts b/ui/middleware/setup.global.ts new file mode 100644 index 00000000..9b2e8d65 --- /dev/null +++ b/ui/middleware/setup.global.ts @@ -0,0 +1,8 @@ +import { useContext } from '@/stores/context' + +export default defineNuxtRouteMiddleware(async (to/* , from */) => { + const sock = useSocket() + await sock.setup() + + return true +}) diff --git a/ui/nuxt.config.ts b/ui/nuxt.config.ts new file mode 100644 index 00000000..b5ac9e02 --- /dev/null +++ b/ui/nuxt.config.ts @@ -0,0 +1,54 @@ +import dotenv from 'dotenv' +import pkg from './package.json' + +dotenv.config() + +const port = 9091 + +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + app: { + baseURL: '/ui', + }, + build: { + analyze: { + filename: '.nuxt/stats/{name}.html', + template: 'treemap', + brotliSize: true, + gzipSize: true, + }, + }, + colorMode: { classSuffix: '' }, + components: true, + devServer: { + port, + }, + devtools: { enabled: true }, + modules: [ + '@nuxt/ui', + '@pinia/nuxt', + ], + nitro: { sourceMap: true }, + runtimeConfig: { + public: { + api: (process.env.NUXT_PUBLIC_API || 'http://localhost:9090/').replace(/\/+$/,'')+'/', + }, + }, + sourcemap: true, + ssr: false, + typescript: { strict: true }, + vite: { + build: { + manifest: true, + rollupOptions: { + output: { + banner: `/* GPTScript ${pkg.version} */`, + }, + }, + sourcemap: true, + ssrManifest: true, + }, + + css: { devSourcemap: true }, + }, +}) diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 00000000..0fefa18f --- /dev/null +++ b/ui/package.json @@ -0,0 +1,39 @@ +{ + "name": "gptscript-ui", + "version": "0.0.1", + "type": "module", + "private": true, + "scripts": { + "build": "./node_modules/.bin/nuxt build", + "clean": "./scripts/clean", + "dev": "./node_modules/.bin/nuxt dev --host", + "generate": "./node_modules/.bin/nuxt generate", + "info": "./node_modules/.bin/nuxt info", + "lint": "./node_modules/.bin/eslint --max-warnings 0 .", + "lint:fix": "./node_modules/.bin/eslint --fix .", + "postinstall": "./node_modules/.bin/nuxt prepare", + "preview": "./node_modules/.bin/nuxt preview", + "start": "node .output/server/index.mjs" + }, + "dependencies": { + "dayjs": "^1.11.10" + }, + "devDependencies": { + "@antfu/eslint-config": "2.6.4", + "@heroicons/vue": "^2.1.1", + "@nuxt/devtools": "1.0.8", + "@nuxt/ui": "2.13.0", + "@nuxtjs/color-mode": "^3.3.2", + "@pinia/nuxt": "^0.5.1", + "@types/lodash-es": "^4.17.12", + "@vueuse/core": "^10.7.2", + "dotenv": "^16.4.1", + "eslint": "^8.56.0", + "lodash-es": "^4.17.21", + "nuxt": "^3.10.1", + "sass": "^1.70.0", + "typescript": "^5.3.3", + "vue": "3.4.15", + "vue-router": "^4.2.5" + } +} diff --git a/ui/pages/gpt/[...gpt].vue b/ui/pages/gpt/[...gpt].vue new file mode 100644 index 00000000..fbb95e16 --- /dev/null +++ b/ui/pages/gpt/[...gpt].vue @@ -0,0 +1,123 @@ + + + diff --git a/ui/pages/index.vue b/ui/pages/index.vue new file mode 100644 index 00000000..2a51b1ea --- /dev/null +++ b/ui/pages/index.vue @@ -0,0 +1,7 @@ + diff --git a/ui/pages/run/[run].vue b/ui/pages/run/[run].vue new file mode 100644 index 00000000..2f1dfd11 --- /dev/null +++ b/ui/pages/run/[run].vue @@ -0,0 +1,115 @@ + + + diff --git a/ui/plugins/dayjs.ts b/ui/plugins/dayjs.ts new file mode 100644 index 00000000..900ef3b7 --- /dev/null +++ b/ui/plugins/dayjs.ts @@ -0,0 +1,10 @@ +import dayjs from 'dayjs' +import utc from 'dayjs/plugin/utc' +import timezone from 'dayjs/plugin/timezone' +import isToday from 'dayjs/plugin/isToday' + +export default defineNuxtPlugin(() => { + dayjs.extend(utc) + dayjs.extend(timezone) + dayjs.extend(isToday) +}) diff --git a/ui/plugins/lookup.ts b/ui/plugins/lookup.ts new file mode 100644 index 00000000..59b91068 --- /dev/null +++ b/ui/plugins/lookup.ts @@ -0,0 +1,33 @@ +import { useContext } from '@/stores/context' +import { addObject } from '@/utils/array' +import { get, set } from '@/utils/object' + +export default defineNuxtPlugin(({ $pinia }) => { + const w: any = window + const ctx = useContext($pinia) + + w.ctx = ctx + w.gpts = useGpts($pinia) + w.runs = useRuns($pinia) + w.socket = useSocket($pinia) + w.prefs = usePrefs($pinia) + + w.get = get + w.set = set + w.ref = ref + w.computed = computed + w.reactive = reactive + w.watchEffect = watchEffect + w.addObject = addObject + w.route = useRoute() + w.router = useRouter() + + console.info('# Welcome to warp zone') + + return { + provide: { + get, + set, + }, + } +}) diff --git a/ui/public/favicon.ico b/ui/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..18993ad91cfd43e03b074dd0b5cc3f37ab38e49c GIT binary patch literal 4286 zcmeHLOKuuL5PjK%MHWVi6lD zOGiREbCw`xmFozJ^aNatJY>w+g ze6a2@u~m#^BZm@8wco9#Crlli0uLb^3E$t2-WIc^#(?t)*@`UpuofJ(Uyh@F>b3Ph z$D^m8Xq~pTkGJ4Q`Q2)te3mgkWYZ^Ijq|hkiP^9`De={bQQ%heZC$QU2UpP(-tbl8 zPWD2abEew;oat@w`uP3J^YpsgT%~jT(Dk%oU}sa$7|n6hBjDj`+I;RX(>)%lm_7N{+B7Mu%H?422lE%MBJH!!YTN2oT7xr>>N-8OF$C&qU^ z>vLsa{$0X%q1fjOe3P1mCv#lN{xQ4_*HCSAZjTb1`}mlc+9rl8$B3OP%VT@mch_~G z7Y+4b{r>9e=M+7vSI;BgB?ryZDY4m>&wcHSn81VH1N~`0gvwH{ z8dv#hG|OK`>1;j7tM#B)Z7zDN?{6=dUal}$e { + return { + mgmtSetup: false, + } + }, + + getters: { + baseUrl: () => { + let base = '' + + if ( process.server ) { + const headers = useRequestHeaders() + + base = `http://${ headers.host }` + } + + base += '/v1' + + return base + }, + }, + + actions: { + async setupMgmt() { + if ( this.mgmtSetup ) { + return + } + + this.mgmtSetup = true + }, + } +}) diff --git a/ui/stores/gpts.ts b/ui/stores/gpts.ts new file mode 100644 index 00000000..809290aa --- /dev/null +++ b/ui/stores/gpts.ts @@ -0,0 +1,34 @@ +import { defineStore } from 'pinia' + +export const useGpts = defineStore('gpts', { + state: () => { + return { + list: [] as Gpt[], + map: {} as Record + } + }, + + getters: { + }, + + actions: { + async find(id: string) { + if ( this.map[id] ) { + return this.map[id] + } + + const url = useRuntimeConfig().public.api + id + const data = reactive(await $fetch(url)) + + this.list.push(data) + this.map[id] = data + return data + }, + + async listAll() { + const url = useRuntimeConfig().public.api + const { data } = (await useFetch(url) as any as {data: Ref}) + return data + } + } +}) diff --git a/ui/stores/prefs.ts b/ui/stores/prefs.ts new file mode 100644 index 00000000..d852b43f --- /dev/null +++ b/ui/stores/prefs.ts @@ -0,0 +1,61 @@ +import { defineStore } from 'pinia' +import { useStorage, type RemovableRef } from '@vueuse/core' + +const prefix='gptscript-' + +export const usePrefs = defineStore('prefs', { + state: () => { + return { + debug: useStorage(`${prefix}debug`, false) as RemovableRef, + cache: useStorage(`${prefix}cache`, true) as RemovableRef, + expanded: {}, + nextCall: 1, + callMap: {} as Record, + allExpanded: useStorage(`${prefix}expand-all`, false) as RemovableRef, + } + }, + + getters: {}, + actions: { + expand(id: string) { + this.expanded[id] = true + }, + + collapse(id: string) { + this.expanded[id] = false + this.allExpanded = false + }, + + expandAll(keys: string[]=[]) { + this.allExpanded = true + this.expanded = {} + if ( keys.length ) { + for ( const k of keys ) { + this.expanded[k] = true + } + } + }, + + collapseAll() { + this.allExpanded = false + this.expanded = {} + }, + + toggleAll() { + if ( this.allExpanded ) { + this.collapseAll() + } else { + this.expandAll() + } + }, + + mapCall(id: string) { + if ( !this.callMap[id] ) { + const k = 'c_' + this.nextCall++ + this.callMap[id] = k + } + + return this.callMap[id] + } + }, +}) diff --git a/ui/stores/runs.ts b/ui/stores/runs.ts new file mode 100644 index 00000000..f72169a5 --- /dev/null +++ b/ui/stores/runs.ts @@ -0,0 +1,59 @@ +import type { JsonDict } from '@/utils/object' +import { defineStore } from 'pinia' + +export const useRuns = defineStore('runs', { + state: () => { + return { + list: reactive([]), + map: {} as Record + } + }, + + getters: { + }, + + actions: { + async find(id: string) { + if ( this.map[id] ) { + return this.map[id] + } + + // const url = useRuntimeConfig().public.api + // const { data } = (await useFetch(url+id) as any as {data: Ref}) + + // this.list.push(data) + // this.map[id] = data + // return data + }, + + async findAll() { + return this.list + }, + + async create(fileName: string, toolName: string, args: any, cache=true): Promise { + let url = useRuntimeConfig().public.api + fileName.split('/').map(x => encodeURIComponent(x)).join('/') + '?async' + + if ( !cache ) { + url = addParam(url, 'nocache', null) + } + + if ( toolName ) { + url = addParam(url, 'tool', toolName) + } + + const res = await $fetch(url, {method: 'POST', body: args}) as {id: string} + const id = res.id + + const obj: Run = reactive({ + id, + state: 'creating', + calls: [] + }) + + this.list.push(obj) + this.map[id] = obj + console.log('Created', id) + return obj + } + } +}) diff --git a/ui/stores/socket.ts b/ui/stores/socket.ts new file mode 100644 index 00000000..0d375f23 --- /dev/null +++ b/ui/stores/socket.ts @@ -0,0 +1,139 @@ +import { useWebSocket, type UseWebSocketReturn, type WebSocketStatus } from '@vueuse/core' +import { defineStore } from 'pinia' + +interface SocketState { + url: string + interval: number + isSetup: boolean + queue: Frame[] + timer?: NodeJS.Timeout + sock: UseWebSocketReturn +} + +export const useSocket = defineStore('socket', { + state: () => { + const url = useRuntimeConfig().public.api.replace(/^http/,'ws') + const sock = useWebSocket(url, { + immediate: false, + autoReconnect: true, + }) + + return { + url, + interval: 250, + isSetup: false, + queue: [], + timer: undefined, + sock + } as SocketState + }, + + actions: { + async setup() { + if ( this.isSetup ) { + return + } + + this.isSetup = true + + watch(() => this.sock.data, async (raw: string) => { + const msg = JSON.parse(raw) as Frame + this.queue.push(msg) + }) + + this.flush() + this.sock.open() + }, + + flush() { + if ( this.queue.length ) { + const q = this.queue.splice(0, this.queue.length) + + nextTick(() => { + for (const msg of q ) { + this.handle(msg) + } + }) + } + + this.timer = setTimeout(() => { + this.flush() + }, this.interval) + }, + + async handle(f: Frame) { + const runs = useRuns() + const run = await runs.find(f.runID) + + if (!run ) { + console.error('Frame received for unknown run', f.runID, f) + return + } + + if (!run.state ) { + run.state = 'creating' + } + + if ( f.type === 'runStart' ) { + run.state = 'running' + if ( f.program ) { + run.program = f.program + } + } else if ( f.type === 'runFinish' ) { + if ( f.err ) { + run.state = 'error' + run.err = f.err + } else { + run.state = 'finished' + run.output = f.output || '' + } + } else if ( f.type.startsWith('call') ) { + let call = run.calls.find(x => x.id === f.callContext.id) + + if ( !call ) { + call = { + id: f.callContext.id, + parentID: f.callContext.parentID, + tool: f.callContext.tool, + messages: [], + state: 'running', + chatCompletionId: f.callContext.chatCompletionId, + chatRequest: f.callContext.chatRequest + } + + run.calls.push(call) + } + + console.log('Call frame', call) + + if ( f.type === 'callStart' ) { + call.state = 'creating' + call.input = f.input || '' + } else if ( f.type === 'callChat' ) { + call.state = 'running' + + if ( f.chatRequest ) { + const more = (f.chatRequest.messages || []).slice(call.messages.length) + call.messages.push(...more) + } + + if ( f.chatResponse ) { + call.messages.push(f.chatResponse) + } + } else if ( f.type === 'callContinue' ) { + call.state = 'running' + } else if ( f.type === 'callProgress' ) { + call.state = 'running' + + if ( typeof f.content === 'string' ) { + call.output = f.content + } + + } else if ( f.type === 'callFinish' ) { + call.state = 'finished' + call.output = f.content + } + } + } + } +}) diff --git a/ui/styles/_base.scss b/ui/styles/_base.scss new file mode 100644 index 00000000..5630f79d --- /dev/null +++ b/ui/styles/_base.scss @@ -0,0 +1,9 @@ +.clearfix { + overflow: auto; + + &::after { + content: ''; + clear: both; + display: table; + } +} diff --git a/ui/styles/app.scss b/ui/styles/app.scss new file mode 100644 index 00000000..079e71b0 --- /dev/null +++ b/ui/styles/app.scss @@ -0,0 +1 @@ +@import "./base"; diff --git a/ui/tailwind.config.ts b/ui/tailwind.config.ts new file mode 100644 index 00000000..e3ce45aa --- /dev/null +++ b/ui/tailwind.config.ts @@ -0,0 +1,26 @@ +import type { Config } from 'tailwindcss' + +// import colors from 'tailwindcss/colors' + +export default > { + darkMode: 'class', + theme: { + extend: { + colors: { + // 'gpt': { + // '50': '#f6f6f6', + // '100': '#e7e7e7', + // '200': '#d1d1d1', + // '300': '#b0b0b0', + // '400': '#888888', + // '500': '#6d6d6d', + // '600': '#5d5d5d', + // '700': '#4f4f4f', + // '800': '#454545', + // '900': '#1d1d1d', + // '950': '#080808', + // }, + }, + }, + }, +} diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 00000000..f2fb10e7 --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,17 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json", + + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "baseUrl": ".", + "paths": { + "@/*": ["./*"], + }, + "types": [ + ], + "sourceMap": true, + "allowSyntheticDefaultImports": true + } +} diff --git a/ui/utils/array.ts b/ui/utils/array.ts new file mode 100644 index 00000000..8fab566a --- /dev/null +++ b/ui/utils/array.ts @@ -0,0 +1,176 @@ +// Portions Copyright (c) 2014-2021 Rancher Labs, Inc. https://github.com/rancher/dashboard +// Portions Copyright (c) 2020 Yehuda Katz, Tom Dale and Ember.js contributors + +import xor from 'lodash-es/xor.js' +import _isArray from 'lodash-es/isArray.js' +import { get } from './object' +import type { JsonDict, JsonValue } from './object' + +export function isArray(ary: any): boolean { + return _isArray(ary) +} + +export function removeObject(ary: T[], obj: T): T[] { + const idx = ary.indexOf(obj) + + if (idx >= 0) { + ary.splice(idx, 1) + } + + return ary +} + +export function removeObjects(ary: T[], objs: T[]): T[] { + let i + let indexes = [] + + for (i = 0; i < objs.length; i++) { + let idx = ary.indexOf(objs[i]) + + // Find multiple copies of the same value + while (idx !== -1) { + indexes.push(idx) + idx = ary.indexOf(objs[i], idx + 1) + } + } + + if (!indexes.length) { + // That was easy... + return ary + } + + indexes = indexes.sort((a, b) => a - b) + + const ranges = [] + let first: number, last: number + + // Group all the indexes into contiguous ranges + while (indexes.length) { + first = indexes.shift() + last = first + + while (indexes.length && indexes[0] === last + 1) { + last = indexes.shift() + } + + ranges.push({ start: first, end: last }) + } + + // Remove the items by range + for (i = ranges.length - 1; i >= 0; i--) { + const { start, end } = ranges[i] + + ary.splice(start, end - start + 1) + } + + return ary +} + +export function addObject(ary: T[], obj: T): void { + const idx = ary.indexOf(obj) + + if (idx === -1) { + ary.push(obj) + } +} + +export function addObjects(ary: T[], objs: T[]): void { + const unique: any[] = [] + + for (const obj of objs) { + if (!ary.includes(obj) && !unique.includes(obj)) { + unique.push(obj) + } + } + + ary.push(...unique) +} + +export function insertAt(ary: T[], idx: number, ...objs: T[]): void { + ary.splice(idx, 0, ...objs) +} + +export function removeAt(ary: T[], idx: number, len = 1): void { + if (idx < 0) { + throw new Error('Index too low') + } + + if (idx + len > ary.length) { + throw new Error('Index + length too high') + } + + ary.splice(idx, len) + + return ary +} + +export function clear(ary: T[]) { + ary.splice(0, ary.length) +} + +export function replaceWith(ary: T[], ...objs: T[]) { + ary.splice(0, ary.length, ...objs) +} + +function findOrFilterBy(method: 'find' | 'filter', ary: null | any[], keyOrObj: string | JsonDict, val?: JsonValue): any { + ary = ary || [] + + if (typeof keyOrObj === 'object') { + return ary[method]((item) => { + for (const path in keyOrObj) { + const want = keyOrObj[path] + const have = get(item, path) + + if (typeof want === 'undefined') { + if (!have) { + return false + } + } else if (have !== want) { + return false + } + } + + return true + }) + } else if (val === undefined) { + return ary[method](item => !!get(item, keyOrObj)) + } else { + return ary[method](item => get(item, keyOrObj) === val) + } +} + +export function filterBy(ary: null | any[], keyOrObj: string | JsonDict, val?: JsonValue): any[] { + return findOrFilterBy('filter', ary, keyOrObj, val) +} + +export function findBy(ary: null | any[], keyOrObj: string | JsonDict, val?: JsonValue): any { + return findOrFilterBy('find', ary, keyOrObj, val) +} + +export function sameContents(a: any[], b: any[]) { + return xor(a, b).length === 0 +} + +export function uniq(ary: any[]) { + const out: any[] = [] + + addObjects(out, ary) + + return out +} + +export function toArray(arg: T | T[]): T[] { + if ( isArray(arg) ) { + return arg as T[] + } else { + return [arg as T] + } +} + +export function fromArray(arg: T | T[] | undefined, def?: T): T { + if ( isArray(arg) ) { + return (arg as T[])[0] || (def as T) + } else { + return (arg as T) || (def as T) + } +} diff --git a/ui/utils/object.ts b/ui/utils/object.ts new file mode 100644 index 00000000..ccc2c0fe --- /dev/null +++ b/ui/utils/object.ts @@ -0,0 +1,141 @@ +// Portions Copyright (c) 2014-2021 Rancher Labs, Inc. https://github.com/rancher/dashboard + +// import { JSONPath } from 'jsonpath-plus'; +import cloneDeep from 'lodash-es/cloneDeep.js' +import difference from 'lodash-es/difference.js' +import flattenDeep from 'lodash-es/flattenDeep.js' +import compact from 'lodash-es/compact.js' +import transform from 'lodash-es/transform.js' +import isEqual from 'lodash-es/isEqual.js' +import isObject from 'lodash-es/isObject.js' +import isEmpty from 'lodash-es/isEmpty.js' +import { addObject, isArray } from './array' +import { appendObjectPath, isNumeric, joinObjectPath, splitObjectPath } from './string' + +export type JsonValue = null | undefined | string | number | boolean | JsonArray | JsonDict | object +export type JsonArray = JsonValue[] +export interface JsonDict extends Record { } + +type Change = { + path: string + op: string + from: JsonValue + value: JsonValue +} +interface ChangeSet extends Record {} + +export function set(obj: JsonDict | null, path: string, value: any): any { + let ptr: any = obj + + if (!ptr) { + return + } + + const parts = splitObjectPath(path) + + for (let i = 0; i < parts.length; i++) { + const key = parts[i] + + if (i === parts.length - 1) { + // Vue.set(ptr, key, value) + ptr[key] = value + } else if (!ptr[key]) { + // Make sure parent keys exist + // Vue.set(ptr, key, {}) + if ( isNumeric(parts[i + 1]) ) { + ptr[key] = [] + } else { + ptr[key] = {} + } + } + + ptr = ptr[key] + } + + return obj +} + +export function get(obj: JsonDict | object | null, path: string): any { + /* + if (path.startsWith('$')) { + try { + return JSONPath({ + path, + json: obj, + wrap: false, + }) + } catch (e) { + console.error('JSON Path error', e, path, obj) // eslint-disable-line no-console + + return '(JSON Path err)' + } + } + */ + + if ( !obj ) { + throw new Error('Missing object') + } + + if (!path.includes('.')) { + return (obj as any)[path] + } + + const parts = splitObjectPath(path) + let ptr = obj as JsonValue + + for (let i = 0; i < parts.length; i++) { + if (!ptr) { + return + } + + ptr = (ptr as any)[parts[i]] + } + + return ptr +} + +export function getter(path: string) { + return function (obj: JsonDict) { + return get(obj, path) + } +} + +export function remove(obj: JsonDict, path: string): JsonDict { + const parentAry = splitObjectPath(path) + const leafKey = parentAry.pop() as string + let parent + + if ( parentAry.length ) { + parent = get(obj, joinObjectPath(parentAry)) + } else { + parent = obj + } + + if (parent) { + // Vue.set(parent, leafKey, undefined) + parent[leafKey] = undefined + delete parent[leafKey] + } + + return obj +} + +export function clone(obj: T): T { + return cloneDeep(obj) +} + +export function definedKeys(obj: JsonDict): string[] { + const keys = Object.keys(obj).map((key) => { + const val = obj[key] + + if ( Array.isArray(val) ) { + return key + } else if ( isObject(val) ) { + return definedKeys(val).map(subkey => appendObjectPath(key, subkey)) + } else { + return key + } + }) + + return compact(flattenDeep(keys)) +} diff --git a/ui/utils/platform.ts b/ui/utils/platform.ts new file mode 100644 index 00000000..5b6c9cd6 --- /dev/null +++ b/ui/utils/platform.ts @@ -0,0 +1,66 @@ +// Portions Copyright (c) 2014-2021 Rancher Labs, Inc. https://github.com/rancher/dashboard + +export const platform = ( typeof window === 'undefined' ? 'server' : window.navigator.platform.toLowerCase() ) +export const userAgent = ( typeof window === 'undefined' ? 'server' : window.navigator.userAgent ) + +export const isLinuxy = platform.includes('linux') || platform.includes('unix') +export const isMac = platform.includes('mac') +export const isWin = platform.includes('win') + +export const alternateKey = (isMac ? 'metaKey' : 'ctrlKey') +export const alternateLabel = (isMac ? 'Command' : 'Control') + +export const moreKey = alternateKey +export const moreLabel = alternateLabel + +export const rangeKey = 'shiftKey' +export const rangeLabel = 'Shift' + +export function isAlternate(event: KeyboardEvent | MouseEvent) { + return !!event[alternateKey] +} + +export function isMore(event: KeyboardEvent | MouseEvent) { + return !!event[moreKey] +} + +export function isRange(event: KeyboardEvent | MouseEvent) { + return !!event[rangeKey] +} + +export function suppressContextMenu(event: MouseEvent) { + return event.ctrlKey && event.button === 2 +} + +// Only intended to work for Mobile Safari at the moment... +export function version() { + const match = userAgent.match(/\s+Version\/([0-9.]+)/) + + if ( match ) { + return Number.parseFloat(match[1]) + } + + return null +} + +export const isGecko = userAgent.includes('Gecko/') +export const isBlink = userAgent.includes('Chrome/') +export const isWebKit = !isBlink && userAgent.includes('AppleWebKit/') +export const isSafari = !isBlink && userAgent.includes('Safari/') +export const isMobile = /Android|webOS|iPhone|iPad|iPod|IEMobile/i.test(userAgent) + +export const KEY = { + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40, + ESCAPE: 27, + CR: 13, + LF: 10, + TAB: 9, + SPACE: 32, + PAGE_UP: 33, + PAGE_DOWN: 34, + HOME: 35, + END: 36, +} diff --git a/ui/utils/promise.ts b/ui/utils/promise.ts new file mode 100644 index 00000000..5fa99e16 --- /dev/null +++ b/ui/utils/promise.ts @@ -0,0 +1,7 @@ +export async function usleep(delay: number) { + return new Promise((resolve) => { + setTimeout(() => { + resolve(true) + }, delay) + }) +} diff --git a/ui/utils/sort.ts b/ui/utils/sort.ts new file mode 100644 index 00000000..c4470480 --- /dev/null +++ b/ui/utils/sort.ts @@ -0,0 +1,292 @@ +import type { JsonDict } from './object' +import { get } from './object' +import { strPad } from './string' + +// Based on https://github.com/emberjs/ember.js/blob/master/packages/@ember/-internals/runtime/lib/type-of.js +// and https://github.com/emberjs/ember.js/blob/master/packages/@ember/-internals/runtime/lib/mixins/array.js +/* +Copyright (c) 2019 Yehuda Katz, Tom Dale and Ember.js contributors + +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. +*/ + +// ........................................ +// TYPING & ARRAY MESSAGING +// +const TYPE_MAP = { + '[object Boolean]': 'boolean', + '[object Number]': 'number', + '[object String]': 'string', + '[object Function]': 'function', + '[object Array]': 'array', + '[object Date]': 'date', + '[object RegExp]': 'regexp', + '[object Object]': 'object', + '[object FileList]': 'filelist', +} + +const { toString } = Object.prototype + +const TYPE_ORDER = { + undefined: 0, + null: 1, + boolean: 2, + number: 3, + string: 4, + array: 5, + object: 6, + instance: 7, + function: 8, + class: 9, + date: 10, +} + +/* + Returns a consistent type for the passed object. + + Use this instead of the built-in `typeof` to get the type of an item. + It will return the same result across all browsers and includes a bit + more detail. Here is what will be returned: + + | Return Value | Meaning | + |---------------|------------------------------------------------------| + | 'string' | String primitive or String object. | + | 'number' | Number primitive or Number object. | + | 'boolean' | Boolean primitive or Boolean object. | + | 'null' | Null value | + | 'undefined' | Undefined value | + | 'function' | A function | + | 'array' | An instance of Array | + | 'regexp' | An instance of RegExp | + | 'date' | An instance of Date | + | 'filelist' | An instance of FileList | + | 'error' | An instance of the Error object | + | 'object' | A JavaScript object | + + Examples: + + import { typeOf } from '@/utils/type-of'; + + typeOf(); // 'undefined' + typeOf(null); // 'null' + typeOf(undefined); // 'undefined' + typeOf('michael'); // 'string' + typeOf(new String('michael')); // 'string' + typeOf(101); // 'number' + typeOf(new Number(101)); // 'number' + typeOf(true); // 'boolean' + typeOf(new Boolean(true)); // 'boolean' + typeOf(A); // 'function' + typeOf([1, 2, 90]); // 'array' + typeOf(/abc/); // 'regexp' + typeOf(new Date()); // 'date' + typeOf(event.target.files); // 'filelist' + typeOf(new Error('teamocil')); // 'error' + + // 'normal' JavaScript object + typeOf({ a: 'b' }); // 'object' +*/ +export function typeOf(item: any): string { + if (item === null) { + return 'null' + } + if (item === undefined) { + return 'undefined' + } + let ret = TYPE_MAP[toString.call(item)] || 'object' + + if (ret === 'object') { + if (item instanceof Error) { + ret = 'error' + } else if (item instanceof Date) { + ret = 'date' + } + } + + return ret +} + +function spaceship(a: any, b: any): number { + const diff: number = a - b + + return (diff > 0 ? 1 : 0) - (diff < 0 ? 1 : 0) +} + +function compare(a: any, b: any): number { + const typeA = typeOf(a) + const typeB = typeOf(b) + + const res = spaceship(TYPE_ORDER[typeA], TYPE_ORDER[typeB]) + + if ( res ) { + return res + } + + switch (typeA) { + case 'boolean': + case 'number': + return spaceship(a, b) + + case 'string': + return spaceship(a.localeCompare(b), 0) + + case 'array': { + const aLen = a.length + const bLen = b.length + const len = Math.min(aLen, bLen) + + for (let i = 0; i < len; i++) { + const r = compare(a[i], b[i]) + + if (r !== 0) { + return r + } + } + + // all elements are equal now + // shorter array should be ordered first + return spaceship(aLen, bLen) + } + case 'date': + return spaceship(a.getTime(), b.getTime()) + } + + return 0 +} + +interface ISortOpt { + field: string + reverse: boolean +} + +export function parseField(str: string): ISortOpt { + const parts = str.split(/:/) + + if ( parts.length === 2 && parts[1] === 'desc' ) { + return { field: parts[0], reverse: true } + } else { + return { field: str, reverse: false } + } +} + +export function sortBy(ary: T[], keys: string | string[], desc?: boolean): T[] { + if ( !Array.isArray(keys) ) { + keys = [keys] + } + + return ary.slice().sort((objA, objB) => { + for ( let i = 0; i < keys.length; i++ ) { + const parsed = parseField(keys[i]) + const a = get(objA as JsonDict, parsed.field) + const b = get(objB as JsonDict, parsed.field) + let res = compare(a, b) + + if ( res ) { + if ( desc ) { + res *= -1 + } + + if ( parsed.reverse ) { + res *= -1 + } + + return res + } + } + + return 0 + }) +} + +// Turn foo1-bar2 into foo0000000001-bar0000000002 so that the numbers sort numerically +const splitRegex = /([^\d]+)/ +const notNumericRegex = /^[0-9]+$/ + +export function sortableNumericSuffix(str: string): string { + if ( typeof str !== 'string' ) { + return str + } + + return str.split(splitRegex).map(x => x.match(notNumericRegex) ? strPad(x, 10, '0') : x).join('').trim() +} + +interface FieldSpec { + field: string + modifier: string +} + +export function search(ary: T[], query: string, keys: string | string[]): T[] { + query = (query || '').trim().toLowerCase() + const tokens = query.split(/\s*[, ]\s*/) + + if ( !Array.isArray(keys) ) { + keys = [keys] + } + + const fields = keys.map((field) => { + let modifier = '' + + if ( field.includes(':') ) { + const idx = field.indexOf(':') + + field = field.substring(0, idx) + modifier = field.substring(idx + 1) + } + + return { + field, + modifier, + } as FieldSpec + }) + + const out: T[] = [] + + for ( const row of ary ) { + let rowMatches = false + + for ( const token of tokens ) { + let tokenMatches = false + + for ( const spec of fields ) { + const val = `${ get(row as object, spec.field) }`.toLowerCase() + + if ( spec.modifier === 'exact' ) { + tokenMatches = val === token + } else { + tokenMatches = val.includes(token) + } + + if ( tokenMatches ) { + break + } + } + + if ( tokenMatches ) { + rowMatches = true + break + } + } + + if (rowMatches ) { + out.push(row) + } + } + + return out +} diff --git a/ui/utils/state.ts b/ui/utils/state.ts new file mode 100644 index 00000000..ac0ee366 --- /dev/null +++ b/ui/utils/state.ts @@ -0,0 +1,39 @@ +export function iconForState(state: string) { + switch (state) { + case 'creating': + return 'i-heroicons-clock' + case 'running': + return 'i-heroicons-cog animate-spin' + case 'finished': + return 'i-heroicons-beaker' + case 'error': + default: + return 'i-heroicons-exclamation-triangle' + } +} + +export function colorForState(state: string, prefix='', brightness: number|boolean = false) { + let out = prefix ? `${prefix}-` : '' + + switch (state) { + case 'creating': + case 'running': + out += 'blue' + break + case 'finished': + out += 'green' + break + case 'error': + default: + out += 'red' + break + } + + if ( brightness === true ) { + out += '-500' + } else if ( brightness ) { + out += `${brightness}` + } + + return out +} diff --git a/ui/utils/string.ts b/ui/utils/string.ts new file mode 100644 index 00000000..93e34d18 --- /dev/null +++ b/ui/utils/string.ts @@ -0,0 +1,397 @@ +// Portions Copyright (c) 2014-2021 Rancher Labs, Inc. https://github.com/rancher/dashboard +import crypto from 'node:crypto' +import escapeRegExp from 'lodash-es/escapeRegExp.js' +import isNaN from 'lodash-es/isNaN.js' + +const camelizeRegex = /[ _-]/ +const decamelizeRegex = /([a-z\d])([A-Z])/g +const dasherizeRegex = /[ _]/g +const quotedMatch = /[^."']+|"([^"]*)"|'([^']*)'/g + +const entityMap: Record = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''', + '/': '/', +} + +const alpha = 'abcdefghijklmnopqrstuvwxyz' +const num = '0123456789' +const sym = '!@#$%^&*()_+-=[]{};:,./<>?|' + +export const Charsets = { + NUMERIC: num, + NO_VOWELS: 'bcdfghjklmnpqrstvwxz2456789', + ALPHA: alpha + alpha.toUpperCase(), + ALPHA_NUM: alpha + alpha.toUpperCase() + num, + ALPHA_NUM_LOWER: alpha + num, + ALPHA_LOWER: alpha, + ALPHA_UPPER: alpha.toUpperCase(), + HEX: `${ num }ABCDEF`, + PASSWORD: alpha + alpha.toUpperCase() + num + alpha + alpha.toUpperCase() + num + sym, + // ^-- includes alpha / ALPHA / num twice to reduce the occurrence of symbols +} + +export function appendObjectPath(path: string, key: string) { + let out: string + + if ( key.includes('.') ) { + out = `${ path }."${ key }"` + } else { + out = `${ path }.${ key }` + } + + if ( out.startsWith('.') ) { + out = out.substring(1) + } + + return out +} + +export function asciiLike(str: string): boolean { + if ( str.match(/[^\r\n\t\x20-\x7F]/) ) { + return false + } + + return true +} + +export function titleCase(str: string): string { + return dasherize(str).split('-').map(str => ucFirst(str)).join(' ') +} + +export function toSnakeCase(str: string): string { + return dasherize(str).split('-').map((str) => { + return str.toUpperCase() + }).join('_') +} + +export function coerceToType(val: string, type: 'float' | 'int' | 'boolean'): number | boolean | null { + if ( type === 'float' ) { + // Coerce strings to floats + return Number.parseFloat(val) || null // NaN becomes null + } else if ( type === 'int' ) { + // Coerce strings to ints + const out = Number.parseInt(val, 10) + + if ( isNaN(out) ) { + return null + } + + return out + } else if ( type === 'boolean') { + // Coerce strings to boolean + if (val.toLowerCase() === 'true') { + return true + } else if (val.toLowerCase() === 'false') { + return false + } + } + + return null +} + +export function camelize(str: string): string { + return str.split(camelizeRegex).map((x, i) => i === 0 ? lcFirst(x) : ucFirst(x)).join('') +} + +export function dasherize(str: string): string { + return decamelize(str).replace(dasherizeRegex, '-') +} + +export function decamelize(str: string): string { + return str.replace(decamelizeRegex, '$1_$2').toLowerCase() +} + +export function ensureRegex(strOrRegex: string | RegExp, exact = true, insensitive = true): RegExp { + if ( typeof strOrRegex === 'string' ) { + if ( exact ) { + return new RegExp(`^${ escapeRegex(strOrRegex) }$`, insensitive ? 'i' : '') + } else { + return new RegExp(`${ escapeRegex(strOrRegex) }`, insensitive ? 'i' : '') + } + } + + return strOrRegex +} + +export function searchToRegex(str: string): RegExp { + const match = str.match(/^\/(\^)?(.*?)(\$)?\/([a-zA-Z]+)?$/) + const hasUpper = !!str.match(/[A-Z]/) + + if ( match ) { + // [maybe ^ ] [before] [actual match] [after] [maybe $] + const re = `${ match[1] || '' }(.*?)(${ match[2] || '' })(.*?)${ match[3] || '' }` + + return new RegExp(re, match[4] || '') + } + + // (before)(match)(after) + return new RegExp(`^(.*)(${ escapeRegExp(str) })(.*)$`, hasUpper ? '' : 'i') +} + +export function escapeHtml(html: string): string { + return String(html).replace(/[&<>"'\/]/g, (s) => { + return entityMap[s] + }) +} + +export function escapeRegex(string: string): string { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string +} + +export function formatPercent(value: number, maxPrecision = 2): string { + if (value < 1 && maxPrecision >= 2) { + return `${ Math.round(value * 100) / 100 }%` + } else if (value < 10 && maxPrecision >= 1) { + return `${ Math.round(value * 10) / 10 }%` + } else { + return `${ Math.round(value) }%` + } +} + +export function indent(lines: string | string[], count = 2, token = ' ', afterRegex?: RegExp): string { + if (typeof lines === 'string') { + lines = lines.split(/\n/) + } + + const padStr = (Array.from({ length: count + 1 })).join(token) + + const out = lines.map((line: string) => { + let prefix = '' + let suffix = line + + if (afterRegex) { + const match = line.match(afterRegex) + + if (match) { + prefix = match[match.length - 1] + suffix = line.substring(match[0].length) + } + } + + return `${ prefix }${ padStr }${ suffix }` + }) + + const str = out.join('\n') + + return str +} + +export function isIpv4(ip: string): boolean { + const reg = /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/ + + return reg.test(ip) +} + +export function joinObjectPath(ary: string[]): string { + let out = '' + + for ( const p of ary ) { + out = appendObjectPath(out, p) + } + + return out +} + +export function lcFirst(str: string): string { + return str.substring(0, 1).toLowerCase() + str.substring(1) +} + +export function matchesSomeRegex(str: string, regexes: (string | RegExp)[] = []): boolean { + return regexes.some((regexRaw: string | RegExp) => { + const regex = ensureRegex(regexRaw) + + return str.match(regex) + }) +} + +export function nlToBr(value: string): string { + return escapeHtml(value).replace(/(\r\n|\r|\n)/g, '
\n') +} + +export function pluralize(str: string): string { + if ( str.match(/.*[^aeiou]y$/i) ) { + return `${ str.substring(0, str.length - 1) }ies` + } else if ( str.endsWith('s') ) { + return `${ str }es` + } else { + return `${ str }s` + } +} + +export function random32s(count: number): number[] { + if ( count <= 0 ) { + throw new Error("Can't generate a negative number of numbers") + } + + if ( Math.floor(count) !== count ) { + throw new Error('Count should be an integer') + } + + const out = [] + let i: number + + if ( process.server || typeof window === 'undefined' ) { + for ( i = 0; i < count; i++ ) { + out[i] = crypto.randomBytes(4).readUInt32BE(0) + } + } else if (window.crypto && window.crypto.getRandomValues) { + const tmp = new Uint32Array(count) + + window.crypto.getRandomValues(tmp) + for (i = 0; i < tmp.length; i++) { + out[i] = Math.round(tmp[i]) + } + } else { + for (i = 0; i < count; i++) { + out[i] = Math.round(Math.random() * 4294967296) // Math.pow(2,32); + } + } + + return out +} + +export function random32(): number { + return random32s(1)[0] +} + +export function randomStr(length = 16, chars = Charsets.ALPHA_NUM): string { + if (!chars.length) { + throw new Error('Charset is empty') + } + + return random32s(length).map((val) => { + return chars[val % chars.length] + }).join('') +} + +export function repeat(str: string, count: number) { + return Array(count + 1).join(str) +} + +export function splitLimit(str: string, separator: string, limit: number): string[] { + const split = str.split(separator) + + if ( split.length < limit ) { + return split + } + + return [...split.slice(0, limit - 1), split.slice(limit - 1).join(separator)] +} + +export function splitObjectPath(path: string): string[] { + if ( path.includes('"') || path.includes('\'') ) { + // Path with quoted section + const matches = path.match(quotedMatch) + + if ( matches?.length ) { + return matches.map(x => x.replace(/['"]/g, '')) + } + } + + // Regular path + return path.split('.') +} + +export function strPad(str: string, toLength: number, padChars = ' ', right = false): string { + if (str.length >= toLength) { + return str + } + + const neededLen = toLength - str.length + 1 + const padStr = (Array.from({ length: neededLen })).join(padChars).substring(0, neededLen) + + if (right) { + return str + padStr + } else { + return padStr + str + } +} + +export function ucFirst(str: string): string { + return str.substring(0, 1).toUpperCase() + str.substring(1) +} + +export function trim(str: string, direction: 'left' | 'right' | 'both' = 'both', chars = ' \n\r') { + if ( direction === 'left' || direction === 'both' ) { + const re = new RegExp(`^[${ escapeRegExp(chars) }]+`, 'g') + + str = str.replace(re, '') + } + + if ( direction === 'right' || direction === 'both' ) { + const re = new RegExp(`[${ escapeRegExp(chars) }]+$`, 'g') + + str = str.replace(re, '') + } + + return str +} + +export function singularize(str: string) { + if ( str.endsWith('ies') ) { + return str.replace(/ies$/, 'y') + } else if ( str.endsWith('s') ) { + return str.replace(/s$/, '') + } else { + return str + } +} + +export async function safeConcatName(...parts: string[]) { + return safeConcatNameWithOptions(63, '-', ...parts) +} + +export function depthOf(str: string, separator = '.') { + let count = 0 + let i = -1 + + do { + i = str.indexOf(separator, i + 1) + + if ( i >= 0 ) { + count++ + } + } while ( i >= 0 ) + + return count +} + +export function nthLevelOf(str: string, level = 0, separator = '.') { + if ( level === 0 ) { + const idx = str.indexOf(separator) + + if ( idx === -1 ) { + return str + } else { + return str.substring(0, idx) + } + } else if ( level === -1 ) { + const parts = str.split(separator) + + parts.pop() + + return parts.join(separator) + } else { + return str.split(separator).slice(0, level + 1).join(separator) + } +} + +export function baseOf(str: string, separator = '.') { + return nthLevelOf(str, -1, separator) +} + +export function leafOf(str: string, separator = '.') { + return str.split(separator).pop() as string +} + +export function isChildOf(str: string, parent: string, separator = '.') { + return str.startsWith(parent + separator) +} + +export function isNumeric(str: string | number) { + return (`${ str }`).match(/^([0-9]+\.)?[0-9]*$/) +} diff --git a/ui/utils/url.ts b/ui/utils/url.ts new file mode 100644 index 00000000..c33f3793 --- /dev/null +++ b/ui/utils/url.ts @@ -0,0 +1,192 @@ +// Portions Copyright (c) 2014-2021 Rancher Labs, Inc. https://github.com/rancher/dashboard + +type UriField = 'source' | 'protocol' | 'authority' | 'userInfo' | 'user' | 'password' | 'host' | 'port' | 'relative' | 'path' | 'directory' | 'file' | 'queryStr' | 'anchor' +type UriFields = { + [key in UriField]: string; // eslint-disable-line no-unused-vars +} + +type QueryParams = Record + +interface ParsedUri extends UriFields { + query: QueryParams +} + +export function partialEncodeUriComponent(v: string, spaceAsPlus = true, safeChars: string[]) { + let escaped = encodeURIComponent(v) + + if ( spaceAsPlus ) { + escaped = escaped.replace(/%20/g, '+') + } + + if ( safeChars.length ) { + for ( const c of safeChars ) { + const re = new RegExp(encodeURIComponent(c), 'ig') + + escaped = escaped.replace(re, c) + } + } + + return escaped +} + +export function addParam(url: string, key: string, val: string | string[] | null, spaceAsPlus = true, safeChars: string[] = []): string { + let out = url + (url.includes('?') ? '&' : '?') + + // val can be a string or an array of strings + if (!Array.isArray(val)) { + val = [val as string] + } + + out += val.map((v) => { + if (v === null) { + return `${ encodeURIComponent(key) }` + } else { + return `${ encodeURIComponent(key) }=${ partialEncodeUriComponent(v, spaceAsPlus, safeChars) }` + } + }).join('&') + + return out +} + +export function addParams(url: string, params: QueryParams, spaceAsPlus = true, safeChars: string[] = []): string { + if (params && typeof params === 'object') { + Object.keys(params).forEach((key) => { + url = addParam(url, key, params[key], spaceAsPlus, safeChars) + }) + } + + return url +} + +export function removeParam(url: string, key: string): string { + const parsed = parseUrl(url) + + if (parsed.query?.[key]) { + delete parsed.query[key] + } + + return stringifyUrl(parsed) +} + +export function parseLinkHeader(str: string) { + const out: Record = { } + const lines = (str || '').split(',') + + for (const line of lines) { + const match = line.match(/^\s*<([^>]+)>\s*;\s*rel\s*="(.*)"/) + + if (match) { + out[match[2].toLowerCase()] = match[1] + } + } + + return out +} + +export function isMaybeSecure(port: number, proto: string): boolean { + const protocol = proto.toLowerCase() + + return portMatch([port], [443, 8443], ['443']) || protocol === 'https' +} + +export function portMatch(ports: number[], equals: number[], endsWith: string[]): boolean { + for (let i = 0; i < ports.length; i++) { + const port = ports[i] + + if (equals.includes(port)) { + return true + } + + for (let j = 0; j < endsWith.length; j++) { + const suffix = `${ endsWith[j] }` + const portStr = `${ port }` + + if (portStr !== suffix && portStr.endsWith(suffix)) { + return true + } + } + } + + return false +} + +// parseUri 1.2.2 +// (c) Steven Levithan +// https://javascriptsource.com/parseuri/ +// MIT License +export function parseUrl(str: string): ParsedUri { + const o = parseUrl.options + const m = o.parser[o.strictMode ? 'strict' : 'loose'].exec(str) + + if (!m) { + throw new Error(`Cannot parse as uri: ${ str }`) + } + + const uri = {} as ParsedUri + let i = 14 + + while (i--) { + uri[o.key[i]] = m[i] || '' + } + + uri.query = {} + uri.queryStr.replace(o.q.parser, (_, $1: string, $2: string): string => { + if ($1) { + uri[o.q.name][$1] = $2 + } + + return '' + }) + + return uri +} + +parseUrl.options = { + strictMode: false, + key: ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'queryStr', 'anchor'], + q: { + name: 'query', + parser: /(?:^|&)([^&=]*)=?([^&]*)/g, + }, + parser: { + strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, + loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/, + }, +} as { + strictMode: boolean + key: UriField[] + q: { + name: 'query' + parser: RegExp + } + parser: { + strict: RegExp + loose: RegExp + } +} + +export function stringifyUrl(uri: ParsedUri): string { + let out = `${ uri.protocol }://` + + if (uri.user && uri.password) { + out += `${ uri.user }:${ uri.password }@` + } else if (uri.user) { + out += `${ uri.user }@` + } + + out += uri.host + + if (uri.port) { + out += `:${ uri.port }` + } + + out += uri.path || '/' + + out = addParams(out, uri.query || {}) + + if (uri.anchor) { + out += `#${ uri.anchor }` + } + + return out +} diff --git a/ui/yarn.lock b/ui/yarn.lock new file mode 100644 index 00000000..72e60bb1 --- /dev/null +++ b/ui/yarn.lock @@ -0,0 +1,8331 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@antfu/eslint-config@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@antfu/eslint-config/-/eslint-config-2.6.4.tgz#45e79c01111fdc37b20bef028e8d34c5f5e679f9" + integrity sha512-dMD/QC5KWS1OltdpKLhfZM7W7y7zils85opk8d4lyNr7yn0OFjZs7eMYtcC6DrrN2kQ1JrFvBM7uB0QdWn5PUQ== + dependencies: + "@antfu/eslint-define-config" "^1.23.0-2" + "@antfu/install-pkg" "^0.3.1" + "@eslint-types/jsdoc" "46.8.2-1" + "@eslint-types/typescript-eslint" "^6.19.1" + "@eslint-types/unicorn" "^50.0.1" + "@stylistic/eslint-plugin" "^1.5.4" + "@typescript-eslint/eslint-plugin" "^6.20.0" + "@typescript-eslint/parser" "^6.20.0" + eslint-config-flat-gitignore "^0.1.2" + eslint-merge-processors "^0.1.0" + eslint-plugin-antfu "^2.1.2" + eslint-plugin-eslint-comments "^3.2.0" + eslint-plugin-i "^2.29.1" + eslint-plugin-jsdoc "^48.0.4" + eslint-plugin-jsonc "^2.13.0" + eslint-plugin-markdown "^3.0.1" + eslint-plugin-n "^16.6.2" + eslint-plugin-no-only-tests "^3.1.0" + eslint-plugin-perfectionist "^2.5.0" + eslint-plugin-toml "^0.9.2" + eslint-plugin-unicorn "^50.0.1" + eslint-plugin-unused-imports "^3.0.0" + eslint-plugin-vitest "^0.3.21" + eslint-plugin-vue "^9.21.1" + eslint-plugin-yml "^1.12.2" + eslint-processor-vue-blocks "^0.1.1" + globals "^13.24.0" + jsonc-eslint-parser "^2.4.0" + local-pkg "^0.5.0" + parse-gitignore "^2.0.0" + picocolors "^1.0.0" + prompts "^2.4.2" + toml-eslint-parser "^0.9.3" + vue-eslint-parser "^9.4.2" + yaml-eslint-parser "^1.2.2" + yargs "^17.7.2" + +"@antfu/eslint-define-config@^1.23.0-2": + version "1.23.0-2" + resolved "https://registry.yarnpkg.com/@antfu/eslint-define-config/-/eslint-define-config-1.23.0-2.tgz#05681d45b7fd24e4666750b6fd8da2bd8bf30a1f" + integrity sha512-LvxY21+ZhpuBf/aHeBUtGQhSEfad4PkNKXKvDOSvukaM3XVTfBhwmHX2EKwAsdq5DlfjbT3qqYyMiueBIO5iDQ== + +"@antfu/install-pkg@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-0.1.1.tgz#157bb04f0de8100b9e4c01734db1a6c77e98bbb5" + integrity sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ== + dependencies: + execa "^5.1.1" + find-up "^5.0.0" + +"@antfu/install-pkg@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-0.3.1.tgz#f63b3c98f92b455cd0929d4503eab276c9680943" + integrity sha512-A3zWY9VeTPnxlMiZtsGHw2lSd3ghwvL8s9RiGOtqvDxhhFfZ781ynsGBa/iUnDJ5zBrmTFQrJDud3TGgRISaxw== + dependencies: + execa "^8.0.1" + +"@antfu/utils@^0.7.5", "@antfu/utils@^0.7.6": + version "0.7.6" + resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.7.6.tgz#30a046419b9e1ecd276e53d41ab68fb6c558c04d" + integrity sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w== + +"@antfu/utils@^0.7.7": + version "0.7.7" + resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.7.7.tgz#26ea493a831b4f3a85475e7157be02fb4eab51fb" + integrity sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg== + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + +"@babel/core@^7.22.9", "@babel/core@^7.23.0", "@babel/core@^7.23.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.5.tgz#6e23f2acbcb77ad283c5ed141f824fd9f70101c7" + integrity sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.5" + "@babel/parser" "^7.23.5" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/core@^7.23.7": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.9.tgz#b028820718000f267870822fec434820e9b1e4d1" + integrity sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.9" + "@babel/parser" "^7.23.9" + "@babel/template" "^7.23.9" + "@babel/traverse" "^7.23.9" + "@babel/types" "^7.23.9" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.5.tgz#17d0a1ea6b62f351d281350a5f80b87a810c4755" + integrity sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA== + dependencies: + "@babel/types" "^7.23.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/generator@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== + dependencies: + "@babel/types" "^7.23.6" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-compilation-targets@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz#2a8792357008ae9ce8c0f2b78b9f646ac96b314b" + integrity sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" + +"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-replace-supers@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helpers@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.5.tgz#52f522840df8f1a848d06ea6a79b79eefa72401e" + integrity sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" + +"@babel/helpers@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.9.tgz#c3e20bbe7f7a7e10cb9b178384b4affdf5995c7d" + integrity sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ== + dependencies: + "@babel/template" "^7.23.9" + "@babel/traverse" "^7.23.9" + "@babel/types" "^7.23.9" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.22.15", "@babel/parser@^7.22.7", "@babel/parser@^7.23.3", "@babel/parser@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.5.tgz#37dee97c4752af148e1d38c34b856b2507660563" + integrity sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ== + +"@babel/parser@^7.23.6", "@babel/parser@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b" + integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA== + +"@babel/plugin-proposal-decorators@^7.23.0": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.5.tgz#eeaa49d0dc9229aec4d23378653738cdc5a3ea0a" + integrity sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.23.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/plugin-syntax-decorators" "^7.23.3" + +"@babel/plugin-syntax-decorators@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.23.3.tgz#a1d351d6c25bfdcf2e16f99b039101bc0ffcb0ca" + integrity sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.22.5": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" + integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-jsx@^7.22.5": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-typescript@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typescript@^7.22.15", "@babel/plugin-transform-typescript@^7.23.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.5.tgz#83da13ef62a1ebddf2872487527094b31c9adb84" + integrity sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.23.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.23.3" + +"@babel/runtime@^7.23.7": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" + integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/standalone@^7.22.9": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.23.5.tgz#3209677d9cfd6411734bd758d445e3f93ad2d698" + integrity sha512-4bqgawmyDPu+9gQhZOKh1ftCUa6BAT0KztElMcWAJgOgQJRNhmGVA0M0McedEqvGi7SbfiBBvlH13Jc47P919A== + +"@babel/standalone@^7.23.8": + version "7.23.10" + resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.23.10.tgz#f28dd3129291d9a26b873930f6d73815401ad540" + integrity sha512-xqWviI/pt1Zb/d+6ilWa5IDL2mkDzsBnlHbreqnfyP3/QB/ofQ1bNVcHj8YQX154Rf/xZKR6y0s1ydVF3nAS8g== + +"@babel/template@^7.22.15", "@babel/template@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/template@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a" + integrity sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.23.9" + "@babel/types" "^7.23.9" + +"@babel/traverse@^7.22.5", "@babel/traverse@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.5.tgz#f546bf9aba9ef2b042c0e00d245990c15508e7ec" + integrity sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.5" + "@babel/types" "^7.23.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.9.tgz#2f9d6aead6b564669394c5ce0f9302bb65b9d950" + integrity sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.9" + "@babel/types" "^7.23.9" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.3", "@babel/types@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.5.tgz#48d730a00c95109fa4393352705954d74fb5b602" + integrity sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@babel/types@^7.23.6", "@babel/types@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002" + integrity sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@cloudflare/kv-asset-handler@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.0.tgz#11f0af0749a400ddadcca16dcd6f4696d7036991" + integrity sha512-9CB/MKf/wdvbfkUdfrj+OkEwZ5b7rws0eogJ4293h+7b6KX5toPwym+VQKmILafNB9YiehqY0DlNrDcDhdWHSQ== + dependencies: + mime "^3.0.0" + +"@csstools/cascade-layer-name-parser@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.7.tgz#9cfc36de9716d219492eb0e5ee75348b2213a8fd" + integrity sha512-9J4aMRJ7A2WRjaRLvsMeWrL69FmEuijtiW1XlK/sG+V0UJiHVYUyvj9mY4WAXfU/hGIiGOgL8e0jJcRyaZTjDQ== + +"@csstools/css-parser-algorithms@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.5.0.tgz#0c03cd5418a9f404a05ff2ffcb1b69d04e8ec532" + integrity sha512-abypo6m9re3clXA00eu5syw+oaPHbJTPapu9C4pzNsJ4hdZDzushT50Zhu+iIYXgEe1CxnRMn7ngsbV+MLrlpQ== + +"@csstools/css-tokenizer@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-2.2.3.tgz#b099d543ea57b64f495915a095ead583866c50c6" + integrity sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg== + +"@csstools/selector-specificity@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-3.0.1.tgz#d84597fbc0f897240c12fc0a31e492b036c70e40" + integrity sha512-NPljRHkq4a14YzZ3YD406uaxh7s0g6eAq3L9aLOWywoqe8PkYamAvtsh7KNX6c++ihDrJ0RiU+/z7rGnhlZ5ww== + +"@egoist/tailwindcss-icons@^1.7.2": + version "1.7.4" + resolved "https://registry.yarnpkg.com/@egoist/tailwindcss-icons/-/tailwindcss-icons-1.7.4.tgz#70e5fdd64d6b5a035d5bb0d82c5e8303eee83c2b" + integrity sha512-883qx0sqeNb8km7os0w8K6UYue88dbgTWwyEUwW74Bgz0H7t+m7PMIIEvSQ4JqHwA823Qd5ciz+NoTBWKaMYfg== + dependencies: + "@iconify/utils" "^2.1.20" + +"@es-joy/jsdoccomment@~0.42.0": + version "0.42.0" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz#59e878708336aaee88c2b34c894f73dbf77ae2b0" + integrity sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw== + dependencies: + comment-parser "1.4.1" + esquery "^1.5.0" + jsdoc-type-pratt-parser "~4.0.0" + +"@esbuild/aix-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" + integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== + +"@esbuild/aix-ppc64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.0.tgz#509621cca4e67caf0d18561a0c56f8b70237472f" + integrity sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw== + +"@esbuild/android-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" + integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== + +"@esbuild/android-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz#fb7130103835b6d43ea499c3f30cfb2b2ed58456" + integrity sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA== + +"@esbuild/android-arm64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.0.tgz#109a6fdc4a2783fc26193d2687827045d8fef5ab" + integrity sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q== + +"@esbuild/android-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" + integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== + +"@esbuild/android-arm@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.8.tgz#b46e4d9e984e6d6db6c4224d72c86b7757e35bcb" + integrity sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA== + +"@esbuild/android-arm@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.0.tgz#1397a2c54c476c4799f9b9073550ede496c94ba5" + integrity sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g== + +"@esbuild/android-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" + integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== + +"@esbuild/android-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.8.tgz#a13db9441b5a4f4e4fec4a6f8ffacfea07888db7" + integrity sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A== + +"@esbuild/android-x64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.0.tgz#2b615abefb50dc0a70ac313971102f4ce2fdb3ca" + integrity sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ== + +"@esbuild/darwin-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" + integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== + +"@esbuild/darwin-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz#49f5718d36541f40dd62bfdf84da9c65168a0fc2" + integrity sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw== + +"@esbuild/darwin-arm64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.0.tgz#5c122ed799eb0c35b9d571097f77254964c276a2" + integrity sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ== + +"@esbuild/darwin-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" + integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== + +"@esbuild/darwin-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz#75c5c88371eea4bfc1f9ecfd0e75104c74a481ac" + integrity sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q== + +"@esbuild/darwin-x64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.0.tgz#9561d277002ba8caf1524f209de2b22e93d170c1" + integrity sha512-bsgTPoyYDnPv8ER0HqnJggXK6RyFy4PH4rtsId0V7Efa90u2+EifxytE9pZnsDgExgkARy24WUQGv9irVbTvIw== + +"@esbuild/freebsd-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" + integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== + +"@esbuild/freebsd-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz#9d7259fea4fd2b5f7437b52b542816e89d7c8575" + integrity sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw== + +"@esbuild/freebsd-arm64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.0.tgz#84178986a3138e8500d17cc380044868176dd821" + integrity sha512-kQ7jYdlKS335mpGbMW5tEe3IrQFIok9r84EM3PXB8qBFJPSc6dpWfrtsC/y1pyrz82xfUIn5ZrnSHQQsd6jebQ== + +"@esbuild/freebsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" + integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== + +"@esbuild/freebsd-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz#abac03e1c4c7c75ee8add6d76ec592f46dbb39e3" + integrity sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg== + +"@esbuild/freebsd-x64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.0.tgz#3f9ce53344af2f08d178551cd475629147324a83" + integrity sha512-uG8B0WSepMRsBNVXAQcHf9+Ko/Tr+XqmK7Ptel9HVmnykupXdS4J7ovSQUIi0tQGIndhbqWLaIL/qO/cWhXKyQ== + +"@esbuild/linux-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" + integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== + +"@esbuild/linux-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz#c577932cf4feeaa43cb9cec27b89cbe0df7d9098" + integrity sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ== + +"@esbuild/linux-arm64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.0.tgz#24efa685515689df4ecbc13031fa0a9dda910a11" + integrity sha512-uTtyYAP5veqi2z9b6Gr0NUoNv9F/rOzI8tOD5jKcCvRUn7T60Bb+42NDBCWNhMjkQzI0qqwXkQGo1SY41G52nw== + +"@esbuild/linux-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" + integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== + +"@esbuild/linux-arm@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz#d6014d8b98b5cbc96b95dad3d14d75bb364fdc0f" + integrity sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ== + +"@esbuild/linux-arm@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.0.tgz#6b586a488e02e9b073a75a957f2952b3b6e87b4c" + integrity sha512-2ezuhdiZw8vuHf1HKSf4TIk80naTbP9At7sOqZmdVwvvMyuoDiZB49YZKLsLOfKIr77+I40dWpHVeY5JHpIEIg== + +"@esbuild/linux-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" + integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== + +"@esbuild/linux-ia32@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz#2379a0554307d19ac4a6cdc15b08f0ea28e7a40d" + integrity sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ== + +"@esbuild/linux-ia32@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.0.tgz#84ce7864f762708dcebc1b123898a397dea13624" + integrity sha512-c88wwtfs8tTffPaoJ+SQn3y+lKtgTzyjkD8NgsyCtCmtoIC8RDL7PrJU05an/e9VuAke6eJqGkoMhJK1RY6z4w== + +"@esbuild/linux-loong64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" + integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== + +"@esbuild/linux-loong64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz#e2a5bbffe15748b49356a6cd7b2d5bf60c5a7123" + integrity sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ== + +"@esbuild/linux-loong64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.0.tgz#1922f571f4cae1958e3ad29439c563f7d4fd9037" + integrity sha512-lR2rr/128/6svngnVta6JN4gxSXle/yZEZL3o4XZ6esOqhyR4wsKyfu6qXAL04S4S5CgGfG+GYZnjFd4YiG3Aw== + +"@esbuild/linux-mips64el@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" + integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== + +"@esbuild/linux-mips64el@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz#1359331e6f6214f26f4b08db9b9df661c57cfa24" + integrity sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q== + +"@esbuild/linux-mips64el@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.0.tgz#7ca1bd9df3f874d18dbf46af009aebdb881188fe" + integrity sha512-9Sycc+1uUsDnJCelDf6ZNqgZQoK1mJvFtqf2MUz4ujTxGhvCWw+4chYfDLPepMEvVL9PDwn6HrXad5yOrNzIsQ== + +"@esbuild/linux-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" + integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== + +"@esbuild/linux-ppc64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz#9ba436addc1646dc89dae48c62d3e951ffe70951" + integrity sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg== + +"@esbuild/linux-ppc64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.0.tgz#8f95baf05f9486343bceeb683703875d698708a4" + integrity sha512-CoWSaaAXOZd+CjbUTdXIJE/t7Oz+4g90A3VBCHLbfuc5yUQU/nFDLOzQsN0cdxgXd97lYW/psIIBdjzQIwTBGw== + +"@esbuild/linux-riscv64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" + integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== + +"@esbuild/linux-riscv64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz#fbcf0c3a0b20f40b5fc31c3b7695f0769f9de66b" + integrity sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg== + +"@esbuild/linux-riscv64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.0.tgz#ca63b921d5fe315e28610deb0c195e79b1a262ca" + integrity sha512-mlb1hg/eYRJUpv8h/x+4ShgoNLL8wgZ64SUr26KwglTYnwAWjkhR2GpoKftDbPOCnodA9t4Y/b68H4J9XmmPzA== + +"@esbuild/linux-s390x@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" + integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== + +"@esbuild/linux-s390x@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz#989e8a05f7792d139d5564ffa7ff898ac6f20a4a" + integrity sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg== + +"@esbuild/linux-s390x@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.0.tgz#cb3d069f47dc202f785c997175f2307531371ef8" + integrity sha512-fgf9ubb53xSnOBqyvWEY6ukBNRl1mVX1srPNu06B6mNsNK20JfH6xV6jECzrQ69/VMiTLvHMicQR/PgTOgqJUQ== + +"@esbuild/linux-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" + integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== + +"@esbuild/linux-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz#b187295393a59323397fe5ff51e769ec4e72212b" + integrity sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg== + +"@esbuild/linux-x64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.0.tgz#ac617e0dc14e9758d3d7efd70288c14122557dc7" + integrity sha512-H9Eu6MGse++204XZcYsse1yFHmRXEWgadk2N58O/xd50P9EvFMLJTQLg+lB4E1cF2xhLZU5luSWtGTb0l9UeSg== + +"@esbuild/netbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" + integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== + +"@esbuild/netbsd-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz#c1ec0e24ea82313cb1c7bae176bd5acd5bde7137" + integrity sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw== + +"@esbuild/netbsd-x64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.0.tgz#6cc778567f1513da6e08060e0aeb41f82eb0f53c" + integrity sha512-lCT675rTN1v8Fo+RGrE5KjSnfY0x9Og4RN7t7lVrN3vMSjy34/+3na0q7RIfWDAj0e0rCh0OL+P88lu3Rt21MQ== + +"@esbuild/openbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" + integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== + +"@esbuild/openbsd-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz#0c5b696ac66c6d70cf9ee17073a581a28af9e18d" + integrity sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ== + +"@esbuild/openbsd-x64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.0.tgz#76848bcf76b4372574fb4d06cd0ed1fb29ec0fbe" + integrity sha512-HKoUGXz/TOVXKQ+67NhxyHv+aDSZf44QpWLa3I1lLvAwGq8x1k0T+e2HHSRvxWhfJrFxaaqre1+YyzQ99KixoA== + +"@esbuild/sunos-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" + integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== + +"@esbuild/sunos-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz#2a697e1f77926ff09fcc457d8f29916d6cd48fb1" + integrity sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w== + +"@esbuild/sunos-x64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.0.tgz#ea4cd0639bf294ad51bc08ffbb2dac297e9b4706" + integrity sha512-GDwAqgHQm1mVoPppGsoq4WJwT3vhnz/2N62CzhvApFD1eJyTroob30FPpOZabN+FgCjhG+AgcZyOPIkR8dfD7g== + +"@esbuild/win32-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" + integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== + +"@esbuild/win32-arm64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz#ec029e62a2fca8c071842ecb1bc5c2dd20b066f1" + integrity sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg== + +"@esbuild/win32-arm64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.0.tgz#a5c171e4a7f7e4e8be0e9947a65812c1535a7cf0" + integrity sha512-0vYsP8aC4TvMlOQYozoksiaxjlvUcQrac+muDqj1Fxy6jh9l9CZJzj7zmh8JGfiV49cYLTorFLxg7593pGldwQ== + +"@esbuild/win32-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" + integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== + +"@esbuild/win32-ia32@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz#cbb9a3146bde64dc15543e48afe418c7a3214851" + integrity sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw== + +"@esbuild/win32-ia32@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.0.tgz#f8ac5650c412d33ea62d7551e0caf82da52b7f85" + integrity sha512-p98u4rIgfh4gdpV00IqknBD5pC84LCub+4a3MO+zjqvU5MVXOc3hqR2UgT2jI2nh3h8s9EQxmOsVI3tyzv1iFg== + +"@esbuild/win32-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" + integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== + +"@esbuild/win32-x64@0.19.8": + version "0.19.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz#c8285183dbdb17008578dbacb6e22748709b4822" + integrity sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA== + +"@esbuild/win32-x64@0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.0.tgz#2efddf82828aac85e64cef62482af61c29561bee" + integrity sha512-NgJnesu1RtWihtTtXGFMU5YSE6JyyHPMxCwBZK7a6/8d31GuSo9l0Ss7w1Jw5QnKUawG6UEehs883kcXf5fYwg== + +"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.0", "@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + +"@eslint-types/jsdoc@46.8.2-1": + version "46.8.2-1" + resolved "https://registry.yarnpkg.com/@eslint-types/jsdoc/-/jsdoc-46.8.2-1.tgz#c1d9ec9ce032f0ad3a943613c346a648bcad9063" + integrity sha512-FwD7V0xX0jyaqj8Ul5ZY+TAAPohDfVqtbuXJNHb+OIv1aTIqZi5+Zn3F2UwQ5O3BnQd2mTduyK0+HjGx3/AMFg== + +"@eslint-types/typescript-eslint@^6.19.1": + version "6.19.1" + resolved "https://registry.yarnpkg.com/@eslint-types/typescript-eslint/-/typescript-eslint-6.19.1.tgz#979f5b4c10666a1b43900ee692128d811addb2ce" + integrity sha512-X0farz1+psE6Qfx6+ISQQ/J3ZetKlUeuTIN9Zt/agx4UXrgK6daH/n9ba776JxysK6YJCRaEHng/bcQQUm+BsA== + +"@eslint-types/unicorn@^50.0.1": + version "50.0.1" + resolved "https://registry.yarnpkg.com/@eslint-types/unicorn/-/unicorn-50.0.1.tgz#f11633d6355e61cb249c74a0d88818153314b7c3" + integrity sha512-nuJuipTNcg9f+oxZ+3QZw4tuDLmir4RJOPfM/oujgToiy1s+tePDZhwg5jUGc3q8OzTtPbVpsFSYX7QApjO3EA== + +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.56.0": + version "8.56.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" + integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== + +"@fastify/busboy@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff" + integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== + +"@headlessui/tailwindcss@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@headlessui/tailwindcss/-/tailwindcss-0.2.0.tgz#2c55c98fd8eee4b4f21ec6eb35a014b840059eec" + integrity sha512-fpL830Fln1SykOCboExsWr3JIVeQKieLJ3XytLe/tt1A0XzqUthOftDmjcCYLW62w7mQI7wXcoPXr3tZ9QfGxw== + +"@headlessui/vue@1.7.16": + version "1.7.16" + resolved "https://registry.yarnpkg.com/@headlessui/vue/-/vue-1.7.16.tgz#bdc9d32d329248910325539b99e6abfce0c69f89" + integrity sha512-nKT+nf/q6x198SsyK54mSszaQl/z+QxtASmgMEJtpxSX2Q0OPJX0upS/9daDyiECpeAsvjkoOrm2O/6PyBQ+Qg== + +"@heroicons/vue@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@heroicons/vue/-/vue-2.1.1.tgz#76299d6607a7a1164e3e06a037d7cf721c53b223" + integrity sha512-Yi5nh/89L193ALgHyJUQUdNLsKXPrrE3yj5yiR8WAlo7nZyXGxGauQcEAmBsa2XJGMhBMuEdoOiuZ8wEwTBxVQ== + +"@humanwhocodes/config-array@^0.11.13": + version "0.11.13" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" + integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== + dependencies: + "@humanwhocodes/object-schema" "^2.0.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" + integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== + +"@iconify-json/heroicons@^1.1.19": + version "1.1.19" + resolved "https://registry.yarnpkg.com/@iconify-json/heroicons/-/heroicons-1.1.19.tgz#55e4c5fcbe8bc0bab0ff62eefc832ae65c0dae96" + integrity sha512-uW2F9vdGll59W21ocBl+wR4Ve+/1CsmzBqPTuOaR3CbKzqnJKwzGASvC4Op0uTieFVWfBaevnzcRxwNo73J29g== + dependencies: + "@iconify/types" "*" + +"@iconify/collections@^1.0.374": + version "1.0.392" + resolved "https://registry.yarnpkg.com/@iconify/collections/-/collections-1.0.392.tgz#96a0367e8a15fc711fea6b95ff4dc6dd2c402af3" + integrity sha512-zk6qb0xKUQtg6j5auOlC5H4TGLvfhS5kGnpkTileHsjUOJMaPJEteGYKs4zuSaeFeamXhoQi6JY00hVVqCCqCA== + dependencies: + "@iconify/types" "*" + +"@iconify/types@*", "@iconify/types@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@iconify/types/-/types-2.0.0.tgz#ab0e9ea681d6c8a1214f30cd741fe3a20cc57f57" + integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== + +"@iconify/utils@^2.1.20": + version "2.1.22" + resolved "https://registry.yarnpkg.com/@iconify/utils/-/utils-2.1.22.tgz#d899026a40350ad44e8db0ee2d1e289572f73aef" + integrity sha512-6UHVzTVXmvO8uS6xFF+L/QTSpTzA/JZxtgU+KYGFyDYMEObZ1bu/b5l+zNJjHy+0leWjHI+C0pXlzGvv3oXZMA== + dependencies: + "@antfu/install-pkg" "^0.1.1" + "@antfu/utils" "^0.7.5" + "@iconify/types" "^2.0.0" + debug "^4.3.4" + kolorist "^1.8.0" + local-pkg "^0.5.0" + mlly "^1.5.0" + +"@iconify/vue@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@iconify/vue/-/vue-4.1.1.tgz#c143c2973a4990ba2b47b766f80a9bca97937305" + integrity sha512-RL85Bm/DAe8y6rT6pux7D2FJSiUEM/TPfyK7GrbAOfTSwrhvwJW+S5yijdGcmtXouA8MtuH9C7l4hiSE4mLMjg== + dependencies: + "@iconify/types" "^2.0.0" + +"@ioredis/commands@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" + integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@koa/router@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@koa/router/-/router-12.0.1.tgz#1a66f92a630c02832cf5bbf0db06c9e53e423468" + integrity sha512-ribfPYfHb+Uw3b27Eiw6NPqjhIhTpVFzEWLwyc/1Xp+DCdwRRyIlAUODX+9bPARF6aQtUu1+/PHzdNvRzcs/+Q== + dependencies: + debug "^4.3.4" + http-errors "^2.0.0" + koa-compose "^4.1.0" + methods "^1.1.2" + path-to-regexp "^6.2.1" + +"@kwsites/file-exists@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99" + integrity sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw== + dependencies: + debug "^4.1.1" + +"@kwsites/promise-deferred@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" + integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== + +"@mapbox/node-pre-gyp@^1.0.5": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" + integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== + dependencies: + detect-libc "^2.0.0" + https-proxy-agent "^5.0.0" + make-dir "^3.1.0" + node-fetch "^2.6.7" + nopt "^5.0.0" + npmlog "^5.0.1" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.11" + +"@netlify/functions@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@netlify/functions/-/functions-2.4.0.tgz#14cc222c44881e7fb3769a458e72a9f1216aff21" + integrity sha512-dIqhdj5u4Lu/8qbYwtYpn8NfvIyPHbSTV2lAP4ocL+iwC9As06AXT0wa/xOpO2vRWJa0IMxdZaqCPnkyHlHiyg== + dependencies: + "@netlify/serverless-functions-api" "1.11.0" + is-promise "^4.0.0" + +"@netlify/node-cookies@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@netlify/node-cookies/-/node-cookies-0.1.0.tgz#dda912ba618527695cf519fafa221c5e6777c612" + integrity sha512-OAs1xG+FfLX0LoRASpqzVntVV/RpYkgpI0VrUnw2u0Q1qiZUzcPffxRK8HF3gc4GjuhG5ahOEMJ9bswBiZPq0g== + +"@netlify/serverless-functions-api@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@netlify/serverless-functions-api/-/serverless-functions-api-1.11.0.tgz#b6fd1909933e50037e37573cb054706465e03a6e" + integrity sha512-3splAsr2CekL7VTwgo6yTvzD2+f269/s+TJafYazonqMNNo31yzvFxD5HpLtni4DNE1ppymVKZ4X/rLN3yl0vQ== + dependencies: + "@netlify/node-cookies" "^0.1.0" + urlpattern-polyfill "8.0.2" + +"@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 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 sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@npmcli/agent@^2.0.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-2.2.0.tgz#e81f00fdb2a670750ff7731bbefb47ecbf0ccf44" + integrity sha512-2yThA1Es98orMkpSLVqlDZAMPK3jHJhifP2gnNUdk1754uZ8yI5c+ulCoVG+WlntQA6MzhrURMXjSd9Z7dJ2/Q== + dependencies: + agent-base "^7.1.0" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.1" + lru-cache "^10.0.1" + socks-proxy-agent "^8.0.1" + +"@npmcli/fs@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" + integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== + dependencies: + semver "^7.3.5" + +"@npmcli/git@^5.0.0": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-5.0.3.tgz#ad3ede0994bcf716ddb63d361f3ea16cb72d878c" + integrity sha512-UZp9NwK+AynTrKvHn5k3KviW/hA5eENmFsu3iAPe7sWRt0lFUdsY/wXIYjpDFe7cdSNwOIzbObfwgt6eL5/2zw== + dependencies: + "@npmcli/promise-spawn" "^7.0.0" + lru-cache "^10.0.1" + npm-pick-manifest "^9.0.0" + proc-log "^3.0.0" + promise-inflight "^1.0.1" + promise-retry "^2.0.1" + semver "^7.3.5" + which "^4.0.0" + +"@npmcli/installed-package-contents@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33" + integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ== + dependencies: + npm-bundled "^3.0.0" + npm-normalize-package-bin "^3.0.0" + +"@npmcli/node-gyp@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" + integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== + +"@npmcli/promise-spawn@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-7.0.0.tgz#fd1c64ed4ff2341e503e1f390c62640a6540df09" + integrity sha512-wBqcGsMELZna0jDblGd7UXgOby45TQaMWmbFwWX+SEotk4HV6zG2t6rT9siyLhPk4P6YYqgfL1UO8nMWDBVJXQ== + dependencies: + which "^4.0.0" + +"@npmcli/run-script@^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-7.0.2.tgz#497e7f058799497889df65900c711312252276d3" + integrity sha512-Omu0rpA8WXvcGeY6DDzyRoY1i5DkCBkzyJ+m2u7PD6quzb0TvSqdIPOkTn8ZBOj7LbbcbMfZ3c5skwSu6m8y2w== + dependencies: + "@npmcli/node-gyp" "^3.0.0" + "@npmcli/promise-spawn" "^7.0.0" + node-gyp "^10.0.0" + read-package-json-fast "^3.0.0" + which "^4.0.0" + +"@nuxt/devalue@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@nuxt/devalue/-/devalue-2.0.2.tgz#5749f04df13bda4c863338d8dabaf370f45ef7c7" + integrity sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA== + +"@nuxt/devtools-kit@1.0.8", "@nuxt/devtools-kit@^1.0.6": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@nuxt/devtools-kit/-/devtools-kit-1.0.8.tgz#ecaa541909293d6b90a7bbab728c1c9891849ae5" + integrity sha512-j7bNZmoAXQ1a8qv6j6zk4c/aekrxYqYVQM21o/Hy4XHCUq4fajSgpoc8mjyWJSTfpkOmuLyEzMexpDWiIVSr6A== + dependencies: + "@nuxt/kit" "^3.9.1" + "@nuxt/schema" "^3.9.1" + execa "^7.2.0" + +"@nuxt/devtools-wizard@1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@nuxt/devtools-wizard/-/devtools-wizard-1.0.8.tgz#cb4e64337e565c349bb7b60cf3a80c117d68c59d" + integrity sha512-RxyOlM7Isk5npwXwDJ/rjm9ekX5sTNG0LS0VOBMdSx+D5nlRPMRr/r9yO+9WQDyzPLClLzHaXRHBWLPlRX3IMw== + dependencies: + consola "^3.2.3" + diff "^5.1.0" + execa "^7.2.0" + global-directory "^4.0.1" + magicast "^0.3.2" + pathe "^1.1.2" + pkg-types "^1.0.3" + prompts "^2.4.2" + rc9 "^2.1.1" + semver "^7.5.4" + +"@nuxt/devtools@1.0.8", "@nuxt/devtools@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@nuxt/devtools/-/devtools-1.0.8.tgz#d8edbb016f5194a7255f90623a205b484df77e26" + integrity sha512-o6aBFEBxc8OgVHV4OPe2g0q9tFIe9HiTxRiJnlTJ+jHvOQsBLS651ArdVtwLChf9UdMouFlpLLJ1HteZqTbtsQ== + dependencies: + "@antfu/utils" "^0.7.7" + "@nuxt/devtools-kit" "1.0.8" + "@nuxt/devtools-wizard" "1.0.8" + "@nuxt/kit" "^3.9.1" + birpc "^0.2.14" + consola "^3.2.3" + destr "^2.0.2" + error-stack-parser-es "^0.1.1" + execa "^7.2.0" + fast-glob "^3.3.2" + flatted "^3.2.9" + get-port-please "^3.1.2" + hookable "^5.5.3" + image-meta "^0.2.0" + is-installed-globally "^1.0.0" + launch-editor "^2.6.1" + local-pkg "^0.5.0" + magicast "^0.3.2" + nypm "^0.3.4" + ohash "^1.1.3" + pacote "^17.0.5" + pathe "^1.1.2" + perfect-debounce "^1.0.0" + pkg-types "^1.0.3" + rc9 "^2.1.1" + scule "^1.2.0" + semver "^7.5.4" + simple-git "^3.22.0" + sirv "^2.0.4" + unimport "^3.7.1" + vite-plugin-inspect "^0.8.1" + vite-plugin-vue-inspector "^4.0.2" + which "^3.0.1" + ws "^8.16.0" + +"@nuxt/kit@3.10.1", "@nuxt/kit@^3.9.0", "@nuxt/kit@^3.9.1", "@nuxt/kit@^3.9.3": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@nuxt/kit/-/kit-3.10.1.tgz#d1608f02a54f8434a389d9efcf50dda8634bc135" + integrity sha512-M9VRY0QGbG6lWOVqt69ZF96RLBUZVXyFpbBUwHnoHgjF9BXSX/MT/hrZcJicN4aPM2QRephGgsBd4U5wFmmn6g== + dependencies: + "@nuxt/schema" "3.10.1" + c12 "^1.6.1" + consola "^3.2.3" + defu "^6.1.4" + globby "^14.0.0" + hash-sum "^2.0.0" + ignore "^5.3.1" + jiti "^1.21.0" + knitwork "^1.0.0" + mlly "^1.5.0" + pathe "^1.1.2" + pkg-types "^1.0.3" + scule "^1.2.0" + semver "^7.5.4" + ufo "^1.3.2" + unctx "^2.3.1" + unimport "^3.7.1" + untyped "^1.4.2" + +"@nuxt/kit@^3.5.0": + version "3.9.3" + resolved "https://registry.yarnpkg.com/@nuxt/kit/-/kit-3.9.3.tgz#2f77b6dc446d519a71f1c76ba9c67ba260d40007" + integrity sha512-bHGXpTB6E+YJCC1L9tTwrP7txgLZzyuFes/tgy1ZM4dlfrCsGqLK/K4mddROMdC3D81scnH84u7yQsN0JRgoTg== + dependencies: + "@nuxt/schema" "3.9.3" + c12 "^1.6.1" + consola "^3.2.3" + defu "^6.1.4" + globby "^14.0.0" + hash-sum "^2.0.0" + ignore "^5.3.0" + jiti "^1.21.0" + knitwork "^1.0.0" + mlly "^1.5.0" + pathe "^1.1.2" + pkg-types "^1.0.3" + scule "^1.2.0" + semver "^7.5.4" + ufo "^1.3.2" + unctx "^2.3.1" + unimport "^3.7.1" + untyped "^1.4.0" + +"@nuxt/kit@^3.8.1", "@nuxt/kit@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@nuxt/kit/-/kit-3.8.2.tgz#f4548f3449d2566dbd2febe2b84f47060f7c668c" + integrity sha512-LrXCm8hAkw+zpX8teUSD/LqXRarlXjbRiYxDkaqw739JSHFReWzBFgJbojsJqL4h1XIEScDGGOWiEgO4QO1sMg== + dependencies: + "@nuxt/schema" "3.8.2" + c12 "^1.5.1" + consola "^3.2.3" + defu "^6.1.3" + globby "^14.0.0" + hash-sum "^2.0.0" + ignore "^5.3.0" + jiti "^1.21.0" + knitwork "^1.0.0" + mlly "^1.4.2" + pathe "^1.1.1" + pkg-types "^1.0.3" + scule "^1.1.0" + semver "^7.5.4" + ufo "^1.3.2" + unctx "^2.3.1" + unimport "^3.5.0" + untyped "^1.4.0" + +"@nuxt/schema@3.10.1", "@nuxt/schema@^3.9.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@nuxt/schema/-/schema-3.10.1.tgz#b7cb2d26d26922f028bbf91f4ff0aa9b69cd19ca" + integrity sha512-DyZLhbaaoGBCXO2jboCHTp77jbCIUem/va5iSu2+GO6M8vAHbNRphksw38gpSk/F74LbJDTbW0t3hrMBzU4B3g== + dependencies: + "@nuxt/ui-templates" "^1.3.1" + consola "^3.2.3" + defu "^6.1.4" + hookable "^5.5.3" + pathe "^1.1.2" + pkg-types "^1.0.3" + scule "^1.2.0" + std-env "^3.7.0" + ufo "^1.3.2" + unimport "^3.7.1" + untyped "^1.4.2" + +"@nuxt/schema@3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@nuxt/schema/-/schema-3.8.2.tgz#6eab0cc6152b921f3fe101b65e341e05c6c36864" + integrity sha512-AMpysQ/wHK2sOujLShqYdC4OSj/S3fFJGjhYXqA2g6dgmz+FNQWJRG/ie5sI9r2EX9Ela1wt0GN1jZR3wYNE8Q== + dependencies: + "@nuxt/ui-templates" "^1.3.1" + consola "^3.2.3" + defu "^6.1.3" + hookable "^5.5.3" + pathe "^1.1.1" + pkg-types "^1.0.3" + scule "^1.1.0" + std-env "^3.5.0" + ufo "^1.3.2" + unimport "^3.5.0" + untyped "^1.4.0" + +"@nuxt/schema@3.9.3": + version "3.9.3" + resolved "https://registry.yarnpkg.com/@nuxt/schema/-/schema-3.9.3.tgz#57ff39a8131b2ded735dfb4b03c2ef37a82196bf" + integrity sha512-pchkGBYdEJ9TAOoC5DKnLuAaFPjzgn2k0OUTr31QwbtHdTR3Q2Ua/oKsS1g9CPU7KRzSE5Vkf7ECE8zVydqF5A== + dependencies: + "@nuxt/ui-templates" "^1.3.1" + consola "^3.2.3" + defu "^6.1.4" + hookable "^5.5.3" + pathe "^1.1.2" + pkg-types "^1.0.3" + scule "^1.2.0" + std-env "^3.7.0" + ufo "^1.3.2" + unimport "^3.7.1" + untyped "^1.4.0" + +"@nuxt/telemetry@^2.5.3": + version "2.5.3" + resolved "https://registry.yarnpkg.com/@nuxt/telemetry/-/telemetry-2.5.3.tgz#e702bbccfb5cc4ab9b0cfc8239e96ed9e2ccfc74" + integrity sha512-Ghv2MgWbJcUM9G5Dy3oQP0cJkUwEgaiuQxEF61FXJdn0a69Q4StZEP/hLF0MWPM9m6EvAwI7orxkJHM7MrmtVg== + dependencies: + "@nuxt/kit" "^3.8.2" + ci-info "^4.0.0" + consola "^3.2.3" + create-require "^1.1.1" + defu "^6.1.3" + destr "^2.0.2" + dotenv "^16.3.1" + git-url-parse "^13.1.1" + is-docker "^3.0.0" + jiti "^1.21.0" + mri "^1.2.0" + nanoid "^4.0.2" + ofetch "^1.3.3" + parse-git-config "^3.0.0" + pathe "^1.1.1" + rc9 "^2.1.1" + std-env "^3.5.0" + +"@nuxt/ui-templates@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@nuxt/ui-templates/-/ui-templates-1.3.1.tgz#35f5c1adced7495a8c1284e37246a16e373ef5d5" + integrity sha512-5gc02Pu1HycOVUWJ8aYsWeeXcSTPe8iX8+KIrhyEtEoOSkY0eMBuo0ssljB8wALuEmepv31DlYe5gpiRwkjESA== + +"@nuxt/ui@2.13.0": + version "2.13.0" + resolved "https://registry.yarnpkg.com/@nuxt/ui/-/ui-2.13.0.tgz#a82d3054abab60c5c3357ae9db92fbcc9e40d4d5" + integrity sha512-u7TXMeNGV/lkPO/k2VlhCXUxJ+iw+OKUOaFLWRjHDfVQpBJMhzIvNvQhRPOD2FMpVuUUbpVjdOqbdEg9VQX3Wg== + dependencies: + "@egoist/tailwindcss-icons" "^1.7.2" + "@headlessui/tailwindcss" "^0.2.0" + "@headlessui/vue" "1.7.16" + "@iconify-json/heroicons" "^1.1.19" + "@nuxt/kit" "^3.9.3" + "@nuxtjs/color-mode" "^3.3.2" + "@nuxtjs/tailwindcss" "^6.11.2" + "@popperjs/core" "^2.11.8" + "@tailwindcss/aspect-ratio" "^0.4.2" + "@tailwindcss/container-queries" "^0.1.1" + "@tailwindcss/forms" "^0.5.7" + "@tailwindcss/typography" "^0.5.10" + "@vueuse/core" "^10.7.2" + "@vueuse/integrations" "^10.7.2" + "@vueuse/math" "^10.7.2" + defu "^6.1.4" + fuse.js "^6.6.2" + nuxt-icon "^0.6.8" + ohash "^1.1.3" + pathe "^1.1.2" + scule "^1.2.0" + tailwind-merge "^2.2.1" + tailwindcss "^3.4.1" + +"@nuxt/vite-builder@3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@nuxt/vite-builder/-/vite-builder-3.10.1.tgz#c6608b811aa9606d40e56a7433b3240d62c83502" + integrity sha512-Rl3sNWd43LNuKc4Y7vwWPLKH+4brbFCfcCQP1W86eSzfijen9AGuqyYIrRaaMieNE7aHMpYSIGCo4kYohhMsuA== + dependencies: + "@nuxt/kit" "3.10.1" + "@rollup/plugin-replace" "^5.0.5" + "@vitejs/plugin-vue" "^5.0.3" + "@vitejs/plugin-vue-jsx" "^3.1.0" + autoprefixer "^10.4.17" + clear "^0.1.0" + consola "^3.2.3" + cssnano "^6.0.3" + defu "^6.1.4" + esbuild "^0.20.0" + escape-string-regexp "^5.0.0" + estree-walker "^3.0.3" + externality "^1.0.2" + fs-extra "^11.2.0" + get-port-please "^3.1.2" + h3 "^1.10.1" + knitwork "^1.0.0" + magic-string "^0.30.6" + mlly "^1.5.0" + ohash "^1.1.3" + pathe "^1.1.2" + perfect-debounce "^1.0.0" + pkg-types "^1.0.3" + postcss "^8.4.33" + rollup-plugin-visualizer "^5.12.0" + std-env "^3.7.0" + strip-literal "^2.0.0" + ufo "^1.3.2" + unenv "^1.9.0" + unplugin "^1.6.0" + vite "5.0.12" + vite-node "^1.2.2" + vite-plugin-checker "^0.6.4" + vue-bundle-renderer "^2.0.0" + +"@nuxtjs/color-mode@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@nuxtjs/color-mode/-/color-mode-3.3.2.tgz#20ba12f40cec3556e1c2fe528630e49e60f7dcd4" + integrity sha512-BLpBfrYZngV2QWFQ4HNEFwAXa3Pno43Ge+2XHcZJTTa1Z4KzRLvOwku8yiyV3ovIaaXKGwduBdv3Z5Ocdp0/+g== + dependencies: + "@nuxt/kit" "^3.8.1" + lodash.template "^4.5.0" + pathe "^1.1.1" + +"@nuxtjs/tailwindcss@^6.11.2": + version "6.11.3" + resolved "https://registry.yarnpkg.com/@nuxtjs/tailwindcss/-/tailwindcss-6.11.3.tgz#29def3365875c0c1b87f5b620ab02b8e172224f6" + integrity sha512-l2iww/zOiHMuNERo6XB9MTJ8MEcq3NHFW/TPWmwPLGdOobV9zYUZ75otqi+mTK+/vgzQTtNXpIe2V0DLuTeb4A== + dependencies: + "@nuxt/kit" "^3.9.3" + autoprefixer "^10.4.17" + chokidar "^3.5.3" + clear-module "^4.1.2" + colorette "^2.0.20" + consola "^3.2.3" + defu "^6.1.4" + h3 "^1.10.0" + micromatch "^4.0.5" + pathe "^1.1.2" + postcss "^8.4.33" + postcss-custom-properties "^13.3.4" + postcss-nesting "^12.0.2" + tailwind-config-viewer "^1.7.3" + tailwindcss "~3.4.1" + ufo "^1.3.2" + +"@parcel/watcher-android-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz#d82e74bb564ebd4d8a88791d273a3d2bd61e27ab" + integrity sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA== + +"@parcel/watcher-darwin-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz#c9cd03f8f233d512fcfc873d5b4e23f1569a82ad" + integrity sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw== + +"@parcel/watcher-darwin-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz#83c902994a2a49b9e1ab5050dba24876fdc2c219" + integrity sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow== + +"@parcel/watcher-freebsd-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz#7a0f4593a887e2752b706aff2dae509aef430cf6" + integrity sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw== + +"@parcel/watcher-linux-arm-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz#3fc90c3ebe67de3648ed2f138068722f9b1d47da" + integrity sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ== + +"@parcel/watcher-linux-arm64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz#f7bbbf2497d85fd11e4c9e9c26ace8f10ea9bcbc" + integrity sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA== + +"@parcel/watcher-linux-arm64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz#de131a9fcbe1fa0854e9cbf4c55bed3b35bcff43" + integrity sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw== + +"@parcel/watcher-linux-x64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz#193dd1c798003cdb5a1e59470ff26300f418a943" + integrity sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow== + +"@parcel/watcher-linux-x64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz#6dbdb86d96e955ab0fe4a4b60734ec0025a689dd" + integrity sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g== + +"@parcel/watcher-wasm@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-wasm/-/watcher-wasm-2.3.0.tgz#73b66c6fbd2a3326ae86a1ec77eab7139d0dd725" + integrity sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA== + dependencies: + is-glob "^4.0.3" + micromatch "^4.0.5" + napi-wasm "^1.1.0" + +"@parcel/watcher-win32-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz#59da26a431da946e6c74fa6b0f30b120ea6650b6" + integrity sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw== + +"@parcel/watcher-win32-ia32@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz#3ee6a18b08929cd3b788e8cc9547fd9a540c013a" + integrity sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow== + +"@parcel/watcher-win32-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz#14e7246289861acc589fd608de39fe5d8b4bb0a7" + integrity sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA== + +"@parcel/watcher@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.3.0.tgz#803517abbc3981a1a1221791d9f59dc0590d50f9" + integrity sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ== + dependencies: + detect-libc "^1.0.3" + is-glob "^4.0.3" + micromatch "^4.0.5" + node-addon-api "^7.0.0" + optionalDependencies: + "@parcel/watcher-android-arm64" "2.3.0" + "@parcel/watcher-darwin-arm64" "2.3.0" + "@parcel/watcher-darwin-x64" "2.3.0" + "@parcel/watcher-freebsd-x64" "2.3.0" + "@parcel/watcher-linux-arm-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-musl" "2.3.0" + "@parcel/watcher-linux-x64-glibc" "2.3.0" + "@parcel/watcher-linux-x64-musl" "2.3.0" + "@parcel/watcher-win32-arm64" "2.3.0" + "@parcel/watcher-win32-ia32" "2.3.0" + "@parcel/watcher-win32-x64" "2.3.0" + +"@pinia/nuxt@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@pinia/nuxt/-/nuxt-0.5.1.tgz#ee7c979d365a5dfda882430ddfae405fbd78d8d5" + integrity sha512-6wT6TqY81n+7/x3Yhf0yfaJVKkZU42AGqOR0T3+UvChcaOJhSma7OWPN64v+ptYlznat+fS1VTwNAcbi2lzHnw== + dependencies: + "@nuxt/kit" "^3.5.0" + pinia ">=2.1.7" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@polka/url@^1.0.0-next.20", "@polka/url@^1.0.0-next.24": + version "1.0.0-next.24" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.24.tgz#58601079e11784d20f82d0585865bb42305c4df3" + integrity sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ== + +"@popperjs/core@^2.11.8": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + +"@rollup/plugin-alias@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz#99a94accc4ff9a3483be5baeedd5d7da3b597e93" + integrity sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ== + dependencies: + slash "^4.0.0" + +"@rollup/plugin-commonjs@^25.0.7": + version "25.0.7" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz#145cec7589ad952171aeb6a585bbeabd0fd3b4cf" + integrity sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ== + dependencies: + "@rollup/pluginutils" "^5.0.1" + commondir "^1.0.1" + estree-walker "^2.0.2" + glob "^8.0.3" + is-reference "1.2.1" + magic-string "^0.30.3" + +"@rollup/plugin-inject@^5.0.5": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz#616f3a73fe075765f91c5bec90176608bed277a3" + integrity sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg== + dependencies: + "@rollup/pluginutils" "^5.0.1" + estree-walker "^2.0.2" + magic-string "^0.30.3" + +"@rollup/plugin-json@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.0.1.tgz#7e2efcf5ed549963f1444e010611d22f463931c0" + integrity sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw== + dependencies: + "@rollup/pluginutils" "^5.0.1" + +"@rollup/plugin-node-resolve@^15.2.3": + version "15.2.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz#e5e0b059bd85ca57489492f295ce88c2d4b0daf9" + integrity sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ== + dependencies: + "@rollup/pluginutils" "^5.0.1" + "@types/resolve" "1.20.2" + deepmerge "^4.2.2" + is-builtin-module "^3.2.1" + is-module "^1.0.0" + resolve "^1.22.1" + +"@rollup/plugin-replace@^5.0.5": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-5.0.5.tgz#33d5653dce6d03cb24ef98bef7f6d25b57faefdf" + integrity sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ== + dependencies: + "@rollup/pluginutils" "^5.0.1" + magic-string "^0.30.3" + +"@rollup/plugin-terser@^0.4.4": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz#15dffdb3f73f121aa4fbb37e7ca6be9aeea91962" + integrity sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A== + dependencies: + serialize-javascript "^6.0.1" + smob "^1.0.0" + terser "^5.17.4" + +"@rollup/plugin-wasm@^6.2.2": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-wasm/-/plugin-wasm-6.2.2.tgz#ea75fd8cc5ddba1e30bdc22e07cdbaf8d6d160bf" + integrity sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ== + dependencies: + "@rollup/pluginutils" "^5.0.2" + +"@rollup/pluginutils@^4.0.0": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" + integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== + dependencies: + estree-walker "^2.0.1" + picomatch "^2.2.2" + +"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.0.2", "@rollup/pluginutils@^5.0.4", "@rollup/pluginutils@^5.0.5", "@rollup/pluginutils@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + +"@rollup/rollup-android-arm-eabi@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.6.1.tgz#0ea289f68ff248b50fea5716ca9f65f7d4dba3ae" + integrity sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA== + +"@rollup/rollup-android-arm-eabi@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz#66b8d9cb2b3a474d115500f9ebaf43e2126fe496" + integrity sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg== + +"@rollup/rollup-android-arm64@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.6.1.tgz#27c8c67fc5de574874085a1b480ac65b3e18378e" + integrity sha512-1TKm25Rn20vr5aTGGZqo6E4mzPicCUD79k17EgTLAsXc1zysyi4xXKACfUbwyANEPAEIxkzwue6JZ+stYzWUTA== + +"@rollup/rollup-android-arm64@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz#46327d5b86420d2307946bec1535fdf00356e47d" + integrity sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw== + +"@rollup/rollup-darwin-arm64@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.6.1.tgz#c5735c042980c85495411af7183dd20294763bd8" + integrity sha512-cEXJQY/ZqMACb+nxzDeX9IPLAg7S94xouJJCNVE5BJM8JUEP4HeTF+ti3cmxWeSJo+5D+o8Tc0UAWUkfENdeyw== + +"@rollup/rollup-darwin-arm64@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz#166987224d2f8b1e2fd28ee90c447d52271d5e90" + integrity sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw== + +"@rollup/rollup-darwin-x64@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.6.1.tgz#af844bd54abb73ca3c9cf89a31eec17861d1375d" + integrity sha512-LoSU9Xu56isrkV2jLldcKspJ7sSXmZWkAxg7sW/RfF7GS4F5/v4EiqKSMCFbZtDu2Nc1gxxFdQdKwkKS4rwxNg== + +"@rollup/rollup-darwin-x64@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz#a2e6e096f74ccea6e2f174454c26aef6bcdd1274" + integrity sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog== + +"@rollup/rollup-linux-arm-gnueabihf@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.6.1.tgz#5e972f63c441eaf859551039b3f18db9b035977d" + integrity sha512-EfI3hzYAy5vFNDqpXsNxXcgRDcFHUWSx5nnRSCKwXuQlI5J9dD84g2Usw81n3FLBNsGCegKGwwTVsSKK9cooSQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz#09fcd4c55a2d6160c5865fec708a8e5287f30515" + integrity sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ== + +"@rollup/rollup-linux-arm64-gnu@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.6.1.tgz#f4cfbc71e3b6fdb395b28b1472414e181515c72d" + integrity sha512-9lhc4UZstsegbNLhH0Zu6TqvDfmhGzuCWtcTFXY10VjLLUe4Mr0Ye2L3rrtHaDd/J5+tFMEuo5LTCSCMXWfUKw== + +"@rollup/rollup-linux-arm64-gnu@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz#19a3c0b6315c747ca9acf86e9b710cc2440f83c9" + integrity sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ== + +"@rollup/rollup-linux-arm64-musl@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.6.1.tgz#6a94c691830dc29bf708de7c640f494996130893" + integrity sha512-FfoOK1yP5ksX3wwZ4Zk1NgyGHZyuRhf99j64I5oEmirV8EFT7+OhUZEnP+x17lcP/QHJNWGsoJwrz4PJ9fBEXw== + +"@rollup/rollup-linux-arm64-musl@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz#94aaf95fdaf2ad9335983a4552759f98e6b2e850" + integrity sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ== + +"@rollup/rollup-linux-riscv64-gnu@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz#160510e63f4b12618af4013bddf1761cf9fc9880" + integrity sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA== + +"@rollup/rollup-linux-x64-gnu@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.6.1.tgz#f07bae3f7dc532d9ea5ab36c9071db329f9a1efb" + integrity sha512-DNGZvZDO5YF7jN5fX8ZqmGLjZEXIJRdJEdTFMhiyXqyXubBa0WVLDWSNlQ5JR2PNgDbEV1VQowhVRUh+74D+RA== + +"@rollup/rollup-linux-x64-gnu@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz#5ac5d068ce0726bd0a96ca260d5bd93721c0cb98" + integrity sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw== + +"@rollup/rollup-linux-x64-musl@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.6.1.tgz#357a34fdbf410af88ce48bd802bea6462bb9a8bc" + integrity sha512-RkJVNVRM+piYy87HrKmhbexCHg3A6Z6MU0W9GHnJwBQNBeyhCJG9KDce4SAMdicQnpURggSvtbGo9xAWOfSvIQ== + +"@rollup/rollup-linux-x64-musl@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz#bafa759ab43e8eab9edf242a8259ffb4f2a57a5d" + integrity sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ== + +"@rollup/rollup-win32-arm64-msvc@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.6.1.tgz#b6e97fd38281667e35297033393cd1101f4a31be" + integrity sha512-v2FVT6xfnnmTe3W9bJXl6r5KwJglMK/iRlkKiIFfO6ysKs0rDgz7Cwwf3tjldxQUrHL9INT/1r4VA0n9L/F1vQ== + +"@rollup/rollup-win32-arm64-msvc@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz#1cc3416682e5a20d8f088f26657e6e47f8db468e" + integrity sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA== + +"@rollup/rollup-win32-ia32-msvc@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.6.1.tgz#a95db026c640c8128bfd38546d85342f2329beaf" + integrity sha512-YEeOjxRyEjqcWphH9dyLbzgkF8wZSKAKUkldRY6dgNR5oKs2LZazqGB41cWJ4Iqqcy9/zqYgmzBkRoVz3Q9MLw== + +"@rollup/rollup-win32-ia32-msvc@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz#7d2251e1aa5e8a1e47c86891fe4547a939503461" + integrity sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ== + +"@rollup/rollup-win32-x64-msvc@4.6.1": + version "4.6.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.6.1.tgz#45785b5caf83200a34a9867ba50d69560880c120" + integrity sha512-0zfTlFAIhgz8V2G8STq8toAjsYYA6eci1hnXuyOTUFnymrtJwnS6uGKiv3v5UrPZkBlamLvrLV2iiaeqCKzb0A== + +"@rollup/rollup-win32-x64-msvc@4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz#2c1fb69e02a3f1506f52698cfdc3a8b6386df9a6" + integrity sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ== + +"@sigstore/bundle@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-2.1.0.tgz#c6140ca97b68815edf7c4fb7bdbf58d656525c39" + integrity sha512-89uOo6yh/oxaU8AeOUnVrTdVMcGk9Q1hJa7Hkvalc6G3Z3CupWk4Xe9djSgJm9fMkH69s0P0cVHUoKSOemLdng== + dependencies: + "@sigstore/protobuf-specs" "^0.2.1" + +"@sigstore/protobuf-specs@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" + integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== + +"@sigstore/sign@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-2.2.0.tgz#4918207d8356877ab42d85d360d5729e9b3ec65a" + integrity sha512-AAbmnEHDQv6CSfrWA5wXslGtzLPtAtHZleKOgxdQYvx/s76Fk6T6ZVt7w2IGV9j1UrFeBocTTQxaXG2oRrDhYA== + dependencies: + "@sigstore/bundle" "^2.1.0" + "@sigstore/protobuf-specs" "^0.2.1" + make-fetch-happen "^13.0.0" + +"@sigstore/tuf@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-2.2.0.tgz#ef636239687e41af3f2ce10667ab88f5ca6165b3" + integrity sha512-KKATZ5orWfqd9ZG6MN8PtCIx4eevWSuGRKQvofnWXRpyMyUEpmrzg5M5BrCpjM+NfZ0RbNGOh5tCz/P2uoRqOA== + dependencies: + "@sigstore/protobuf-specs" "^0.2.1" + tuf-js "^2.1.0" + +"@sindresorhus/merge-streams@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz#9cd84cc15bc865a5ca35fcaae198eb899f7b5c90" + integrity sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw== + +"@stylistic/eslint-plugin-js@1.6.0", "@stylistic/eslint-plugin-js@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.6.0.tgz#c17a7e4b28bd6d8ba21ea240344eaa677e91ece2" + integrity sha512-qlBAu08fy4d5BEF+c31E5y0OvEOVZo3SfOOs2Qrb4/CwAaXrAch++axBWedzgR3n0XqkuXjr6dbexqrdOm92ag== + dependencies: + acorn "^8.11.3" + escape-string-regexp "^4.0.0" + eslint-visitor-keys "^3.4.3" + espree "^10.0.0" + +"@stylistic/eslint-plugin-jsx@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.6.0.tgz#4aad037bb680cad44b60c135f198494a7ced5651" + integrity sha512-MlRpiuNpanQrszotBlar77GDf71HjemJNNQBvLnsk/MHxo6fxbIcAyLSNSVQJhP14ah6PvpPFcExRK4Hj7MGeg== + dependencies: + "@stylistic/eslint-plugin-js" "^1.6.0" + estraverse "^5.3.0" + picomatch "^3.0.1" + +"@stylistic/eslint-plugin-plus@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.6.0.tgz#a9fc6296c8c758ead8292547a06ad9249567fa6c" + integrity sha512-XfLBBkKIERzMYGEX1A5RCe/gVe9pTdGuHC2xDzlEIs2npudMHxm304K7l2CqlAWGyJ/yP6wwrsSEHozQUIo/Og== + dependencies: + "@typescript-eslint/utils" "^6.20.0" + +"@stylistic/eslint-plugin-ts@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.6.0.tgz#c2d9a2e135bf0908315fd0ea441b2ee866ce05c9" + integrity sha512-qM9Vw8TfZeGmN8oreWwUIdEdCs/py9/X88O4ksJv0V/kDmaupVKL8Uu06IlphN2crN6SPU8ljv9rcGXZoxwvmA== + dependencies: + "@stylistic/eslint-plugin-js" "1.6.0" + "@typescript-eslint/utils" "^6.20.0" + +"@stylistic/eslint-plugin@^1.5.4": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin/-/eslint-plugin-1.6.0.tgz#47c20059bb378f48d0bb603c17b4cdb9fe243ae7" + integrity sha512-Bdz9mFIvOkpM03QLoTSg7rTTYj+u3kokWIQ+nI5UFE+FkRQSVgvL41cwkdCebud/L4dMcItuBPA25h6XOuHFPA== + dependencies: + "@stylistic/eslint-plugin-js" "1.6.0" + "@stylistic/eslint-plugin-jsx" "1.6.0" + "@stylistic/eslint-plugin-plus" "1.6.0" + "@stylistic/eslint-plugin-ts" "1.6.0" + +"@tailwindcss/aspect-ratio@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@tailwindcss/aspect-ratio/-/aspect-ratio-0.4.2.tgz#9ffd52fee8e3c8b20623ff0dcb29e5c21fb0a9ba" + integrity sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ== + +"@tailwindcss/container-queries@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz#9a759ce2cb8736a4c6a0cb93aeb740573a731974" + integrity sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA== + +"@tailwindcss/forms@^0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.5.7.tgz#db5421f062a757b5f828bc9286ba626c6685e821" + integrity sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw== + dependencies: + mini-svg-data-uri "^1.2.3" + +"@tailwindcss/typography@^0.5.10": + version "0.5.10" + resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.10.tgz#2abde4c6d5c797ab49cf47610830a301de4c1e0a" + integrity sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw== + dependencies: + lodash.castarray "^4.4.0" + lodash.isplainobject "^4.0.6" + lodash.merge "^4.6.2" + postcss-selector-parser "6.0.10" + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@tufjs/canonical-json@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz#a52f61a3d7374833fca945b2549bc30a2dd40d0a" + integrity sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA== + +"@tufjs/models@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-2.0.0.tgz#c7ab241cf11dd29deb213d6817dabb8c99ce0863" + integrity sha512-c8nj8BaOExmZKO2DXhDfegyhSGcG9E/mPN3U13L+/PsoWm1uaGiHHjxqSHQiasDBQwDA3aHuw9+9spYAP1qvvg== + dependencies: + "@tufjs/canonical-json" "2.0.0" + minimatch "^9.0.3" + +"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/http-proxy@^1.17.14": + version "1.17.14" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== + dependencies: + "@types/node" "*" + +"@types/json-schema@^7.0.12": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/lodash-es@^4.17.12": + version "4.17.12" + resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b" + integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.202" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== + +"@types/mdast@^3.0.0": + version "3.0.15" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5" + integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ== + dependencies: + "@types/unist" "^2" + +"@types/node@*": + version "20.10.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.4.tgz#b246fd84d55d5b1b71bf51f964bd514409347198" + integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== + dependencies: + undici-types "~5.26.4" + +"@types/normalize-package-data@^2.4.0": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== + +"@types/resolve@1.20.2": + version "1.20.2" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" + integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== + +"@types/semver@^7.5.0": + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== + +"@types/unist@^2", "@types/unist@^2.0.2": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" + integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== + +"@types/web-bluetooth@^0.0.20": + version "0.0.20" + resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597" + integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow== + +"@typescript-eslint/eslint-plugin@^6.20.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" + integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/type-utils" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.20.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" + integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== + dependencies: + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz#5fa4e4adace028dafac212c770640b94e7b61052" + integrity sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA== + dependencies: + "@typescript-eslint/types" "6.13.2" + "@typescript-eslint/visitor-keys" "6.13.2" + +"@typescript-eslint/scope-manager@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" + integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + +"@typescript-eslint/type-utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" + integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== + dependencies: + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.13.2.tgz#c044aac24c2f6cefb8e921e397acad5417dd0ae6" + integrity sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg== + +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== + +"@typescript-eslint/typescript-estree@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz#ae556ee154c1acf025b48d37c3ef95a1d55da258" + integrity sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w== + dependencies: + "@typescript-eslint/types" "6.13.2" + "@typescript-eslint/visitor-keys" "6.13.2" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== + dependencies: + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "9.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.21.0", "@typescript-eslint/utils@^6.20.0", "@typescript-eslint/utils@^6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" + integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + semver "^7.5.4" + +"@typescript-eslint/utils@^6.13.0": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.13.2.tgz#8eb89e53adc6d703a879b131e528807245486f89" + integrity sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.13.2" + "@typescript-eslint/types" "6.13.2" + "@typescript-eslint/typescript-estree" "6.13.2" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz#e0a4a80cf842bb08e6127b903284166ac4a5594c" + integrity sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw== + dependencies: + "@typescript-eslint/types" "6.13.2" + eslint-visitor-keys "^3.4.1" + +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== + dependencies: + "@typescript-eslint/types" "6.21.0" + eslint-visitor-keys "^3.4.1" + +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@unhead/dom@1.8.10", "@unhead/dom@^1.8.10": + version "1.8.10" + resolved "https://registry.yarnpkg.com/@unhead/dom/-/dom-1.8.10.tgz#18505665a021d924645fedda18deb8fc8b2e81c3" + integrity sha512-dBeDbHrBjeU+eVgMsD91TGEazb1dwLrY0x/ve01CldMCmm+WcRu++SUW7s1QX84mzGH2EgFz78o1OPn6jpV3zw== + dependencies: + "@unhead/schema" "1.8.10" + "@unhead/shared" "1.8.10" + +"@unhead/schema@1.8.10": + version "1.8.10" + resolved "https://registry.yarnpkg.com/@unhead/schema/-/schema-1.8.10.tgz#40e2578a006ae212b5afe7a44bd556846c32ea2e" + integrity sha512-cy8RGOPkwOVY5EmRoCgGV8AqLjy/226xBVTY54kBct02Om3hBdpB9FZa9frM910pPUXMI8PNmFgABO23O7IdJA== + dependencies: + hookable "^5.5.3" + zhead "^2.2.4" + +"@unhead/shared@1.8.10": + version "1.8.10" + resolved "https://registry.yarnpkg.com/@unhead/shared/-/shared-1.8.10.tgz#86e02d7961fb7d523238a21c3532e5042aceb399" + integrity sha512-pEFryAs3EmV+ShDQx2ZBwUnt5l3RrMrXSMZ50oFf+MImKZNARVvD4+3I8fEI9wZh+Zq0JYG3UAfzo51MUP+Juw== + dependencies: + "@unhead/schema" "1.8.10" + +"@unhead/ssr@^1.8.10": + version "1.8.10" + resolved "https://registry.yarnpkg.com/@unhead/ssr/-/ssr-1.8.10.tgz#057f0dc98bbe8f328fe01f70ba6bf39abf02956b" + integrity sha512-7wKRKDd8c2NFmMyPetj8Ah5u2hXunDBZT5Y2DH83O16PiMxx4/uobGamTV1EfcqjTvOKJvAqkrYZNYSWss99NQ== + dependencies: + "@unhead/schema" "1.8.10" + "@unhead/shared" "1.8.10" + +"@unhead/vue@^1.8.10": + version "1.8.10" + resolved "https://registry.yarnpkg.com/@unhead/vue/-/vue-1.8.10.tgz#ee1b8cda7fc77de0c43fa5fc7c081528e31ec9cb" + integrity sha512-KF8pftHnxnlBlgNpKXWLTg3ZUtkuDCxRPUFSDBy9CtqRSX/qvAhLZ26mbqRVmHj8KigiRHP/wnPWNyGnUx20Bg== + dependencies: + "@unhead/schema" "1.8.10" + "@unhead/shared" "1.8.10" + hookable "^5.5.3" + unhead "1.8.10" + +"@vercel/nft@^0.24.3": + version "0.24.4" + resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.24.4.tgz#b8942340c7821e6ff7bdf943b559642dbc9cae78" + integrity sha512-KjYAZty7boH5fi5udp6p+lNu6nawgs++pHW+3koErMgbRkkHuToGX/FwjN5clV1FcaM3udfd4zW/sUapkMgpZw== + dependencies: + "@mapbox/node-pre-gyp" "^1.0.5" + "@rollup/pluginutils" "^4.0.0" + acorn "^8.6.0" + async-sema "^3.1.1" + bindings "^1.4.0" + estree-walker "2.0.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + micromatch "^4.0.2" + node-gyp-build "^4.2.2" + resolve-from "^5.0.0" + +"@vitejs/plugin-vue-jsx@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.1.0.tgz#9953fd9456539e1f0f253bf0fcd1289e66c67cd1" + integrity sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA== + dependencies: + "@babel/core" "^7.23.3" + "@babel/plugin-transform-typescript" "^7.23.3" + "@vue/babel-plugin-jsx" "^1.1.5" + +"@vitejs/plugin-vue@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.3.tgz#164b36653910d27c130cf6c945b4bd9bde5bcbee" + integrity sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA== + +"@vue-macros/common@^1.8.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@vue-macros/common/-/common-1.9.0.tgz#a2659f220b7f2d3117a560e50c30fb61833356dd" + integrity sha512-LbfRHDkceuokkLlVuQW9Wq3ZLmRs6KIDPzCjUvvL14HB4GslWdtvBB1suFfNs6VMvh9Zj30cEKF/EAP7QBCZ6Q== + dependencies: + "@babel/types" "^7.23.3" + "@rollup/pluginutils" "^5.0.5" + "@vue/compiler-sfc" "^3.3.8" + ast-kit "^0.11.2" + local-pkg "^0.5.0" + magic-string-ast "^0.3.0" + +"@vue/babel-helper-vue-transform-on@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.1.5.tgz#a976486b21e108e545524fe41ffe3fc9bbc28c7f" + integrity sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w== + +"@vue/babel-plugin-jsx@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.5.tgz#5088bae7dbb83531d94df3742ff650c12fd54973" + integrity sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + "@vue/babel-helper-vue-transform-on" "^1.1.5" + camelcase "^6.3.0" + html-tags "^3.3.1" + svg-tags "^1.0.0" + +"@vue/compiler-core@3.3.10": + version "3.3.10" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.10.tgz#9ca4123a1458df43db641aaa8b7d1e636aa22545" + integrity sha512-doe0hODR1+i1menPkRzJ5MNR6G+9uiZHIknK3Zn5OcIztu6GGw7u0XUzf3AgB8h/dfsZC9eouzoLo3c3+N/cVA== + dependencies: + "@babel/parser" "^7.23.5" + "@vue/shared" "3.3.10" + estree-walker "^2.0.2" + source-map-js "^1.0.2" + +"@vue/compiler-core@3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.15.tgz#be20d1bbe19626052500b48969302cb6f396d36e" + integrity sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw== + dependencies: + "@babel/parser" "^7.23.6" + "@vue/shared" "3.4.15" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.0.2" + +"@vue/compiler-dom@3.3.10", "@vue/compiler-dom@^3.3.4": + version "3.3.10" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.10.tgz#183811252be6aff4ac923f783124bb1590301907" + integrity sha512-NCrqF5fm10GXZIK0GrEAauBqdy+F2LZRt3yNHzrYjpYBuRssQbuPLtSnSNjyR9luHKkWSH8we5LMB3g+4z2HvA== + dependencies: + "@vue/compiler-core" "3.3.10" + "@vue/shared" "3.3.10" + +"@vue/compiler-dom@3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz#753f5ed55f78d33dff04701fad4d76ff0cf81ee5" + integrity sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ== + dependencies: + "@vue/compiler-core" "3.4.15" + "@vue/shared" "3.4.15" + +"@vue/compiler-sfc@3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz#4e5811e681955fcec886cebbec483f6ae463a64b" + integrity sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA== + dependencies: + "@babel/parser" "^7.23.6" + "@vue/compiler-core" "3.4.15" + "@vue/compiler-dom" "3.4.15" + "@vue/compiler-ssr" "3.4.15" + "@vue/shared" "3.4.15" + estree-walker "^2.0.2" + magic-string "^0.30.5" + postcss "^8.4.33" + source-map-js "^1.0.2" + +"@vue/compiler-sfc@^3.3.8": + version "3.3.10" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.3.10.tgz#8eb97d42f276089ec58fd0565ef3a813bceeaa87" + integrity sha512-xpcTe7Rw7QefOTRFFTlcfzozccvjM40dT45JtrE3onGm/jBLZ0JhpKu3jkV7rbDFLeeagR/5RlJ2Y9SvyS0lAg== + dependencies: + "@babel/parser" "^7.23.5" + "@vue/compiler-core" "3.3.10" + "@vue/compiler-dom" "3.3.10" + "@vue/compiler-ssr" "3.3.10" + "@vue/reactivity-transform" "3.3.10" + "@vue/shared" "3.3.10" + estree-walker "^2.0.2" + magic-string "^0.30.5" + postcss "^8.4.32" + source-map-js "^1.0.2" + +"@vue/compiler-ssr@3.3.10": + version "3.3.10" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.3.10.tgz#5a1b14a358cb3960a4edbce0ade90548e452fcaa" + integrity sha512-12iM4jA4GEbskwXMmPcskK5wImc2ohKm408+o9iox3tfN9qua8xL0THIZtoe9OJHnXP4eOWZpgCAAThEveNlqQ== + dependencies: + "@vue/compiler-dom" "3.3.10" + "@vue/shared" "3.3.10" + +"@vue/compiler-ssr@3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz#a910a5b89ba4f0a776e40b63d69bdae2f50616cf" + integrity sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw== + dependencies: + "@vue/compiler-dom" "3.4.15" + "@vue/shared" "3.4.15" + +"@vue/devtools-api@^6.5.0": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.1.tgz#7f71f31e40973eeee65b9a64382b13593fdbd697" + integrity sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA== + +"@vue/reactivity-transform@3.3.10": + version "3.3.10" + resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.3.10.tgz#b045776cc954bb57883fd305db7a200d42993768" + integrity sha512-0xBdk+CKHWT+Gev8oZ63Tc0qFfj935YZx+UAynlutnrDZ4diFCVFMWixn65HzjE3S1iJppWOo6Tt1OzASH7VEg== + dependencies: + "@babel/parser" "^7.23.5" + "@vue/compiler-core" "3.3.10" + "@vue/shared" "3.3.10" + estree-walker "^2.0.2" + magic-string "^0.30.5" + +"@vue/reactivity@3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.15.tgz#ad9d9b83f5398d2e8660ad5cfc0f171e7679a9a1" + integrity sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w== + dependencies: + "@vue/shared" "3.4.15" + +"@vue/runtime-core@3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.15.tgz#f81e2fd2108ea41a6d5c61c2462b11dfb754fdf0" + integrity sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw== + dependencies: + "@vue/reactivity" "3.4.15" + "@vue/shared" "3.4.15" + +"@vue/runtime-dom@3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.15.tgz#108ef86aa7334ead5d6b9c56a7d93679e1e45406" + integrity sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw== + dependencies: + "@vue/runtime-core" "3.4.15" + "@vue/shared" "3.4.15" + csstype "^3.1.3" + +"@vue/server-renderer@3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.15.tgz#34438f998e6f6370fac78883a75efe136631957f" + integrity sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw== + dependencies: + "@vue/compiler-ssr" "3.4.15" + "@vue/shared" "3.4.15" + +"@vue/shared@3.3.10": + version "3.3.10" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.10.tgz#1583a8d85a957d8b819078c465d2a11db7914b2f" + integrity sha512-2y3Y2J1a3RhFa0WisHvACJR2ncvWiVHcP8t0Inxo+NKz+8RKO4ZV8eZgCxRgQoA6ITfV12L4E6POOL9HOU5nqw== + +"@vue/shared@3.4.15", "@vue/shared@^3.4.15": + version "3.4.15" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.15.tgz#e7d2ea050c667480cb5e1a6df2ac13bcd03a8f30" + integrity sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g== + +"@vueuse/core@10.7.2", "@vueuse/core@^10.7.2": + version "10.7.2" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.7.2.tgz#78917803a29a0bca1803a6521fdf7ff873f6e72c" + integrity sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ== + dependencies: + "@types/web-bluetooth" "^0.0.20" + "@vueuse/metadata" "10.7.2" + "@vueuse/shared" "10.7.2" + vue-demi ">=0.14.6" + +"@vueuse/integrations@^10.7.2": + version "10.7.2" + resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.7.2.tgz#763de1337d3925be9097aac9a725eec39d4c8e69" + integrity sha512-+u3RLPFedjASs5EKPc69Ge49WNgqeMfSxFn+qrQTzblPXZg6+EFzhjarS5edj2qAf6xQ93f95TUxRwKStXj/sQ== + dependencies: + "@vueuse/core" "10.7.2" + "@vueuse/shared" "10.7.2" + vue-demi ">=0.14.6" + +"@vueuse/math@^10.7.2": + version "10.7.2" + resolved "https://registry.yarnpkg.com/@vueuse/math/-/math-10.7.2.tgz#df7d6afadfc11cda4f5fd3a561072024641adc65" + integrity sha512-Z1h/kdW5f4c/v/QOpWFFaEx4UaIt7xQTxoDnxQAx1gHGHpGYTtBlQHm80zrRodCz0auyBZMkALkCgKinzGggXw== + dependencies: + "@vueuse/shared" "10.7.2" + vue-demi ">=0.14.6" + +"@vueuse/metadata@10.7.2": + version "10.7.2" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.7.2.tgz#ba0187ce138c287fd80301afc5b0d6a97e563633" + integrity sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ== + +"@vueuse/shared@10.7.2": + version "10.7.2" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.7.2.tgz#746441fbc08072371dd600a55883422c83fd0cab" + integrity sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA== + dependencies: + vue-demi ">=0.14.6" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" + integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== + +accepts@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@8.11.3, acorn@^8.11.3: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + +acorn@^8.10.0, acorn@^8.11.2, acorn@^8.5.0, acorn@^8.6.0, acorn@^8.8.2, acorn@^8.9.0: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + dependencies: + debug "^4.3.4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity 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" + +ansi-colors@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity 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 sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@^3.1.3, anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + +archiver-utils@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-4.0.1.tgz#66ad15256e69589a77f706c90c6dbcc1b2775d2a" + integrity sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg== + dependencies: + glob "^8.0.0" + graceful-fs "^4.2.0" + lazystream "^1.0.0" + lodash "^4.17.15" + normalize-path "^3.0.0" + readable-stream "^3.6.0" + +archiver@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-6.0.1.tgz#d56968d4c09df309435adb5a1bbfc370dae48133" + integrity sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ== + dependencies: + archiver-utils "^4.0.1" + async "^3.2.4" + buffer-crc32 "^0.2.1" + readable-stream "^3.6.0" + readdir-glob "^1.1.2" + tar-stream "^3.0.0" + zip-stream "^5.0.1" + +are-docs-informative@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/are-docs-informative/-/are-docs-informative-0.0.2.tgz#387f0e93f5d45280373d387a59d34c96db321963" + integrity sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig== + +are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +ast-kit@^0.11.2: + version "0.11.3" + resolved "https://registry.yarnpkg.com/ast-kit/-/ast-kit-0.11.3.tgz#47d420dbdd23b4900531e05285e89f0301d2c41f" + integrity sha512-qdwwKEhckRk0XE22/xDdmU3v/60E8Edu4qFhgTLIhGGDs/PAJwLw9pQn8Rj99PitlbBZbYpx0k/lbir4kg0SuA== + dependencies: + "@babel/parser" "^7.23.5" + "@rollup/pluginutils" "^5.1.0" + pathe "^1.1.1" + +ast-kit@^0.9.4: + version "0.9.5" + resolved "https://registry.yarnpkg.com/ast-kit/-/ast-kit-0.9.5.tgz#88c0ba76b6f7f24c04ccf9ae778e33afc187dc80" + integrity sha512-kbL7ERlqjXubdDd+szuwdlQ1xUxEz9mCz1+m07ftNVStgwRb2RWw+U6oKo08PAvOishMxiqz1mlJyLl8yQx2Qg== + dependencies: + "@babel/parser" "^7.22.7" + "@rollup/pluginutils" "^5.0.2" + pathe "^1.1.1" + +ast-walker-scope@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/ast-walker-scope/-/ast-walker-scope-0.5.0.tgz#87e0ca4f34394d11ec4dea5925b8bda80b811819" + integrity sha512-NsyHMxBh4dmdEHjBo1/TBZvCKxffmZxRYhmclfu0PP6Aftre47jOHYaYaNqJcV0bxihxFXhDkzLHUwHc0ocd0Q== + dependencies: + "@babel/parser" "^7.22.7" + ast-kit "^0.9.4" + +async-sema@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/async-sema/-/async-sema-3.1.1.tgz#e527c08758a0f8f6f9f15f799a173ff3c40ea808" + integrity sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg== + +async@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +async@^3.2.4: + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + +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 sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +autoprefixer@^10.4.17: + version "10.4.17" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.17.tgz#35cd5695cbbe82f536a50fa025d561b01fdec8be" + integrity sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg== + dependencies: + browserslist "^4.22.2" + caniuse-lite "^1.0.30001578" + fraction.js "^4.3.7" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +b4a@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" + integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +big-integer@^1.6.44: + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bindings@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +birpc@^0.2.14: + version "0.2.14" + resolved "https://registry.yarnpkg.com/birpc/-/birpc-0.2.14.tgz#4a5498771e6ff24cf8ae5f47faf90e76ca2fce03" + integrity sha512-37FHE8rqsYM5JEKCnXFyHpBCzvgHEExwVVTq+nUmloInU7l8ezD1TpOhKpS8oe1DTYFqEK27rFZVKG43oTqXRA== + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.0.0, browserslist@^4.21.9: + version "4.22.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== + dependencies: + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +browserslist@^4.22.2: + version "4.22.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.3.tgz#299d11b7e947a6b843981392721169e27d60c5a6" + integrity sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A== + dependencies: + caniuse-lite "^1.0.30001580" + electron-to-chromium "^1.4.648" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +buffer-crc32@^0.2.1: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + +builtins@^5.0.0, builtins@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" + +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + +c12@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/c12/-/c12-1.5.1.tgz#41554f3cf6bc63b124e81e2b193f619aa60d4d84" + integrity sha512-BWZRJgDEveT8uI+cliCwvYSSSSvb4xKoiiu5S0jaDbKBopQLQF7E+bq9xKk1pTcG+mUa3yXuFO7bD9d8Lr9Xxg== + dependencies: + chokidar "^3.5.3" + defu "^6.1.2" + dotenv "^16.3.1" + giget "^1.1.3" + jiti "^1.20.0" + mlly "^1.4.2" + ohash "^1.1.3" + pathe "^1.1.1" + perfect-debounce "^1.0.0" + pkg-types "^1.0.3" + rc9 "^2.1.1" + +c12@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/c12/-/c12-1.6.1.tgz#e6d3198d214cce66f82101e58e30daf2a0f58737" + integrity sha512-fAZOi3INDvIbmjuwAVVggusyRTxwNdTAnwLay8IsXwhFzDwPPGzFxzrx6L55CPFGPulUSZI0eyFUvRDXveoE3g== + dependencies: + chokidar "^3.5.3" + defu "^6.1.3" + dotenv "^16.3.1" + giget "^1.2.1" + jiti "^1.21.0" + mlly "^1.4.2" + ohash "^1.1.3" + pathe "^1.1.1" + perfect-debounce "^1.0.0" + pkg-types "^1.0.3" + rc9 "^2.1.1" + +cac@^6.7.14: + version "6.7.14" + resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" + integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== + +cacache@^18.0.0: + version "18.0.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.1.tgz#b026d56ad569e4f73cc07c813b3c66707d0fb142" + integrity sha512-g4Uf2CFZPaxtJKre6qr4zqLDOOPU7bNVhWjlNhvzc51xaTOx2noMOLhfFkTAqwtrAZAKQUuDfyjitzilpA8WsQ== + dependencies: + "@npmcli/fs" "^3.1.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^10.0.1" + minipass "^7.0.3" + minipass-collect "^2.0.1" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + p-map "^4.0.0" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" + +cache-content-type@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" + integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA== + dependencies: + mime-types "^2.1.18" + ylru "^1.2.0" + +callsites@^3.0.0, callsites@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelcase@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity 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.30001565: + version "1.0.30001566" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz#61a8e17caf3752e3e426d4239c549ebbb37fef0d" + integrity sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA== + +caniuse-lite@^1.0.30001578, caniuse-lite@^1.0.30001580: + version "1.0.30001585" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001585.tgz#0b4e848d84919c783b2a41c13f7de8ce96744401" + integrity sha512-yr2BWR1yLXQ8fMpdS/4ZZXpseBgE7o4g41x3a6AJOqZuOi+iE/WdJYAuZ6Y95i4Ohd2Y+9MzIWRR+uGABH4s3Q== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity 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.1, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + +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 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 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 sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== + +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.1, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + 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" + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +ci-info@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.0.0.tgz#65466f8b280fc019b9f50a5388115d17a63a44f2" + integrity sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg== + +citty@^0.1.3, citty@^0.1.4, citty@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.5.tgz#fe37ceae5dc764af75eb2fece99d2bf527ea4e50" + integrity sha512-AS7n5NSc0OQVMV9v6wt3ByujNIrne0/cTjiC2MYqhvao57VNfiuVksTSr2p17nVOhEr2KtqiAkGwHcgMC/qUuQ== + dependencies: + consola "^3.2.3" + +clean-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" + integrity sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw== + dependencies: + escape-string-regexp "^1.0.5" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +clear-module@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/clear-module/-/clear-module-4.1.2.tgz#5a58a5c9f8dccf363545ad7284cad3c887352a80" + integrity sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw== + dependencies: + parent-module "^2.0.0" + resolve-from "^5.0.0" + +clear@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/clear/-/clear-0.1.0.tgz#b81b1e03437a716984fd7ac97c87d73bdfe7048a" + integrity sha512-qMjRnoL+JDPJHeLePZJuao6+8orzHMGP04A8CdwCNsKhRbOnKRjefxONR7bwILT3MHecxKBjHkKL/tkZ8r4Uzw== + +clipboardy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092" + integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg== + dependencies: + arch "^2.2.0" + execa "^5.1.1" + is-wsl "^2.2.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +cluster-key-slot@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" + integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity 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 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 sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-support@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +colord@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== + +colorette@^2.0.20: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commander@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^8.0.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +comment-parser@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.1.tgz#bdafead37961ac079be11eb7ec65c4d021eaf9cc" + integrity sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +compress-commons@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-5.0.1.tgz#e46723ebbab41b50309b27a0e0f6f3baed2d6590" + integrity sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag== + dependencies: + crc-32 "^1.2.0" + crc32-stream "^5.0.0" + normalize-path "^3.0.0" + readable-stream "^3.6.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +consola@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" + integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== + +console-control-strings@^1.0.0, console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + +content-disposition@~0.5.2: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie-es@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.0.0.tgz#4759684af168dfc54365b2c2dda0a8d7ee1e4865" + integrity sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ== + +cookies@~0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" + integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow== + dependencies: + depd "~2.0.0" + keygrip "~1.1.0" + +core-js-compat@^3.34.0: + version "3.35.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.35.1.tgz#215247d7edb9e830efa4218ff719beb2803555e2" + integrity sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw== + dependencies: + browserslist "^4.22.2" + +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 sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +crc-32@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + +crc32-stream@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-5.0.0.tgz#a97d3a802c8687f101c27cc17ca5253327354720" + integrity sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw== + dependencies: + crc-32 "^1.2.0" + readable-stream "^3.4.0" + +create-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-declaration-sorter@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-7.1.1.tgz#9796bcc257b4647c39993bda8d431ce32b666f80" + integrity sha512-dZ3bVTEEc1vxr3Bek9vGwfB5Z6ESPULhcRvO472mfjVnj8jRcTnKO8/JTczlvxM10Myb+wBM++1MtdO76eWcaQ== + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + +css-tree@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== + dependencies: + mdn-data "2.0.28" + source-map-js "^1.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-default@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-6.0.3.tgz#b4ce755974f4dc8d3d09ac13bb6281cce3ced45e" + integrity sha512-4y3H370aZCkT9Ev8P4SO4bZbt+AExeKhh8wTbms/X7OLDo5E7AYUUy6YPxa/uF5Grf+AJwNcCnxKhZynJ6luBA== + dependencies: + css-declaration-sorter "^7.1.1" + cssnano-utils "^4.0.1" + postcss-calc "^9.0.1" + postcss-colormin "^6.0.2" + postcss-convert-values "^6.0.2" + postcss-discard-comments "^6.0.1" + postcss-discard-duplicates "^6.0.1" + postcss-discard-empty "^6.0.1" + postcss-discard-overridden "^6.0.1" + postcss-merge-longhand "^6.0.2" + postcss-merge-rules "^6.0.3" + postcss-minify-font-values "^6.0.1" + postcss-minify-gradients "^6.0.1" + postcss-minify-params "^6.0.2" + postcss-minify-selectors "^6.0.2" + postcss-normalize-charset "^6.0.1" + postcss-normalize-display-values "^6.0.1" + postcss-normalize-positions "^6.0.1" + postcss-normalize-repeat-style "^6.0.1" + postcss-normalize-string "^6.0.1" + postcss-normalize-timing-functions "^6.0.1" + postcss-normalize-unicode "^6.0.2" + postcss-normalize-url "^6.0.1" + postcss-normalize-whitespace "^6.0.1" + postcss-ordered-values "^6.0.1" + postcss-reduce-initial "^6.0.2" + postcss-reduce-transforms "^6.0.1" + postcss-svgo "^6.0.2" + postcss-unique-selectors "^6.0.2" + +cssnano-utils@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-4.0.1.tgz#fd18b42f95938bf55ab47967705355d6047bf1da" + integrity sha512-6qQuYDqsGoiXssZ3zct6dcMxiqfT6epy7x4R0TQJadd4LWO3sPR6JH6ZByOvVLoZ6EdwPGgd7+DR1EmX3tiXQQ== + +cssnano@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-6.0.3.tgz#46db972da71aa159437287fb4c6bc9c5d3cc5d93" + integrity sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw== + dependencies: + cssnano-preset-default "^6.0.3" + lilconfig "^3.0.0" + +csso@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== + dependencies: + css-tree "~2.2.0" + +csstype@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +dayjs@^1.11.10: + version "1.11.10" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" + integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^3.1.0, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw== + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + +defu@^6.0.0, defu@^6.1.2, defu@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.3.tgz#6d7f56bc61668e844f9f593ace66fd67ef1205fd" + integrity sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ== + +defu@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" + integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + +depd@2.0.0, depd@^2.0.0, depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destr@^2.0.0, destr@^2.0.1, destr@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.2.tgz#8d3c0ee4ec0a76df54bc8b819bca215592a8c218" + integrity sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg== + +destroy@1.2.0, destroy@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== + +detect-libc@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== + +devalue@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/devalue/-/devalue-4.3.2.tgz#cc44e4cf3872ac5a78229fbce3b77e57032727b5" + integrity sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg== + +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +diff@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dot-prop@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-8.0.2.tgz#afda6866610684dd155a96538f8efcdf78a27f18" + integrity sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ== + dependencies: + type-fest "^3.8.0" + +dotenv@^16.3.1: + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + +dotenv@^16.4.1: + version "16.4.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.1.tgz#1d9931f1d3e5d2959350d1250efab299561f7f11" + integrity sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ== + +duplexer@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.601: + version "1.4.608" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.608.tgz#ff567c51dde4892ae330860c7d9f19571e9e1d69" + integrity sha512-J2f/3iIIm3Mo0npneITZ2UPe4B1bg8fTNrFjD8715F/k1BvbviRuqYGkET1PgprrczXYTHFvotbBOmUp6KE0uA== + +electron-to-chromium@^1.4.648: + version "1.4.659" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.659.tgz#e93af8119b6610cb4d2614a47508a74543b96ce5" + integrity sha512-sRJ3nV3HowrYpBtPF9bASQV7OW49IgZC01Xiq43WfSE3RTCkK0/JidoCmR73Hyc1mN+l/H4Yqx0eNiomvExFZg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +encodeurl@^1.0.2, encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +enhanced-resolve@^5.14.1: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^4.2.0, entities@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +error-stack-parser-es@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/error-stack-parser-es/-/error-stack-parser-es-0.1.1.tgz#9c1d2bbfbba8b51670062e7fbf43c6bcfb6eb4da" + integrity sha512-g/9rfnvnagiNf+DRMHEVGuGuIBlCIMDFoTA616HaP2l9PlCjGjVhD98PNbVSJvmK4TttqT5mV5tInMhoFgi+aA== + +esbuild@^0.19.3: + version "0.19.12" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.12.tgz#dc82ee5dc79e82f5a5c3b4323a2a641827db3e04" + integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.19.12" + "@esbuild/android-arm" "0.19.12" + "@esbuild/android-arm64" "0.19.12" + "@esbuild/android-x64" "0.19.12" + "@esbuild/darwin-arm64" "0.19.12" + "@esbuild/darwin-x64" "0.19.12" + "@esbuild/freebsd-arm64" "0.19.12" + "@esbuild/freebsd-x64" "0.19.12" + "@esbuild/linux-arm" "0.19.12" + "@esbuild/linux-arm64" "0.19.12" + "@esbuild/linux-ia32" "0.19.12" + "@esbuild/linux-loong64" "0.19.12" + "@esbuild/linux-mips64el" "0.19.12" + "@esbuild/linux-ppc64" "0.19.12" + "@esbuild/linux-riscv64" "0.19.12" + "@esbuild/linux-s390x" "0.19.12" + "@esbuild/linux-x64" "0.19.12" + "@esbuild/netbsd-x64" "0.19.12" + "@esbuild/openbsd-x64" "0.19.12" + "@esbuild/sunos-x64" "0.19.12" + "@esbuild/win32-arm64" "0.19.12" + "@esbuild/win32-ia32" "0.19.12" + "@esbuild/win32-x64" "0.19.12" + +esbuild@^0.19.8: + version "0.19.8" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.19.8.tgz#ad05b72281d84483fa6b5345bd246c27a207b8f1" + integrity sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w== + optionalDependencies: + "@esbuild/android-arm" "0.19.8" + "@esbuild/android-arm64" "0.19.8" + "@esbuild/android-x64" "0.19.8" + "@esbuild/darwin-arm64" "0.19.8" + "@esbuild/darwin-x64" "0.19.8" + "@esbuild/freebsd-arm64" "0.19.8" + "@esbuild/freebsd-x64" "0.19.8" + "@esbuild/linux-arm" "0.19.8" + "@esbuild/linux-arm64" "0.19.8" + "@esbuild/linux-ia32" "0.19.8" + "@esbuild/linux-loong64" "0.19.8" + "@esbuild/linux-mips64el" "0.19.8" + "@esbuild/linux-ppc64" "0.19.8" + "@esbuild/linux-riscv64" "0.19.8" + "@esbuild/linux-s390x" "0.19.8" + "@esbuild/linux-x64" "0.19.8" + "@esbuild/netbsd-x64" "0.19.8" + "@esbuild/openbsd-x64" "0.19.8" + "@esbuild/sunos-x64" "0.19.8" + "@esbuild/win32-arm64" "0.19.8" + "@esbuild/win32-ia32" "0.19.8" + "@esbuild/win32-x64" "0.19.8" + +esbuild@^0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.0.tgz#a7170b63447286cd2ff1f01579f09970e6965da4" + integrity sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.20.0" + "@esbuild/android-arm" "0.20.0" + "@esbuild/android-arm64" "0.20.0" + "@esbuild/android-x64" "0.20.0" + "@esbuild/darwin-arm64" "0.20.0" + "@esbuild/darwin-x64" "0.20.0" + "@esbuild/freebsd-arm64" "0.20.0" + "@esbuild/freebsd-x64" "0.20.0" + "@esbuild/linux-arm" "0.20.0" + "@esbuild/linux-arm64" "0.20.0" + "@esbuild/linux-ia32" "0.20.0" + "@esbuild/linux-loong64" "0.20.0" + "@esbuild/linux-mips64el" "0.20.0" + "@esbuild/linux-ppc64" "0.20.0" + "@esbuild/linux-riscv64" "0.20.0" + "@esbuild/linux-s390x" "0.20.0" + "@esbuild/linux-x64" "0.20.0" + "@esbuild/netbsd-x64" "0.20.0" + "@esbuild/openbsd-x64" "0.20.0" + "@esbuild/sunos-x64" "0.20.0" + "@esbuild/win32-arm64" "0.20.0" + "@esbuild/win32-ia32" "0.20.0" + "@esbuild/win32-x64" "0.20.0" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@^1.0.3, escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +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 sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +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 sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + +eslint-compat-utils@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz#f45e3b5ced4c746c127cf724fb074cd4e730d653" + integrity sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg== + +eslint-compat-utils@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.4.1.tgz#498d9dad03961174a283f7741838a3fbe4a34e89" + integrity sha512-5N7ZaJG5pZxUeNNJfUchurLVrunD1xJvyg5kYOIVF8kg1f3ajTikmAu/5fZ9w100omNPOoMjngRszh/Q/uFGMg== + dependencies: + semver "^7.5.4" + +eslint-config-flat-gitignore@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.2.tgz#ae79caf65adb308ba8fc727c53d11562554a9b40" + integrity sha512-PcBsqtd5QHEZH4ROvpnRN4EP0qcHh9voCCHgtyHxnJZHGspJREcZn7oPqRG/GfWt9m3C0fkC2l5CuBtMig2wXQ== + dependencies: + parse-gitignore "^2.0.0" + +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + +eslint-merge-processors@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/eslint-merge-processors/-/eslint-merge-processors-0.1.0.tgz#30ac4c59725a63d12a9677de7d2b2ec2a09fb779" + integrity sha512-IvRXXtEajLeyssvW4wJcZ2etxkR9mUf4zpNwgI+m/Uac9RfXHskuJefkHUcawVzePnd6xp24enp5jfgdHzjRdQ== + +eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + dependencies: + debug "^3.2.7" + +eslint-plugin-antfu@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-antfu/-/eslint-plugin-antfu-2.1.2.tgz#3f35d4f78187d3e3b72657030a1cc340740dc648" + integrity sha512-s7ZTOM3uq0iqpp6gF0UEotnvup7f2PHBUftCytLZX0+6C9j9KadKZQh6bVVngAyFgsmeD9+gcBopOYLClb2oDg== + +eslint-plugin-es-x@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz#d08d9cd155383e35156c48f736eb06561d07ba92" + integrity sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ== + dependencies: + "@eslint-community/eslint-utils" "^4.1.2" + "@eslint-community/regexpp" "^4.6.0" + eslint-compat-utils "^0.1.2" + +eslint-plugin-eslint-comments@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa" + integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + +eslint-plugin-i@^2.29.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-i/-/eslint-plugin-i-2.29.1.tgz#97e4a055b6b2040cec0842700dd1d2066773b5a4" + integrity sha512-ORizX37MelIWLbMyqI7hi8VJMf7A0CskMmYkB+lkCX3aF4pkGV7kwx5bSEb4qx7Yce2rAf9s34HqDRPjGRZPNQ== + dependencies: + debug "^4.3.4" + doctrine "^3.0.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + get-tsconfig "^4.7.2" + is-glob "^4.0.3" + minimatch "^3.1.2" + semver "^7.5.4" + +eslint-plugin-jsdoc@^48.0.4: + version "48.0.6" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.0.6.tgz#be74ff68b517417eec42df5908201194ebdfb5ee" + integrity sha512-LgwXOX6TWxxFYcbdVe+BJ94Kl/pgjSPYHLzqEdAMXTA1BH9WDx7iJ+9/iDajPF64LtzWX8C1mCfpbMZjJGhAOw== + dependencies: + "@es-joy/jsdoccomment" "~0.42.0" + are-docs-informative "^0.0.2" + comment-parser "1.4.1" + debug "^4.3.4" + escape-string-regexp "^4.0.0" + esquery "^1.5.0" + is-builtin-module "^3.2.1" + semver "^7.6.0" + spdx-expression-parse "^4.0.0" + +eslint-plugin-jsonc@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.13.0.tgz#e05f88d3671c08ca96e87b5be6a4cfe8d66e6746" + integrity sha512-2wWdJfpO/UbZzPDABuUVvlUQjfMJa2p2iQfYt/oWxOMpXCcjuiMUSaA02gtY/Dbu82vpaSqc+O7Xq6ECHwtIxA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + eslint-compat-utils "^0.4.0" + espree "^9.6.1" + graphemer "^1.4.0" + jsonc-eslint-parser "^2.0.4" + natural-compare "^1.4.0" + synckit "^0.6.0" + +eslint-plugin-markdown@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.1.tgz#fc6765bdb5f82a75e2438d7fac619602f2abc38c" + integrity sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A== + dependencies: + mdast-util-from-markdown "^0.8.5" + +eslint-plugin-n@^16.6.2: + version "16.6.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz#6a60a1a376870064c906742272074d5d0b412b0b" + integrity sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + builtins "^5.0.1" + eslint-plugin-es-x "^7.5.0" + get-tsconfig "^4.7.0" + globals "^13.24.0" + ignore "^5.2.4" + is-builtin-module "^3.2.1" + is-core-module "^2.12.1" + minimatch "^3.1.2" + resolve "^1.22.2" + semver "^7.5.3" + +eslint-plugin-no-only-tests@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz#f38e4935c6c6c4842bf158b64aaa20c366fe171b" + integrity sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw== + +eslint-plugin-perfectionist@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.5.0.tgz#f7f83733e18d1b26694c4aab1b986eac836773a7" + integrity sha512-F6XXcq4mKKUe/SREoMGQqzgw6cgCgf3pFzkFfQVIGtqD1yXVpQjnhTepzhBeZfxZwgMzR9HO4yH4CUhIQ2WBcQ== + dependencies: + "@typescript-eslint/utils" "^6.13.0" + minimatch "^9.0.3" + natural-compare-lite "^1.4.0" + +eslint-plugin-toml@^0.9.2: + version "0.9.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-toml/-/eslint-plugin-toml-0.9.2.tgz#f9489500bb6070115b75098caa08316cc53a97c4" + integrity sha512-ri0xf63PYf3pIq/WY9BIwrqxZmGTIwSkAO0bHddI0ajUwN4KGz6W8vOvdXFHOpRdRfzxlmXze/vfsY/aTEXESg== + dependencies: + debug "^4.1.1" + eslint-compat-utils "^0.4.0" + lodash "^4.17.19" + toml-eslint-parser "^0.9.0" + +eslint-plugin-unicorn@^50.0.1: + version "50.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-50.0.1.tgz#e539cdb02dfd893c603536264c4ed9505b70e3bf" + integrity sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + "@eslint-community/eslint-utils" "^4.4.0" + "@eslint/eslintrc" "^2.1.4" + ci-info "^4.0.0" + clean-regexp "^1.0.0" + core-js-compat "^3.34.0" + esquery "^1.5.0" + indent-string "^4.0.0" + is-builtin-module "^3.2.1" + jsesc "^3.0.2" + pluralize "^8.0.0" + read-pkg-up "^7.0.1" + regexp-tree "^0.1.27" + regjsparser "^0.10.0" + semver "^7.5.4" + strip-indent "^3.0.0" + +eslint-plugin-unused-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.0.0.tgz#d25175b0072ff16a91892c3aa72a09ca3a9e69e7" + integrity sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw== + dependencies: + eslint-rule-composer "^0.3.0" + +eslint-plugin-vitest@^0.3.21: + version "0.3.22" + resolved "https://registry.yarnpkg.com/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.22.tgz#207eb4630768f6400cd91a6df23688e8a1fd0898" + integrity sha512-atkFGQ7aVgcuSeSMDqnyevIyUpfBPMnosksgEPrKE7Y8xQlqG/5z2IQ6UDau05zXaaFv7Iz8uzqvIuKshjZ0Zw== + dependencies: + "@typescript-eslint/utils" "^6.21.0" + +eslint-plugin-vue@^9.21.1: + version "9.21.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz#da5629efa48527cec98278dca0daa90fada4caf7" + integrity sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + natural-compare "^1.4.0" + nth-check "^2.1.1" + postcss-selector-parser "^6.0.13" + semver "^7.5.4" + vue-eslint-parser "^9.4.2" + xml-name-validator "^4.0.0" + +eslint-plugin-yml@^1.12.2: + version "1.12.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-yml/-/eslint-plugin-yml-1.12.2.tgz#e75d27cfbf5c0297c509b409fd8d43dfc2c4dc8b" + integrity sha512-hvS9p08FhPT7i/ynwl7/Wt7ke7Rf4P2D6fT8lZlL43peZDTsHtH2A0SIFQ7Kt7+mJ6if6P+FX3iJhMkdnxQwpg== + dependencies: + debug "^4.3.2" + eslint-compat-utils "^0.4.0" + lodash "^4.17.21" + natural-compare "^1.4.0" + yaml-eslint-parser "^1.2.1" + +eslint-processor-vue-blocks@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-0.1.1.tgz#485a57c92c726ac60e86f5c9f4d73185ba6aab94" + integrity sha512-9+dU5lU881log570oBwpelaJmOfOzSniben7IWEDRYQPPWwlvaV7NhOtsTuUWDqpYT+dtKKWPsgz4OkOi+aZnA== + +eslint-rule-composer@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" + integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== + +eslint-scope@^7.1.1, eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.56.0: + version "8.56.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" + integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.56.0" + "@humanwhocodes/config-array" "^0.11.13" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.0.0.tgz#ce1411bb31a514797dbd29ee360e4f3404643096" + integrity sha512-gdlKrfXQWv/3vubKqeQIiBUoWeknNQVEDpKD7OD3bC53g5EKISTuhcIoA1H1e+zqIuosdKrKuTDMmj8eFfhOnA== + dependencies: + acorn "^8.11.3" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +espree@^9.0.0, espree@^9.3.1, espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.0, esquery@^1.4.2, esquery@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-walker@2.0.2, estree-walker@^2.0.1, estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +estree-walker@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@^1.8.1, etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +execa@^5.0.0, execa@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +execa@^7.1.1, execa@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" + integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + +execa@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" + +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + +externality@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/externality/-/externality-1.0.2.tgz#a027f8cfd995c42fd35a8d794cfc224d4a5840c0" + integrity sha512-LyExtJWKxtgVzmgtEHyQtLFpw1KFhQphF9nTG8TpAIVkiI/xQ3FJh75tRFLYl4hkn7BNIIdLJInuDAavX35pMw== + dependencies: + enhanced-resolve "^5.14.1" + mlly "^1.3.0" + pathe "^1.1.1" + ufo "^1.1.2" + +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 sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-fifo@^1.1.0, fast-fifo@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + +fast-glob@^3.2.7, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1, fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + 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-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 sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +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 sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +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 sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +fraction.js@^4.3.7: + version "4.3.7" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" + integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== + +fresh@0.5.2, fresh@~0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^11.1.0, fs-extra@^11.1.1, fs-extra@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity 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-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-minipass@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" + integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== + dependencies: + minipass "^7.0.3" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +fuse.js@^6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.6.2.tgz#fe463fed4b98c0226ac3da2856a415576dc9a111" + integrity sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA== + +gauge@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" + integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + object-assign "^4.1.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" + +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 sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +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 sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-port-please@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/get-port-please/-/get-port-please-3.1.1.tgz#2556623cddb4801d823c0a6a15eec038abb483be" + integrity sha512-3UBAyM3u4ZBVYDsxOQfJDxEa6XTbpBDrOjp4mf7ExFRt5BKs/QywQQiJsh2B+hxcZLSapWqCRvElUe8DnKcFHA== + +get-port-please@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/get-port-please/-/get-port-please-3.1.2.tgz#502795e56217128e4183025c89a48c71652f4e49" + integrity sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ== + +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + +get-tsconfig@^4.7.0, get-tsconfig@^4.7.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.2.tgz#0dcd6fb330391d46332f4c6c1bf89a6514c2ddce" + integrity sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A== + dependencies: + resolve-pkg-maps "^1.0.0" + +giget@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/giget/-/giget-1.1.3.tgz#574ed901031eafa732347a7990d84bfa6484c51a" + integrity sha512-zHuCeqtfgqgDwvXlR84UNgnJDuUHQcNI5OqWqFxxuk2BshuKbYhJWdxBsEo4PvKqoGh23lUAIvBNpChMLv7/9Q== + dependencies: + colorette "^2.0.20" + defu "^6.1.2" + https-proxy-agent "^7.0.2" + mri "^1.2.0" + node-fetch-native "^1.4.0" + pathe "^1.1.1" + tar "^6.2.0" + +giget@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/giget/-/giget-1.2.1.tgz#4f42779aae57a5f664a1c4d50401b008e9810f4c" + integrity sha512-4VG22mopWtIeHwogGSy1FViXVo0YT+m6BrqZfz0JJFwbSsePsCdOzdLIIli5BtMp7Xe8f/o2OmBpQX2NBOC24g== + dependencies: + citty "^0.1.5" + consola "^3.2.3" + defu "^6.1.3" + node-fetch-native "^1.6.1" + nypm "^0.3.3" + ohash "^1.1.3" + pathe "^1.1.1" + tar "^6.2.0" + +git-config-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-config-path/-/git-config-path-2.0.0.tgz#62633d61af63af4405a5024efd325762f58a181b" + integrity sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA== + +git-up@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" + integrity sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ== + dependencies: + is-ssh "^1.4.0" + parse-url "^8.1.0" + +git-url-parse@^13.1.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.1.tgz#664bddf0857c6a75b3c1f0ae6239abb08a1486d4" + integrity sha512-PCFJyeSSdtnbfhSNRw9Wk96dDCNx+sogTe4YNXeXSJxt7xz5hvXekuRn9JX7m+Mf4OscCu8h+mtAl3+h5Fo8lQ== + dependencies: + git-up "^7.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 sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + 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" + +glob@^10.2.2, glob@^10.3.10: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +glob@^7.1.3, glob@^7.2.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^8.0.0, glob@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +global-directory@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/global-directory/-/global-directory-4.0.1.tgz#4d7ac7cfd2cb73f304c53b8810891748df5e361e" + integrity sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q== + dependencies: + ini "4.1.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== + dependencies: + type-fest "^0.20.2" + +globals@^13.24.0: + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +globby@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-14.0.0.tgz#ea9c062a3614e33f516804e778590fcf055256b9" + integrity sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ== + dependencies: + "@sindresorhus/merge-streams" "^1.0.0" + fast-glob "^3.3.2" + ignore "^5.2.4" + path-type "^5.0.0" + slash "^5.1.0" + unicorn-magic "^0.1.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +gzip-size@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-7.0.0.tgz#9f9644251f15bc78460fccef4055ae5a5562ac60" + integrity sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA== + dependencies: + duplexer "^0.1.2" + +h3@^1.10.0, h3@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/h3/-/h3-1.10.1.tgz#221634ca9bdb216a6b359bd2915be466a179b8a1" + integrity sha512-UBAUp47hmm4BB5/njB4LrEa9gpuvZj4/Qf/ynSMzO6Ku2RXaouxEfiG2E2IFnv6fxbhAkzjasDxmo6DFdEeXRg== + dependencies: + cookie-es "^1.0.0" + defu "^6.1.4" + destr "^2.0.2" + iron-webcrypto "^1.0.0" + ohash "^1.1.3" + radix3 "^1.1.0" + ufo "^1.3.2" + uncrypto "^0.1.3" + unenv "^1.9.0" + +h3@^1.8.1, h3@^1.8.2, h3@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/h3/-/h3-1.9.0.tgz#c5f512a93026df9837db6f30c9ef51135dd46752" + integrity sha512-+F3ZqrNV/CFXXfZ2lXBINHi+rM4Xw3CDC5z2CDK3NMPocjonKipGLLDSkrqY9DOrioZNPTIdDMWfQKm//3X2DA== + dependencies: + cookie-es "^1.0.0" + defu "^6.1.3" + destr "^2.0.2" + iron-webcrypto "^1.0.0" + radix3 "^1.1.0" + ufo "^1.3.2" + uncrypto "^0.1.3" + unenv "^1.7.4" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity 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 sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + +hash-sum@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" + integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +hookable@^5.5.3: + version "5.5.3" + resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d" + integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ== + +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 sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hosted-git-info@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.1.tgz#9985fcb2700467fecf7f33a4d4874e30680b5322" + integrity sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA== + dependencies: + lru-cache "^10.0.1" + +html-tags@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== + +http-assert@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f" + integrity sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w== + dependencies: + deep-equal "~1.0.1" + http-errors "~1.8.0" + +http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-errors@2.0.0, http-errors@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.8.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" + integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + +http-shutdown@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/http-shutdown/-/http-shutdown-1.2.2.tgz#41bc78fc767637c4c95179bc492f312c0ae64c5f" + integrity sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw== + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +https-proxy-agent@^7.0.1, https-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" + integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== + dependencies: + agent-base "^7.0.2" + debug "4" + +httpxy@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/httpxy/-/httpxy-0.1.5.tgz#fd2401206e0b5d919aeda25e967ece0f1a6c8569" + integrity sha512-hqLDO+rfststuyEUTWObQK6zHEEmZ/kaIP2/zclGGZn6X8h/ESTWg+WKecQ/e5k4nPswjzZD+q2VqZIbr15CoQ== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +ignore-walk@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.4.tgz#89950be94b4f522225eb63a13c56badb639190e9" + integrity sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw== + dependencies: + minimatch "^9.0.0" + +ignore@^5.0.5, ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + +ignore@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + +image-meta@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/image-meta/-/image-meta-0.2.0.tgz#ea28d05d52f5ad35f75b14f46278a44d626f48bc" + integrity sha512-ZBGjl0ZMEMeOC3Ns0wUF/5UdUmr3qQhBSCniT0LxOgGGIRHiNFOkMtIHB7EOznRU47V2AxPgiVP+s+0/UCU0Hg== + +immutable@^4.0.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ini@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1" + integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g== + +ini@^1.3.5: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +ioredis@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" + integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== + dependencies: + "@ioredis/commands" "^1.1.1" + cluster-key-slot "^1.1.0" + debug "^4.3.4" + denque "^2.1.0" + lodash.defaults "^4.2.0" + lodash.isarguments "^3.1.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" + +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + +iron-webcrypto@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.0.0.tgz#e3b689c0c61b434a0a4cb82d0aeabbc8b672a867" + integrity sha512-anOK1Mktt8U1Xi7fCM3RELTuYbnFikQY5VtrDj7kPgpejV7d43tWKhzgioO0zpkazLEL/j/iayRqnJhrGfqUsg== + +is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + integrity 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 sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^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 sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +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 sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-builtin-module@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + +is-core-module@^2.12.1, is-core-module@^2.13.0, is-core-module@^2.8.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.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 sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +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 sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity 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 sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + +is-installed-globally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-1.0.0.tgz#08952c43758c33d815692392f7f8437b9e436d5a" + integrity sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ== + dependencies: + global-directory "^4.0.1" + is-path-inside "^4.0.0" + +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-path-inside@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-4.0.0.tgz#805aeb62c47c1b12fc3fd13bfb3ed1e7430071db" + integrity sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA== + +is-primitive@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-3.0.1.tgz#98c4db1abff185485a657fc2905052b940524d05" + integrity sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w== + +is-promise@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" + integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== + +is-reference@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== + dependencies: + "@types/estree" "*" + +is-ssh@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.0.tgz#4f8220601d2839d8fa624b3106f8e8884f01b8b2" + integrity sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ== + dependencies: + protocols "^2.0.1" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-wsl@^2.1.1, is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity 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 sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isexe@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d" + integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ== + +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jiti@^1.19.1, jiti@^1.20.0, jiti@^1.21.0: + version "1.21.0" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" + integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^8.0.2: + version "8.0.3" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-8.0.3.tgz#1c407ec905643603b38b6be6977300406ec48775" + integrity sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsdoc-type-pratt-parser@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz#136f0571a99c184d84ec84662c45c29ceff71114" + integrity sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ== + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +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 sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-parse-even-better-errors@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" + integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== + +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 sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +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 sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonc-eslint-parser@^2.0.4, jsonc-eslint-parser@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz#74ded53f9d716e8d0671bd167bf5391f452d5461" + integrity sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg== + dependencies: + acorn "^8.5.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" + semver "^7.3.5" + +jsonc-parser@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonparse@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== + +keygrip@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" + integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== + dependencies: + tsscmp "1.0.6" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +klona@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== + +knitwork@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/knitwork/-/knitwork-1.0.0.tgz#38d124dead875bee5feea1733632295af58a49d2" + integrity sha512-dWl0Dbjm6Xm+kDxhPQJsCBTxrJzuGl0aP9rhr+TG8D3l+GL90N8O8lYUi7dTSAN2uuDqCtNgb6aEuQH5wsiV8Q== + +koa-compose@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" + integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== + +koa-convert@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5" + integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA== + dependencies: + co "^4.6.0" + koa-compose "^4.1.0" + +koa-send@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.1.tgz#39dceebfafb395d0d60beaffba3a70b4f543fe79" + integrity sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ== + dependencies: + debug "^4.1.1" + http-errors "^1.7.3" + resolve-path "^1.4.0" + +koa-static@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943" + integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ== + dependencies: + debug "^3.1.0" + koa-send "^5.0.0" + +koa@^2.14.2: + version "2.14.2" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.14.2.tgz#a57f925c03931c2b4d94b19d2ebf76d3244863fc" + integrity sha512-VFI2bpJaodz6P7x2uyLiX6RLYpZmOJqNmoCst/Yyd7hQlszyPwG/I9CQJ63nOtKSxpt5M7NH67V6nJL2BwCl7g== + dependencies: + accepts "^1.3.5" + cache-content-type "^1.0.0" + content-disposition "~0.5.2" + content-type "^1.0.4" + cookies "~0.8.0" + debug "^4.3.2" + delegates "^1.0.0" + depd "^2.0.0" + destroy "^1.0.4" + encodeurl "^1.0.2" + escape-html "^1.0.3" + fresh "~0.5.2" + http-assert "^1.3.0" + http-errors "^1.6.3" + is-generator-function "^1.0.7" + koa-compose "^4.1.0" + koa-convert "^2.0.0" + on-finished "^2.3.0" + only "~0.0.2" + parseurl "^1.3.2" + statuses "^1.5.0" + type-is "^1.6.16" + vary "^1.1.2" + +kolorist@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.8.0.tgz#edddbbbc7894bc13302cdf740af6374d4a04743c" + integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== + +launch-editor@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.1.tgz#f259c9ef95cbc9425620bbbd14b468fcdb4ffe3c" + integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.8.1" + +lazystream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== + dependencies: + readable-stream "^2.0.5" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lilconfig@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc" + integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +listhen@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/listhen/-/listhen-1.5.5.tgz#58915512af70f770aa3e9fb19367adf479bb58c4" + integrity sha512-LXe8Xlyh3gnxdv4tSjTjscD1vpr/2PRpzq8YIaMJgyKzRG8wdISlWVWnGThJfHnlJ6hmLt2wq1yeeix0TEbuoA== + dependencies: + "@parcel/watcher" "^2.3.0" + "@parcel/watcher-wasm" "2.3.0" + citty "^0.1.4" + clipboardy "^3.0.0" + consola "^3.2.3" + defu "^6.1.2" + get-port-please "^3.1.1" + h3 "^1.8.1" + http-shutdown "^1.2.2" + jiti "^1.20.0" + mlly "^1.4.2" + node-forge "^1.3.1" + pathe "^1.1.1" + std-env "^3.4.3" + ufo "^1.3.0" + untun "^0.1.2" + uqr "^0.1.2" + +local-pkg@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963" + integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g== + +local-pkg@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.5.0.tgz#093d25a346bae59a99f80e75f6e9d36d7e8c925c" + integrity sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg== + dependencies: + mlly "^1.4.2" + pkg-types "^1.0.3" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA== + +lodash.castarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" + integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q== + +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== + +lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity 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 sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity 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 sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^10.0.1, lru-cache@^10.0.2, "lru-cache@^9.1.1 || ^10.0.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity 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 sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string-ast@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/magic-string-ast/-/magic-string-ast-0.3.0.tgz#8fc83ac6d084c5a342645a30354184a6e0ab4382" + integrity sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA== + dependencies: + magic-string "^0.30.2" + +magic-string@^0.30.0, magic-string@^0.30.2, magic-string@^0.30.3, magic-string@^0.30.4, magic-string@^0.30.5: + version "0.30.5" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" + integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + +magic-string@^0.30.6: + version "0.30.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.7.tgz#0cecd0527d473298679da95a2d7aeb8c64048505" + integrity sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + +magicast@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.2.tgz#42dcade5573ed8f10f5540f9d04964e21dba9130" + integrity sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg== + dependencies: + "@babel/parser" "^7.23.3" + "@babel/types" "^7.23.3" + source-map-js "^1.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 sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-fetch-happen@^13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz#705d6f6cbd7faecb8eac2432f551e49475bfedf0" + integrity sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A== + dependencies: + "@npmcli/agent" "^2.0.0" + cacache "^18.0.0" + http-cache-semantics "^4.1.1" + is-lambda "^1.0.1" + minipass "^7.0.2" + minipass-fetch "^3.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + ssri "^10.0.0" + +mdast-util-from-markdown@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c" + integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-string "^2.0.0" + micromark "~2.11.0" + parse-entities "^2.0.0" + unist-util-stringify-position "^2.0.0" + +mdast-util-to-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" + integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== + +mdn-data@2.0.28: + version "2.0.28" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== + +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity 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 sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromark@~2.11.0: + version "2.11.4" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a" + integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== + dependencies: + debug "^4.0.0" + parse-entities "^2.0.0" + +micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.18, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + +mini-svg-data-uri@^1.2.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939" + integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg== + +minimatch@9.0.3, minimatch@^9.0.0, minimatch@^9.0.1, minimatch@^9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1, minimatch@^5.1.0: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +minipass-collect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-2.0.1.tgz#1621bc77e12258a12c60d34e2276ec5c20680863" + integrity sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw== + dependencies: + minipass "^7.0.3" + +minipass-fetch@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" + integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== + dependencies: + minipass "^7.0.3" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-json-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" + integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + dependencies: + jsonparse "^1.3.1" + minipass "^3.0.0" + +minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.2, minipass@^7.0.3: + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + +minizlib@^2.1.1, minizlib@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mlly@^1.2.0, mlly@^1.3.0, mlly@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.2.tgz#7cf406aa319ff6563d25da6b36610a93f2a8007e" + integrity sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg== + dependencies: + acorn "^8.10.0" + pathe "^1.1.1" + pkg-types "^1.0.3" + ufo "^1.3.0" + +mlly@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.5.0.tgz#8428a4617d54cc083d3009030ac79739a0e5447a" + integrity sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ== + dependencies: + acorn "^8.11.3" + pathe "^1.1.2" + pkg-types "^1.0.3" + ufo "^1.3.2" + +mri@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" + integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== + +mrmime@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" + integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== + +mrmime@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.0.tgz#151082a6e06e59a9a39b46b3e14d5cfe92b3abb4" + integrity sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +nanoid@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e" + integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw== + +napi-wasm@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/napi-wasm/-/napi-wasm-1.1.0.tgz#bbe617823765ae9c1bc12ff5942370eae7b2ba4e" + integrity sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3, negotiator@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +nitropack@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/nitropack/-/nitropack-2.8.1.tgz#9132cf8c01417c32ee45338e1d3fd00cac6219f8" + integrity sha512-pODv2kEEzZSDQR+1UMXbGyNgMedUDq/qUomtiAnQKQvLy52VGlecXO1xDfH3i0kP1yKEcKTnWsx1TAF5gHM7xQ== + dependencies: + "@cloudflare/kv-asset-handler" "^0.3.0" + "@netlify/functions" "^2.4.0" + "@rollup/plugin-alias" "^5.1.0" + "@rollup/plugin-commonjs" "^25.0.7" + "@rollup/plugin-inject" "^5.0.5" + "@rollup/plugin-json" "^6.0.1" + "@rollup/plugin-node-resolve" "^15.2.3" + "@rollup/plugin-replace" "^5.0.5" + "@rollup/plugin-terser" "^0.4.4" + "@rollup/plugin-wasm" "^6.2.2" + "@rollup/pluginutils" "^5.0.5" + "@types/http-proxy" "^1.17.14" + "@vercel/nft" "^0.24.3" + archiver "^6.0.1" + c12 "^1.5.1" + chalk "^5.3.0" + chokidar "^3.5.3" + citty "^0.1.5" + consola "^3.2.3" + cookie-es "^1.0.0" + defu "^6.1.3" + destr "^2.0.2" + dot-prop "^8.0.2" + esbuild "^0.19.8" + escape-string-regexp "^5.0.0" + estree-walker "^3.0.3" + etag "^1.8.1" + fs-extra "^11.2.0" + globby "^14.0.0" + gzip-size "^7.0.0" + h3 "^1.9.0" + hookable "^5.5.3" + httpxy "^0.1.5" + is-primitive "^3.0.1" + jiti "^1.21.0" + klona "^2.0.6" + knitwork "^1.0.0" + listhen "^1.5.5" + magic-string "^0.30.5" + mime "^3.0.0" + mlly "^1.4.2" + mri "^1.2.0" + node-fetch-native "^1.4.1" + ofetch "^1.3.3" + ohash "^1.1.3" + openapi-typescript "^6.7.1" + pathe "^1.1.1" + perfect-debounce "^1.0.0" + pkg-types "^1.0.3" + pretty-bytes "^6.1.1" + radix3 "^1.1.0" + rollup "^4.6.0" + rollup-plugin-visualizer "^5.9.3" + scule "^1.1.0" + semver "^7.5.4" + serve-placeholder "^2.0.1" + serve-static "^1.15.0" + std-env "^3.5.0" + ufo "^1.3.2" + uncrypto "^0.1.3" + unctx "^2.3.1" + unenv "^1.8.0" + unimport "^3.6.0" + unstorage "^1.10.1" + +node-addon-api@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.0.0.tgz#8136add2f510997b3b94814f4af1cce0b0e3962e" + integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA== + +node-fetch-native@^1.4.0, node-fetch-native@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.4.1.tgz#5a336e55b4e1b1e72b9927da09fecd2b374c9be5" + integrity sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w== + +node-fetch-native@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.1.tgz#f95c74917d3cebc794cdae0cd2a9c7594aad0cb4" + integrity sha512-bW9T/uJDPAJB2YNYEpWzE54U5O3MQidXsOyTfnbKYtTtFexRvGzb1waphBN4ZwP6EcIvYYEOwW0b72BpAqydTw== + +node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-forge@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-gyp-build@^4.2.2: + version "4.7.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.7.1.tgz#cd7d2eb48e594874053150a9418ac85af83ca8f7" + integrity sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg== + +node-gyp@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-10.0.1.tgz#205514fc19e5830fa991e4a689f9e81af377a966" + integrity sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg== + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1" + glob "^10.3.10" + graceful-fs "^4.2.6" + make-fetch-happen "^13.0.0" + nopt "^7.0.0" + proc-log "^3.0.0" + semver "^7.3.5" + tar "^6.1.2" + which "^4.0.0" + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +nopt@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" + integrity sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA== + dependencies: + abbrev "^2.0.0" + +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 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-package-data@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.0.tgz#68a96b3c11edd462af7189c837b6b1064a484196" + integrity sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg== + dependencies: + hosted-git-info "^7.0.0" + is-core-module "^2.8.1" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + +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 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 sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +npm-bundled@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7" + integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ== + dependencies: + npm-normalize-package-bin "^3.0.0" + +npm-install-checks@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" + integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== + dependencies: + semver "^7.1.1" + +npm-normalize-package-bin@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" + integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== + +npm-package-arg@^11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-11.0.1.tgz#f208b0022c29240a1c532a449bdde3f0a4708ebc" + integrity sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ== + dependencies: + hosted-git-info "^7.0.0" + proc-log "^3.0.0" + semver "^7.3.5" + validate-npm-package-name "^5.0.0" + +npm-packlist@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-8.0.1.tgz#97d1eb2a9a90e10ce1b028d058da3740c91b89ab" + integrity sha512-MQpL27ZrsJQ2kiAuQPpZb5LtJwydNRnI15QWXsf3WHERu4rzjRj6Zju/My2fov7tLuu3Gle/uoIX/DDZ3u4O4Q== + dependencies: + ignore-walk "^6.0.4" + +npm-pick-manifest@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-9.0.0.tgz#f87a4c134504a2c7931f2bb8733126e3c3bb7e8f" + integrity sha512-VfvRSs/b6n9ol4Qb+bDwNGUXutpy76x6MARw/XssevE0TnctIKcmklJZM5Z7nqs5z5aW+0S63pgCNbpkUNNXBg== + dependencies: + npm-install-checks "^6.0.0" + npm-normalize-package-bin "^3.0.0" + npm-package-arg "^11.0.0" + semver "^7.3.5" + +npm-registry-fetch@^16.0.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-16.1.0.tgz#10227b7b36c97bc1cf2902a24e4f710cfe62803c" + integrity sha512-PQCELXKt8Azvxnt5Y85GseQDJJlglTFM9L9U9gkv2y4e9s0k3GVDdOx3YoB6gm2Do0hlkzC39iCGXby+Wve1Bw== + dependencies: + make-fetch-happen "^13.0.0" + minipass "^7.0.2" + minipass-fetch "^3.0.0" + minipass-json-stream "^1.0.1" + minizlib "^2.1.2" + npm-package-arg "^11.0.0" + proc-log "^3.0.0" + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + +npmlog@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" + integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== + dependencies: + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^3.0.0" + set-blocking "^2.0.0" + +nth-check@^2.0.1, nth-check@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +nuxi@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/nuxi/-/nuxi-3.10.0.tgz#32db1c774d1829fbca7034135297e6c3e791b661" + integrity sha512-veZXw2NuaQ1PrpvHrnQ1dPgkAjv0WqPlvFReg5Iubum0QVGWdJJvGuNsltDQyPcZ7X7mhMXq9SLIpokK4kpvKA== + optionalDependencies: + fsevents "~2.3.3" + +nuxt-icon@^0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/nuxt-icon/-/nuxt-icon-0.6.8.tgz#15c36e92e4baa03adf322938dba86bb872b6251f" + integrity sha512-6eWlNOb6Uvp63uXFdhcmsB1JlubDv76Pot/VwmIu0yJxDYhwytbnv3WAjw2khl2l7W/65V4eMGIEeX9C5Ahxng== + dependencies: + "@iconify/collections" "^1.0.374" + "@iconify/vue" "^4.1.1" + "@nuxt/devtools-kit" "^1.0.6" + "@nuxt/kit" "^3.9.0" + +nuxt@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-3.10.1.tgz#b0236e73df6db8f8465a4d1088c54a6a995e554c" + integrity sha512-1X1DFTGPbVQFF1tjOWYl3qYc3zQww8htknu3qiP8xNzY1MFnDT3Xisxcf6KDe375tHHui0UpXflseL6evlEoMQ== + dependencies: + "@nuxt/devalue" "^2.0.2" + "@nuxt/devtools" "^1.0.8" + "@nuxt/kit" "3.10.1" + "@nuxt/schema" "3.10.1" + "@nuxt/telemetry" "^2.5.3" + "@nuxt/ui-templates" "^1.3.1" + "@nuxt/vite-builder" "3.10.1" + "@unhead/dom" "^1.8.10" + "@unhead/ssr" "^1.8.10" + "@unhead/vue" "^1.8.10" + "@vue/shared" "^3.4.15" + acorn "8.11.3" + c12 "^1.6.1" + chokidar "^3.5.3" + cookie-es "^1.0.0" + defu "^6.1.4" + destr "^2.0.2" + devalue "^4.3.2" + esbuild "^0.20.0" + escape-string-regexp "^5.0.0" + estree-walker "^3.0.3" + fs-extra "^11.2.0" + globby "^14.0.0" + h3 "^1.10.1" + hookable "^5.5.3" + jiti "^1.21.0" + klona "^2.0.6" + knitwork "^1.0.0" + magic-string "^0.30.6" + mlly "^1.5.0" + nitropack "^2.8.1" + nuxi "^3.10.0" + nypm "^0.3.6" + ofetch "^1.3.3" + ohash "^1.1.3" + pathe "^1.1.2" + perfect-debounce "^1.0.0" + pkg-types "^1.0.3" + radix3 "^1.1.0" + scule "^1.2.0" + std-env "^3.7.0" + strip-literal "^2.0.0" + ufo "^1.3.2" + ultrahtml "^1.5.2" + uncrypto "^0.1.3" + unctx "^2.3.1" + unenv "^1.9.0" + unimport "^3.7.1" + unplugin "^1.6.0" + unplugin-vue-router "^0.7.0" + untyped "^1.4.2" + vue "^3.4.15" + vue-bundle-renderer "^2.0.0" + vue-devtools-stub "^0.1.0" + vue-router "^4.2.5" + +nypm@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/nypm/-/nypm-0.3.3.tgz#e775fd8f62c3ed7d60958ede80911410cb792724" + integrity sha512-FHoxtTscAE723e80d2M9cJRb4YVjL82Ra+ZV+YqC6rfNZUWahi+ZhPF+krnR+bdMvibsfHCtgKXnZf5R6kmEPA== + dependencies: + citty "^0.1.4" + execa "^8.0.1" + pathe "^1.1.1" + ufo "^1.3.0" + +nypm@^0.3.4, nypm@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/nypm/-/nypm-0.3.6.tgz#940b558e6e56c2ed5dc43adf6dcf2c16577a80ff" + integrity sha512-2CATJh3pd6CyNfU5VZM7qSwFu0ieyabkEdnogE30Obn1czrmOYiZ8DOZLe1yBdLKWoyD3Mcy2maUs+0MR3yVjQ== + dependencies: + citty "^0.1.5" + execa "^8.0.1" + pathe "^1.1.2" + ufo "^1.3.2" + +object-assign@^4.0.1, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + +ofetch@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.3.3.tgz#588cb806a28e5c66c2c47dd8994f9059a036d8c0" + integrity sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg== + dependencies: + destr "^2.0.1" + node-fetch-native "^1.4.0" + ufo "^1.3.0" + +ohash@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.3.tgz#f12c3c50bfe7271ce3fd1097d42568122ccdcf07" + integrity sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw== + +on-finished@2.4.1, on-finished@^2.3.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +only@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" + integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ== + +open@^7.0.4: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + +open@^8.4.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + +openapi-typescript@^6.7.1: + version "6.7.2" + resolved "https://registry.yarnpkg.com/openapi-typescript/-/openapi-typescript-6.7.2.tgz#f2e923e586d1fba770561866326ec4bbfac5681a" + integrity sha512-7rsUArlMBqmSaRd6EzPl2nGKzPFNRicsRGrxf6W+/HLEDZoOxghR3B53YlyGjcqak8YDZMBNzZQ3o93Bp3qY9Q== + dependencies: + ansi-colors "^4.1.3" + fast-glob "^3.3.1" + js-yaml "^4.1.0" + supports-color "^9.4.0" + undici "^5.27.2" + yargs-parser "^21.1.1" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.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 sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.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 sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pacote@^17.0.5: + version "17.0.5" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-17.0.5.tgz#e9854edee7a073635cdd36b0c07cd4f2ab1757b6" + integrity sha512-TAE0m20zSDMnchPja9vtQjri19X3pZIyRpm2TJVeI+yU42leJBBDTRYhOcWFsPhaMxf+3iwQkFiKz16G9AEeeA== + dependencies: + "@npmcli/git" "^5.0.0" + "@npmcli/installed-package-contents" "^2.0.1" + "@npmcli/promise-spawn" "^7.0.0" + "@npmcli/run-script" "^7.0.0" + cacache "^18.0.0" + fs-minipass "^3.0.0" + minipass "^7.0.2" + npm-package-arg "^11.0.0" + npm-packlist "^8.0.0" + npm-pick-manifest "^9.0.0" + npm-registry-fetch "^16.0.0" + proc-log "^3.0.0" + promise-retry "^2.0.1" + read-package-json "^7.0.0" + read-package-json-fast "^3.0.0" + sigstore "^2.0.0" + ssri "^10.0.0" + tar "^6.1.11" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parent-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-2.0.0.tgz#fa71f88ff1a50c27e15d8ff74e0e3a9523bf8708" + integrity sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg== + dependencies: + callsites "^3.1.0" + +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + integrity 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-git-config@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/parse-git-config/-/parse-git-config-3.0.0.tgz#4a2de08c7b74a2555efa5ae94d40cd44302a6132" + integrity sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA== + dependencies: + git-config-path "^2.0.0" + ini "^1.3.5" + +parse-gitignore@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-gitignore/-/parse-gitignore-2.0.0.tgz#81156b265115c507129f3faea067b8476da3b642" + integrity sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog== + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity 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" + +parse-path@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.0.0.tgz#605a2d58d0a749c8594405d8cc3a2bf76d16099b" + integrity sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog== + dependencies: + protocols "^2.0.0" + +parse-url@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" + integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== + dependencies: + parse-path "^7.0.0" + +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 sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@1.0.1, 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 sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +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 sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-to-regexp@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" + integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +path-type@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-5.0.0.tgz#14b01ed7aea7ddf9c7c3f46181d4d04f9c785bb8" + integrity sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg== + +pathe@^1.1.0, pathe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" + integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== + +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== + +perfect-debounce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a" + integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +picomatch@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-3.0.1.tgz#817033161def55ec9638567a2f3bbc876b3e7516" + integrity sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pinia@>=2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc" + integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ== + dependencies: + "@vue/devtools-api" "^6.5.0" + vue-demi ">=0.14.5" + +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-types@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" + integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== + dependencies: + jsonc-parser "^3.2.0" + mlly "^1.2.0" + pathe "^1.1.0" + +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + +portfinder@^1.0.26: + version "1.0.32" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81" + integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== + dependencies: + async "^2.6.4" + debug "^3.2.7" + mkdirp "^0.5.6" + +postcss-calc@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-9.0.1.tgz#a744fd592438a93d6de0f1434c572670361eb6c6" + integrity sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ== + dependencies: + postcss-selector-parser "^6.0.11" + postcss-value-parser "^4.2.0" + +postcss-colormin@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-6.0.2.tgz#2af9ce753937b08e058dbc6879e4aedfab42806b" + integrity sha512-TXKOxs9LWcdYo5cgmcSHPkyrLAh86hX1ijmyy6J8SbOhyv6ua053M3ZAM/0j44UsnQNIWdl8gb5L7xX2htKeLw== + dependencies: + browserslist "^4.22.2" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" + +postcss-convert-values@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-6.0.2.tgz#c4a7509aeb1cc7ac3f6948fcbffc2bf8cac7c56a" + integrity sha512-aeBmaTnGQ+NUSVQT8aY0sKyAD/BaLJenEKZ03YK0JnDE1w1Rr8XShoxdal2V2H26xTJKr3v5haByOhJuyT4UYw== + dependencies: + browserslist "^4.22.2" + postcss-value-parser "^4.2.0" + +postcss-custom-properties@^13.3.4: + version "13.3.4" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-13.3.4.tgz#0ad5be700b692e0288ce3b2b406eac964244f197" + integrity sha512-9YN0gg9sG3OH+Z9xBrp2PWRb+O4msw+5Sbp3ZgqrblrwKspXVQe5zr5sVqi43gJGwW/Rv1A483PRQUzQOEewvA== + dependencies: + "@csstools/cascade-layer-name-parser" "^1.0.7" + "@csstools/css-parser-algorithms" "^2.5.0" + "@csstools/css-tokenizer" "^2.2.3" + postcss-value-parser "^4.2.0" + +postcss-discard-comments@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-6.0.1.tgz#46176212bd9c3e5f48aa4b8b4868786726c41d36" + integrity sha512-f1KYNPtqYLUeZGCHQPKzzFtsHaRuECe6jLakf/RjSRqvF5XHLZnM2+fXLhb8Qh/HBFHs3M4cSLb1k3B899RYIg== + +postcss-discard-duplicates@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.1.tgz#112b1a95948e69b3484fdd43584dda6930977939" + integrity sha512-1hvUs76HLYR8zkScbwyJ8oJEugfPV+WchpnA+26fpJ7Smzs51CzGBHC32RS03psuX/2l0l0UKh2StzNxOrKCYg== + +postcss-discard-empty@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-6.0.1.tgz#b34cb45ec891246da4506b53e352390fdef126c4" + integrity sha512-yitcmKwmVWtNsrrRqGJ7/C0YRy53i0mjexBDQ9zYxDwTWVBgbU4+C9jIZLmQlTDT9zhml+u0OMFJh8+31krmOg== + +postcss-discard-overridden@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-6.0.1.tgz#c63c559237758d74bc505452393a64dda9b19ef4" + integrity sha512-qs0ehZMMZpSESbRkw1+inkf51kak6OOzNRaoLd/U7Fatp0aN2HQ1rxGOrJvYcRAN9VpX8kUF13R2ofn8OlvFVA== + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + dependencies: + lilconfig "^3.0.0" + yaml "^2.3.4" + +postcss-merge-longhand@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-6.0.2.tgz#cd4e83014851da59545e9a906b245615550f4064" + integrity sha512-+yfVB7gEM8SrCo9w2lCApKIEzrTKl5yS1F4yGhV3kSim6JzbfLGJyhR1B6X+6vOT0U33Mgx7iv4X9MVWuaSAfw== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^6.0.2" + +postcss-merge-rules@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-6.0.3.tgz#08fcf714faaad75b1980ecd961b080ae2f8ddeb3" + integrity sha512-yfkDqSHGohy8sGYIJwBmIGDv4K4/WrJPX355XrxQb/CSsT4Kc/RxDi6akqn5s9bap85AWgv21ArcUWwWdGNSHA== + dependencies: + browserslist "^4.22.2" + caniuse-api "^3.0.0" + cssnano-utils "^4.0.1" + postcss-selector-parser "^6.0.15" + +postcss-minify-font-values@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-6.0.1.tgz#788eb930168be90225f3937f0b70aa19d8b532b2" + integrity sha512-tIwmF1zUPoN6xOtA/2FgVk1ZKrLcCvE0dpZLtzyyte0j9zUeB8RTbCqrHZGjJlxOvNWKMYtunLrrl7HPOiR46w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-minify-gradients@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-6.0.1.tgz#4faf1880b483dc37016658aa186b42194ff9b5bc" + integrity sha512-M1RJWVjd6IOLPl1hYiOd5HQHgpp6cvJVLrieQYS9y07Yo8itAr6jaekzJphaJFR0tcg4kRewCk3kna9uHBxn/w== + dependencies: + colord "^2.9.1" + cssnano-utils "^4.0.1" + postcss-value-parser "^4.2.0" + +postcss-minify-params@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-6.0.2.tgz#bd64af642fa5610281b8a9461598bbb91f92ae05" + integrity sha512-zwQtbrPEBDj+ApELZ6QylLf2/c5zmASoOuA4DzolyVGdV38iR2I5QRMsZcHkcdkZzxpN8RS4cN7LPskOkTwTZw== + dependencies: + browserslist "^4.22.2" + cssnano-utils "^4.0.1" + postcss-value-parser "^4.2.0" + +postcss-minify-selectors@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-6.0.2.tgz#62065b38d3453ddc6627ba50e4f4a2154b031aa0" + integrity sha512-0b+m+w7OAvZejPQdN2GjsXLv5o0jqYHX3aoV0e7RBKPCsB7TYG5KKWBFhGnB/iP3213Ts8c5H4wLPLMm7z28Sg== + dependencies: + postcss-selector-parser "^6.0.15" + +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== + dependencies: + postcss-selector-parser "^6.0.11" + +postcss-nesting@^12.0.2: + version "12.0.2" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-12.0.2.tgz#cb92061347db3e7c38c174c97cb01feff2eef439" + integrity sha512-63PpJHSeNs93S3ZUIyi+7kKx4JqOIEJ6QYtG3x+0qA4J03+4n0iwsyA1GAHyWxsHYljQS4/4ZK1o2sMi70b5wQ== + dependencies: + "@csstools/selector-specificity" "^3.0.1" + postcss-selector-parser "^6.0.13" + +postcss-normalize-charset@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-6.0.1.tgz#5f70e1eb8bbdbcfcbed060ef70f179e8fef57d0c" + integrity sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg== + +postcss-normalize-display-values@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.1.tgz#ff9aa30bbf1283294bfd9cc8b6fb81ff060a7f2d" + integrity sha512-mc3vxp2bEuCb4LgCcmG1y6lKJu1Co8T+rKHrcbShJwUmKJiEl761qb/QQCfFwlrvSeET3jksolCR/RZuMURudw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-positions@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-6.0.1.tgz#41ffdc72994f024c6cd6e91dbfb40ab9abe6fe90" + integrity sha512-HRsq8u/0unKNvm0cvwxcOUEcakFXqZ41fv3FOdPn916XFUrympjr+03oaLkuZENz3HE9RrQE9yU0Xv43ThWjQg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-repeat-style@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.1.tgz#55dc54b6f80305b280a379899a6626e0a07b04a8" + integrity sha512-Gbb2nmCy6tTiA7Sh2MBs3fj9W8swonk6lw+dFFeQT68B0Pzwp1kvisJQkdV6rbbMSd9brMlS8I8ts52tAGWmGQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-string@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-6.0.1.tgz#7605e0fb4ec7bf2709709991d13a949e4419db1d" + integrity sha512-5Fhx/+xzALJD9EI26Aq23hXwmv97Zfy2VFrt5PLT8lAhnBIZvmaT5pQk+NuJ/GWj/QWaKSKbnoKDGLbV6qnhXg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.1.tgz#ef937b7ca2fd62ed0b46645ea5728b842a3600db" + integrity sha512-4zcczzHqmCU7L5dqTB9rzeqPWRMc0K2HoR+Bfl+FSMbqGBUcP5LRfgcH4BdRtLuzVQK1/FHdFoGT3F7rkEnY+g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-unicode@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.2.tgz#361026744ff11baebaec771b60c2a5f36f274fd0" + integrity sha512-Ff2VdAYCTGyMUwpevTZPZ4w0+mPjbZzLLyoLh/RMpqUqeQKZ+xMm31hkxBavDcGKcxm6ACzGk0nBfZ8LZkStKA== + dependencies: + browserslist "^4.22.2" + postcss-value-parser "^4.2.0" + +postcss-normalize-url@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-6.0.1.tgz#eae58cb4f5f9a4fa5bbbf6d4222dff534ad46186" + integrity sha512-jEXL15tXSvbjm0yzUV7FBiEXwhIa9H88JOXDGQzmcWoB4mSjZIsmtto066s2iW9FYuIrIF4k04HA2BKAOpbsaQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-whitespace@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.1.tgz#b5933750b938814c028d3d2b2e5c0199e0037b53" + integrity sha512-76i3NpWf6bB8UHlVuLRxG4zW2YykF9CTEcq/9LGAiz2qBuX5cBStadkk0jSkg9a9TCIXbMQz7yzrygKoCW9JuA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-ordered-values@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-6.0.1.tgz#553e735d009065b362da93340e57f43d5f2d0fbc" + integrity sha512-XXbb1O/MW9HdEhnBxitZpPFbIvDgbo9NK4c/5bOfiKpnIGZDoL2xd7/e6jW5DYLsWxBbs+1nZEnVgnjnlFViaA== + dependencies: + cssnano-utils "^4.0.1" + postcss-value-parser "^4.2.0" + +postcss-reduce-initial@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-6.0.2.tgz#763d25902406c872264041df69f182eb15a5d9be" + integrity sha512-YGKalhNlCLcjcLvjU5nF8FyeCTkCO5UtvJEt0hrPZVCTtRLSOH4z00T1UntQPj4dUmIYZgMj8qK77JbSX95hSw== + dependencies: + browserslist "^4.22.2" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.1.tgz#7bf59d7c6e7066e3b18ef17237d2344bd3da6d75" + integrity sha512-fUbV81OkUe75JM+VYO1gr/IoA2b/dRiH6HvMwhrIBSUrxq3jNZQZitSnugcTLDi1KkQh1eR/zi+iyxviUNBkcQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-selector-parser@6.0.10: + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.13: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.15: + version "6.0.15" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz#11cc2b21eebc0b99ea374ffb9887174855a01535" + integrity sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-svgo@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-6.0.2.tgz#dbc9d03e7f346bc0d82443078602a951e0214836" + integrity sha512-IH5R9SjkTkh0kfFOQDImyy1+mTCb+E830+9SV1O+AaDcoHTvfsvt6WwJeo7KwcHbFnevZVCsXhDmjFiGVuwqFQ== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^3.2.0" + +postcss-unique-selectors@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-6.0.2.tgz#09a34a5a31a649d3e9bca5962af0616f39d071d2" + integrity sha512-8IZGQ94nechdG7Y9Sh9FlIY2b4uS8/k8kdKRX040XHsS3B6d1HrJAkXrBSsSu4SuARruSsUjW3nlSw8BHkaAYQ== + dependencies: + postcss-selector-parser "^6.0.15" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.23, postcss@^8.4.32: + version "8.4.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9" + integrity sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@^8.4.33: + version "8.4.34" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.34.tgz#563276e86b4ff20dfa5eed0d394d4c53853b2051" + integrity sha512-4eLTO36woPSocqZ1zIrFD2K1v6wH7pY1uBh0JIM2KKfrVtGvPFiAku6aNOP0W1Wr9qwnaCsF0Z+CrVnryB2A8Q== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +pretty-bytes@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.1.1.tgz#38cd6bb46f47afbf667c202cfc754bffd2016a3b" + integrity sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ== + +proc-log@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" + integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== + +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 sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +prompts@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +protocols@^2.0.0, protocols@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" + integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + +radix3@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.0.tgz#9745df67a49c522e94a33d0a93cf743f104b6e0d" + integrity sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +rc9@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/rc9/-/rc9-2.1.1.tgz#6614c32db7731b44cd48641ce68f373c3ee212a9" + integrity sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q== + dependencies: + defu "^6.1.2" + destr "^2.0.0" + flat "^5.0.2" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +read-package-json-fast@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049" + integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw== + dependencies: + json-parse-even-better-errors "^3.0.0" + npm-normalize-package-bin "^3.0.0" + +read-package-json@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-7.0.0.tgz#d605c9dcf6bc5856da24204aa4e9518ee9714be0" + integrity sha512-uL4Z10OKV4p6vbdvIXB+OzhInYtIozl/VxUBPgNkBuUi2DeRonnuspmaVAMcrkmfjKGNmRndyQAbE7/AmzGwFg== + dependencies: + glob "^10.2.2" + json-parse-even-better-errors "^3.0.0" + normalize-package-data "^6.0.0" + npm-normalize-package-bin "^3.0.0" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity 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@^2.0.5: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + 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.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdir-glob@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.3.tgz#c3d831f51f5e7bfa62fa2ffbe4b508c640f09584" + integrity sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA== + dependencies: + minimatch "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== + +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== + dependencies: + redis-errors "^1.0.0" + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +regexp-tree@^0.1.27: + version "0.1.27" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd" + integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== + +regjsparser@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.10.0.tgz#b1ed26051736b436f22fdec1c8f72635f9f44892" + integrity sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA== + dependencies: + jsesc "~0.5.0" + +replace-in-file@^6.1.0: + version "6.3.5" + resolved "https://registry.yarnpkg.com/replace-in-file/-/replace-in-file-6.3.5.tgz#ff956b0ab5bc96613207d603d197cd209400a654" + integrity sha512-arB9d3ENdKva2fxRnSjwBEXfK1npgyci7ZZuwysgAp7ORjHSyxz6oqIjTEv8R0Ydl4Ll7uOAZXL4vbkhGIizCg== + dependencies: + chalk "^4.1.2" + glob "^7.2.0" + yargs "^17.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-path@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" + integrity sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w== + dependencies: + http-errors "~1.6.2" + path-is-absolute "1.0.1" + +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + +resolve@^1.1.7, resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity 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 sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup-plugin-visualizer@^5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz#661542191ce78ee4f378995297260d0c1efb1302" + integrity sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ== + dependencies: + open "^8.4.0" + picomatch "^2.3.1" + source-map "^0.7.4" + yargs "^17.5.1" + +rollup-plugin-visualizer@^5.9.3: + version "5.10.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.10.0.tgz#a71c733255dff4cb1ca57ecf31fd62f895c0535f" + integrity sha512-N4AkNL0qFvipegbDJ0kupS+8eKGjL0q+lYwV46NflLX/B8Rh73wz3kCIdg50bR6XVhNcaMA4Eb519xtm90Ckfg== + dependencies: + open "^8.4.0" + picomatch "^2.3.1" + source-map "^0.7.4" + yargs "^17.5.1" + +rollup@^4.2.0: + version "4.9.6" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.9.6.tgz#4515facb0318ecca254a2ee1315e22e09efc50a0" + integrity sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.9.6" + "@rollup/rollup-android-arm64" "4.9.6" + "@rollup/rollup-darwin-arm64" "4.9.6" + "@rollup/rollup-darwin-x64" "4.9.6" + "@rollup/rollup-linux-arm-gnueabihf" "4.9.6" + "@rollup/rollup-linux-arm64-gnu" "4.9.6" + "@rollup/rollup-linux-arm64-musl" "4.9.6" + "@rollup/rollup-linux-riscv64-gnu" "4.9.6" + "@rollup/rollup-linux-x64-gnu" "4.9.6" + "@rollup/rollup-linux-x64-musl" "4.9.6" + "@rollup/rollup-win32-arm64-msvc" "4.9.6" + "@rollup/rollup-win32-ia32-msvc" "4.9.6" + "@rollup/rollup-win32-x64-msvc" "4.9.6" + fsevents "~2.3.2" + +rollup@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.6.1.tgz#351501c86b5b4f976dde8c5837516452b59921f8" + integrity sha512-jZHaZotEHQaHLgKr8JnQiDT1rmatjgKlMekyksz+yk9jt/8z9quNjnKNRoaM0wd9DC2QKXjmWWuDYtM3jfF8pQ== + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.6.1" + "@rollup/rollup-android-arm64" "4.6.1" + "@rollup/rollup-darwin-arm64" "4.6.1" + "@rollup/rollup-darwin-x64" "4.6.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.6.1" + "@rollup/rollup-linux-arm64-gnu" "4.6.1" + "@rollup/rollup-linux-arm64-musl" "4.6.1" + "@rollup/rollup-linux-x64-gnu" "4.6.1" + "@rollup/rollup-linux-x64-musl" "4.6.1" + "@rollup/rollup-win32-arm64-msvc" "4.6.1" + "@rollup/rollup-win32-ia32-msvc" "4.6.1" + "@rollup/rollup-win32-x64-msvc" "4.6.1" + fsevents "~2.3.2" + +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.2.1, safe-buffer@^5.1.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 sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +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 sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass@^1.70.0: + version "1.70.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.70.0.tgz#761197419d97b5358cb25f9dd38c176a8a270a75" + integrity sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +scule@^1.0.0, scule@^1.1.0, scule@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/scule/-/scule-1.1.1.tgz#82b4d13bb8c729c15849256e749cee0cb52a4d89" + integrity sha512-sHtm/SsIK9BUBI3EFT/Gnp9VoKfY6QLvlkvAE6YK7454IF8FSgJEAnJpVdSC7K5/pjI5NfxhzBLW2JAfYA/shQ== + +scule@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/scule/-/scule-1.2.0.tgz#b46d444d6a8c92e73eb80d2d8d00b94ab065cc3e" + integrity sha512-CRCmi5zHQnSoeCik9565PONMg0kfkvYmcSqrbOJY4txFfy1wvVULV4FDaiXhUblUgahdqz3F2NwHZ8i4eBTwUw== + +"semver@2 || 3 || 4 || 5": + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.0.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.0.0, semver@^7.1.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.6, semver@^7.5.0, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +semver@^7.6.0: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +serve-placeholder@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/serve-placeholder/-/serve-placeholder-2.0.1.tgz#dfa741812f49dfea472a68c4f292dbc40d28389a" + integrity sha512-rUzLlXk4uPFnbEaIz3SW8VISTxMuONas88nYWjAWaM2W9VDbt9tyFOr3lq8RhVOFrT3XISoBw8vni5una8qMnQ== + dependencies: + defu "^6.0.0" + +serve-static@^1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + +signal-exit@^3.0.0, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1, signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +sigstore@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-2.1.0.tgz#c577b596642b3f360dc4135d476466e6edeb2364" + integrity sha512-kPIj+ZLkyI3QaM0qX8V/nSsweYND3W448pwkDgS6CQ74MfhEkIR8ToK5Iyx46KJYRjseVcD3Rp9zAmUAj6ZjPw== + dependencies: + "@sigstore/bundle" "^2.1.0" + "@sigstore/protobuf-specs" "^0.2.1" + "@sigstore/sign" "^2.1.0" + "@sigstore/tuf" "^2.1.0" + +simple-git@^3.22.0: + version "3.22.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.22.0.tgz#616d41c661e30f9c65778956317d422b1729a242" + integrity sha512-6JujwSs0ac82jkGjMHiCnTifvf1crOiY/+tfs/Pqih6iow7VrpNKRRNdWm6RtaXpvvv/JGNYhlUtLhGFqHF+Yw== + dependencies: + "@kwsites/file-exists" "^1.1.1" + "@kwsites/promise-deferred" "^1.1.1" + debug "^4.3.4" + +sirv@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.3.tgz#ca5868b87205a74bef62a469ed0296abceccd446" + integrity sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA== + dependencies: + "@polka/url" "^1.0.0-next.20" + mrmime "^1.0.0" + totalist "^3.0.0" + +sirv@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.4.tgz#5dd9a725c578e34e449f332703eb2a74e46a29b0" + integrity sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ== + dependencies: + "@polka/url" "^1.0.0-next.24" + mrmime "^2.0.0" + totalist "^3.0.0" + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +slash@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce" + integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg== + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +smob@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/smob/-/smob-1.4.1.tgz#66270e7df6a7527664816c5b577a23f17ba6f5b5" + integrity sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ== + +socks-proxy-agent@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad" + integrity sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g== + dependencies: + agent-base "^7.0.2" + debug "^4.3.4" + socks "^2.7.1" + +socks@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + 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 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 sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-expression-parse@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz#a23af9f3132115465dac215c099303e4ceac5794" + integrity sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.16" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== + +ssri@^10.0.0: + version "10.0.5" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" + integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== + dependencies: + minipass "^7.0.3" + +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"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 sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +std-env@^3.4.3, std-env@^3.5.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.6.0.tgz#94807562bddc68fa90f2e02c5fd5b6865bb4e98e" + integrity sha512-aFZ19IgVmhdB2uX599ve2kE6BIE3YMnQ6Gp6BURhW/oIzpXGKr878TQfAQZn1+i0Flcc/UKUy1gOlcfaUBCryg== + +std-env@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" + integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== + +streamx@^2.15.0: + version "2.15.5" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.5.tgz#87bcef4dc7f0b883f9359671203344a4e004c7f1" + integrity sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg== + dependencies: + fast-fifo "^1.1.0" + queue-tick "^1.0.1" + +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", 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 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-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity 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 sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", 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 sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +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 sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.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 sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-literal@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-1.3.0.tgz#db3942c2ec1699e6836ad230090b84bb458e3a07" + integrity sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg== + dependencies: + acorn "^8.10.0" + +strip-literal@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-2.0.0.tgz#5d063580933e4e03ebb669b12db64d2200687527" + integrity sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA== + dependencies: + js-tokens "^8.0.2" + +stylehacks@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-6.0.2.tgz#5bf2654561752547d4548765f35c9a49659b3742" + integrity sha512-00zvJGnCu64EpMjX8b5iCZ3us2Ptyw8+toEkb92VdmkEaRaSGBNKAoK6aWZckhXxmQP8zWiTaFaiMGIU8Ve8sg== + dependencies: + browserslist "^4.22.2" + postcss-selector-parser "^6.0.15" + +sucrase@^3.32.0: + version "3.34.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f" + integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + 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 sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.4.0.tgz#17bfcf686288f531db3dea3215510621ccb55954" + integrity sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw== + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svg-tags@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" + integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA== + +svgo@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.2.0.tgz#7a5dff2938d8c6096e00295c2390e8e652fa805d" + integrity sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^5.1.0" + css-tree "^2.3.1" + css-what "^6.1.0" + csso "^5.0.5" + picocolors "^1.0.0" + +synckit@^0.6.0: + version "0.6.2" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.6.2.tgz#e1540b97825f2855f7170b98276e8463167f33eb" + integrity sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA== + dependencies: + tslib "^2.3.1" + +tailwind-config-viewer@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/tailwind-config-viewer/-/tailwind-config-viewer-1.7.3.tgz#3e448cad29545aa31613a5d82c61798ee93c4e88" + integrity sha512-rgeFXe9vL4njtaSI1y2uUAD1aRx05RYHbReN72ARAVEVSlNmS0Zf46pj3/ORc3xQwLK/AzbaIs6UFcK7hJSIlA== + dependencies: + "@koa/router" "^12.0.1" + commander "^6.0.0" + fs-extra "^9.0.1" + koa "^2.14.2" + koa-static "^5.0.0" + open "^7.0.4" + portfinder "^1.0.26" + replace-in-file "^6.1.0" + +tailwind-merge@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.1.tgz#3f10f296a2dba1d88769de8244fafd95c3324aeb" + integrity sha512-o+2GTLkthfa5YUt4JxPfzMIpQzZ3adD1vLVkvKE1Twl9UAhGsEbIZhHHZVRttyW177S8PDJI3bTQNaebyofK3Q== + dependencies: + "@babel/runtime" "^7.23.7" + +tailwindcss@^3.4.1, tailwindcss@~3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.1.tgz#f512ca5d1dd4c9503c7d3d28a968f1ad8f5c839d" + integrity sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.3.0" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.19.1" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" + +tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +tar-stream@^3.0.0: + version "3.1.6" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab" + integrity sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + +tar@^6.1.11, tar@^6.1.2, tar@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" + integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +terser@^5.17.4: + version "5.26.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.26.0.tgz#ee9f05d929f4189a9c28a0feb889d96d50126fe1" + integrity sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity 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 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 sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +tiny-invariant@^1.1.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + +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 sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +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 sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +toml-eslint-parser@^0.9.0, toml-eslint-parser@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/toml-eslint-parser/-/toml-eslint-parser-0.9.3.tgz#fc02498ba76e935f888c4b68b00e75b59789d272" + integrity sha512-moYoCvkNUAPCxSW9jmHmRElhm4tVJpHL8ItC/+uYD0EpPSFXbck7yREz9tNdJVTSpHVod8+HoipcpbQ0oE6gsw== + dependencies: + eslint-visitor-keys "^3.0.0" + +totalist@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-api-utils@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" + integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +tslib@^2.3.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tsscmp@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== + +tuf-js@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-2.1.0.tgz#87aa36d5a166e7522f1e2050eb502a3a9b0bde72" + integrity sha512-eD7YPPjVlMzdggrOeE8zwoegUaG/rt6Bt3jwoQPunRiNVzgcCE009UDFJKJjG+Gk9wFu6W/Vi+P5d/5QpdD9jA== + dependencies: + "@tufjs/models" "2.0.0" + debug "^4.3.4" + make-fetch-happen "^13.0.0" + +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 sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity 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 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 sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type-fest@^3.8.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" + integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== + +type-is@^1.6.16: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + +ufo@^1.1.2, ufo@^1.2.0, ufo@^1.3.0, ufo@^1.3.1, ufo@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.2.tgz#c7d719d0628a1c80c006d2240e0d169f6e3c0496" + integrity sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA== + +ultrahtml@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/ultrahtml/-/ultrahtml-1.5.2.tgz#77be18c531adc4cda198b8767eda27df9427cc7f" + integrity sha512-qh4mBffhlkiXwDAOxvSGxhL0QEQsTbnP9BozOK3OYPEGvPvdWzvAUaXNtUSMdNsKDtuyjEbyVUPFZ52SSLhLqw== + +uncrypto@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/uncrypto/-/uncrypto-0.1.3.tgz#e1288d609226f2d02d8d69ee861fa20d8348ef2b" + integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q== + +unctx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unctx/-/unctx-2.3.1.tgz#5eb4aa9f96fb5fdac18b88fe5ba8e122fe671a62" + integrity sha512-PhKke8ZYauiqh3FEMVNm7ljvzQiph0Mt3GBRve03IJm7ukfaON2OBK795tLwhbyfzknuRRkW0+Ze+CQUmzOZ+A== + dependencies: + acorn "^8.8.2" + estree-walker "^3.0.3" + magic-string "^0.30.0" + unplugin "^1.3.1" + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +undici@^5.27.2: + version "5.28.2" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.2.tgz#fea200eac65fc7ecaff80a023d1a0543423b4c91" + integrity sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w== + dependencies: + "@fastify/busboy" "^2.0.0" + +unenv@^1.7.4, unenv@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.8.0.tgz#0f860d5278405700bd95d47b23bc01f3a735d68c" + integrity sha512-uIGbdCWZfhRRmyKj1UioCepQ0jpq638j/Cf0xFTn4zD1nGJ2lSdzYHLzfdXN791oo/0juUiSWW1fBklXMTsuqg== + dependencies: + consola "^3.2.3" + defu "^6.1.3" + mime "^3.0.0" + node-fetch-native "^1.4.1" + pathe "^1.1.1" + +unenv@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.9.0.tgz#469502ae85be1bd3a6aa60f810972b1a904ca312" + integrity sha512-QKnFNznRxmbOF1hDgzpqrlIf6NC5sbZ2OJ+5Wl3OX8uM+LUJXbj4TXvLJCtwbPTmbMHCLIz6JLKNinNsMShK9g== + dependencies: + consola "^3.2.3" + defu "^6.1.3" + mime "^3.0.0" + node-fetch-native "^1.6.1" + pathe "^1.1.1" + +unhead@1.8.10: + version "1.8.10" + resolved "https://registry.yarnpkg.com/unhead/-/unhead-1.8.10.tgz#dd8aeda5ba3388e44f585dcd8f3d3e67d97e2cc1" + integrity sha512-dth8FvZkLriO5ZWWOBIYBNSfGiwJtKcqpPWpSOk/Z0e2jdlgwoZEWZHFyte0EKvmbZxKcsWNMqIuv7dEmS5yZQ== + dependencies: + "@unhead/dom" "1.8.10" + "@unhead/schema" "1.8.10" + "@unhead/shared" "1.8.10" + hookable "^5.5.3" + +unicorn-magic@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4" + integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ== + +unimport@^3.5.0, unimport@^3.6.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/unimport/-/unimport-3.6.1.tgz#b1448ba7c86ee5fca362ba4030691759205998f9" + integrity sha512-zKzbp8AQ+l8QK3XrONtUBdgBbMI8TkGh8hBYF77ZkVqMLLIAHwGSwJRFolPQMBx/5pezeRKvmu2gzlqnxRZeqQ== + dependencies: + "@rollup/pluginutils" "^5.1.0" + escape-string-regexp "^5.0.0" + fast-glob "^3.3.2" + local-pkg "^0.5.0" + magic-string "^0.30.5" + mlly "^1.4.2" + pathe "^1.1.1" + pkg-types "^1.0.3" + scule "^1.1.1" + strip-literal "^1.3.0" + unplugin "^1.5.1" + +unimport@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/unimport/-/unimport-3.7.1.tgz#37250d0f3f2dcf1e1b66ed13728db0e9f50ba0c3" + integrity sha512-V9HpXYfsZye5bPPYUgs0Otn3ODS1mDUciaBlXljI4C2fTwfFpvFZRywmlOu943puN9sncxROMZhsZCjNXEpzEQ== + dependencies: + "@rollup/pluginutils" "^5.1.0" + acorn "^8.11.2" + escape-string-regexp "^5.0.0" + estree-walker "^3.0.3" + fast-glob "^3.3.2" + local-pkg "^0.5.0" + magic-string "^0.30.5" + mlly "^1.4.2" + pathe "^1.1.1" + pkg-types "^1.0.3" + scule "^1.1.1" + strip-literal "^1.3.0" + unplugin "^1.5.1" + +unique-filename@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" + integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== + dependencies: + unique-slug "^4.0.0" + +unique-slug@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" + integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== + dependencies: + imurmurhash "^0.1.4" + +unist-util-stringify-position@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" + integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== + dependencies: + "@types/unist" "^2.0.2" + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unplugin-vue-router@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/unplugin-vue-router/-/unplugin-vue-router-0.7.0.tgz#27bd250c7dc698366cce70c5b72b97c3b3766c26" + integrity sha512-ddRreGq0t5vlSB7OMy4e4cfU1w2AwBQCwmvW3oP/0IHQiokzbx4hd3TpwBu3eIAFVuhX2cwNQwp1U32UybTVCw== + dependencies: + "@babel/types" "^7.22.19" + "@rollup/pluginutils" "^5.0.4" + "@vue-macros/common" "^1.8.0" + ast-walker-scope "^0.5.0" + chokidar "^3.5.3" + fast-glob "^3.3.1" + json5 "^2.2.3" + local-pkg "^0.4.3" + mlly "^1.4.2" + pathe "^1.1.1" + scule "^1.0.0" + unplugin "^1.5.0" + yaml "^2.3.2" + +unplugin@^1.3.1, unplugin@^1.5.0, unplugin@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.5.1.tgz#806688376fa3dcca4d2fa2c5d27cf6cd0370fbef" + integrity sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew== + dependencies: + acorn "^8.11.2" + chokidar "^3.5.3" + webpack-sources "^3.2.3" + webpack-virtual-modules "^0.6.0" + +unplugin@^1.6.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.7.1.tgz#009571e3128640f4e327f33680d2db27afaf1e11" + integrity sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw== + dependencies: + acorn "^8.11.3" + chokidar "^3.5.3" + webpack-sources "^3.2.3" + webpack-virtual-modules "^0.6.1" + +unstorage@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/unstorage/-/unstorage-1.10.1.tgz#bf8cc00a406e40a6293e893da9807057d95875b0" + integrity sha512-rWQvLRfZNBpF+x8D3/gda5nUCQL2PgXy2jNG4U7/Rc9BGEv9+CAJd0YyGCROUBKs9v49Hg8huw3aih5Bf5TAVw== + dependencies: + anymatch "^3.1.3" + chokidar "^3.5.3" + destr "^2.0.2" + h3 "^1.8.2" + ioredis "^5.3.2" + listhen "^1.5.5" + lru-cache "^10.0.2" + mri "^1.2.0" + node-fetch-native "^1.4.1" + ofetch "^1.3.3" + ufo "^1.3.1" + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + +untun@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/untun/-/untun-0.1.2.tgz#fa42a62ae24c1c5c6f3209692a2b0e1f573f1353" + integrity sha512-wLAMWvxfqyTiBODA1lg3IXHQtjggYLeTK7RnSfqtOXixWJ3bAa2kK/HHmOOg19upteqO3muLvN6O/icbyQY33Q== + dependencies: + citty "^0.1.3" + consola "^3.2.3" + pathe "^1.1.1" + +untyped@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/untyped/-/untyped-1.4.0.tgz#c2e84bea78372ca7841f179504d5596af4e85a89" + integrity sha512-Egkr/s4zcMTEuulcIb7dgURS6QpN7DyqQYdf+jBtiaJvQ+eRsrtWUoX84SbvQWuLkXsOjM+8sJC9u6KoMK/U7Q== + dependencies: + "@babel/core" "^7.22.9" + "@babel/standalone" "^7.22.9" + "@babel/types" "^7.22.5" + defu "^6.1.2" + jiti "^1.19.1" + mri "^1.2.0" + scule "^1.0.0" + +untyped@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/untyped/-/untyped-1.4.2.tgz#7945ea53357635434284e6112fd1afe84dd5dcab" + integrity sha512-nC5q0DnPEPVURPhfPQLahhSTnemVtPzdx7ofiRxXpOB2SYnb3MfdU3DVGyJdS8Lx+tBWeAePO8BfU/3EgksM7Q== + dependencies: + "@babel/core" "^7.23.7" + "@babel/standalone" "^7.23.8" + "@babel/types" "^7.23.6" + defu "^6.1.4" + jiti "^1.21.0" + mri "^1.2.0" + scule "^1.2.0" + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uqr@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/uqr/-/uqr-0.1.2.tgz#5c6cd5dcff9581f9bb35b982cb89e2c483a41d7d" + integrity sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urlpattern-polyfill@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz#99f096e35eff8bf4b5a2aa7d58a1523d6ebc7ce5" + integrity sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ== + +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 sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validate-npm-package-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713" + integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== + dependencies: + builtins "^5.0.0" + +vary@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +vite-node@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.2.2.tgz#f6d329b06f9032130ae6eac1dc773f3663903c25" + integrity sha512-1as4rDTgVWJO3n1uHmUYqq7nsFgINQ9u+mRcXpjeOMJUmviqNKjcZB7UfRZrlM7MjYXMKpuWp5oGkjaFLnjawg== + dependencies: + cac "^6.7.14" + debug "^4.3.4" + pathe "^1.1.1" + picocolors "^1.0.0" + vite "^5.0.0" + +vite-plugin-checker@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/vite-plugin-checker/-/vite-plugin-checker-0.6.4.tgz#aca186ab605aa15bd2c5dd9cc6d7c8fdcbe214ec" + integrity sha512-2zKHH5oxr+ye43nReRbC2fny1nyARwhxdm0uNYp/ERy4YvU9iZpNOsueoi/luXw5gnpqRSvjcEPxXbS153O2wA== + dependencies: + "@babel/code-frame" "^7.12.13" + ansi-escapes "^4.3.0" + chalk "^4.1.1" + chokidar "^3.5.1" + commander "^8.0.0" + fast-glob "^3.2.7" + fs-extra "^11.1.0" + npm-run-path "^4.0.1" + semver "^7.5.0" + strip-ansi "^6.0.0" + tiny-invariant "^1.1.0" + vscode-languageclient "^7.0.0" + vscode-languageserver "^7.0.0" + vscode-languageserver-textdocument "^1.0.1" + vscode-uri "^3.0.2" + +vite-plugin-inspect@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/vite-plugin-inspect/-/vite-plugin-inspect-0.8.1.tgz#40cd353ceeb0967e9264e3dad69bdbde502e82c7" + integrity sha512-oPBPVGp6tBd5KdY/qY6lrbLXqrbHRG0hZLvEaJfiZ/GQfDB+szRuLHblQh1oi1Hhh8GeLit/50l4xfs2SA+TCA== + dependencies: + "@antfu/utils" "^0.7.6" + "@rollup/pluginutils" "^5.0.5" + debug "^4.3.4" + error-stack-parser-es "^0.1.1" + fs-extra "^11.1.1" + open "^9.1.0" + picocolors "^1.0.0" + sirv "^2.0.3" + +vite-plugin-vue-inspector@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-4.0.2.tgz#1d02646b20f4dc72cda0c2e0309551c7b332df73" + integrity sha512-KPvLEuafPG13T7JJuQbSm5PwSxKFnVS965+MP1we2xGw9BPkkc/+LPix5MMWenpKWqtjr0ws8THrR+KuoDC8hg== + dependencies: + "@babel/core" "^7.23.0" + "@babel/plugin-proposal-decorators" "^7.23.0" + "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-transform-typescript" "^7.22.15" + "@vue/babel-plugin-jsx" "^1.1.5" + "@vue/compiler-dom" "^3.3.4" + kolorist "^1.8.0" + magic-string "^0.30.4" + +vite@5.0.12, vite@^5.0.0: + version "5.0.12" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.0.12.tgz#8a2ffd4da36c132aec4adafe05d7adde38333c47" + integrity sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w== + dependencies: + esbuild "^0.19.3" + postcss "^8.4.32" + rollup "^4.2.0" + optionalDependencies: + fsevents "~2.3.3" + +vscode-jsonrpc@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e" + integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg== + +vscode-languageclient@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz#b505c22c21ffcf96e167799757fca07a6bad0fb2" + integrity sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg== + dependencies: + minimatch "^3.0.4" + semver "^7.3.4" + vscode-languageserver-protocol "3.16.0" + +vscode-languageserver-protocol@3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821" + integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A== + dependencies: + vscode-jsonrpc "6.0.0" + vscode-languageserver-types "3.16.0" + +vscode-languageserver-textdocument@^1.0.1: + version "1.0.11" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz#0822a000e7d4dc083312580d7575fe9e3ba2e2bf" + integrity sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA== + +vscode-languageserver-types@3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247" + integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA== + +vscode-languageserver@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz#49b068c87cfcca93a356969d20f5d9bdd501c6b0" + integrity sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw== + dependencies: + vscode-languageserver-protocol "3.16.0" + +vscode-uri@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f" + integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== + +vue-bundle-renderer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/vue-bundle-renderer/-/vue-bundle-renderer-2.0.0.tgz#ecab5c9b2803ab2454ba212afef502e684ddbb8e" + integrity sha512-oYATTQyh8XVkUWe2kaKxhxKVuuzK2Qcehe+yr3bGiaQAhK3ry2kYE4FWOfL+KO3hVFwCdLmzDQTzYhTi9C+R2A== + dependencies: + ufo "^1.2.0" + +vue-demi@>=0.14.5, vue-demi@>=0.14.6: + version "0.14.6" + resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92" + integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w== + +vue-devtools-stub@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/vue-devtools-stub/-/vue-devtools-stub-0.1.0.tgz#a65b9485edecd4273cedcb8102c739b83add2c81" + integrity sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ== + +vue-eslint-parser@^9.4.2: + version "9.4.2" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz#02ffcce82042b082292f2d1672514615f0d95b6d" + integrity sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ== + dependencies: + debug "^4.3.4" + eslint-scope "^7.1.1" + eslint-visitor-keys "^3.3.0" + espree "^9.3.1" + esquery "^1.4.0" + lodash "^4.17.21" + semver "^7.3.6" + +vue-router@^4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.2.5.tgz#b9e3e08f1bd9ea363fdd173032620bc50cf0e98a" + integrity sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw== + dependencies: + "@vue/devtools-api" "^6.5.0" + +vue@3.4.15, vue@^3.4.15: + version "3.4.15" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.15.tgz#91f979844ffca9239dff622ba4c79c5d5524b88c" + integrity sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ== + dependencies: + "@vue/compiler-dom" "3.4.15" + "@vue/compiler-sfc" "3.4.15" + "@vue/runtime-dom" "3.4.15" + "@vue/server-renderer" "3.4.15" + "@vue/shared" "3.4.15" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack-virtual-modules@^0.6.0, webpack-virtual-modules@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.1.tgz#ac6fdb9c5adb8caecd82ec241c9631b7a3681b6f" + integrity sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" + integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== + dependencies: + isexe "^2.0.0" + +which@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/which/-/which-4.0.0.tgz#cd60b5e74503a3fbcfbf6cd6b4138a8bae644c1a" + integrity sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg== + dependencies: + isexe "^3.1.1" + +wide-align@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +"wrap-ansi-cjs@npm:wrap-ansi@^7.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 sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^8.16.0: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== + +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml-eslint-parser@^1.2.1, yaml-eslint-parser@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz#1a9673ebe254328cfc2fa99f297f6d8c9364ccd8" + integrity sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg== + dependencies: + eslint-visitor-keys "^3.0.0" + lodash "^4.17.21" + yaml "^2.0.0" + +yaml@^2.0.0, yaml@^2.3.2, yaml@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.2.1, yargs@^17.5.1, yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +ylru@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.3.2.tgz#0de48017473275a4cbdfc83a1eaf67c01af8a785" + integrity sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zhead@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/zhead/-/zhead-2.2.4.tgz#87cd1e2c3d2f465fa9f43b8db23f9716dfe6bed7" + integrity sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag== + +zip-stream@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-5.0.1.tgz#cf3293bba121cad98be2ec7f05991d81d9f18134" + integrity sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA== + dependencies: + archiver-utils "^4.0.1" + compress-commons "^5.0.1" + readable-stream "^3.6.0" From 1b0514645d5ca70b673de545e8d5e35f3e264846 Mon Sep 17 00:00:00 2001 From: Vincent Fiduccia Date: Mon, 12 Feb 2024 14:31:17 -0700 Subject: [PATCH 070/774] Update actions to not complain about node verison --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 310c4f2f..70f03f53 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,10 +11,10 @@ jobs: test: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 1 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: cache: false go-version: "1.21" From b28a7d001e2796b7cb3de7b3ab2817d65f42c98f Mon Sep 17 00:00:00 2001 From: Vincent Fiduccia Date: Mon, 12 Feb 2024 14:59:51 -0700 Subject: [PATCH 071/774] Redirect / from browser to /ui --- pkg/server/server.go | 17 ++++++++++++++++- ui/Makefile | 1 + ui/components/left-nav.vue | 2 +- ui/stores/gpts.ts | 4 ++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pkg/server/server.go b/pkg/server/server.go index ad56e6b3..048fca36 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -234,6 +234,21 @@ func (s *Server) Connect(session *melody.Session) { } func (s *Server) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + isUpgrade := strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") + isBrowser := strings.Contains(strings.ToLower(req.Header.Get("User-Agent")), "mozilla") + isAjax := req.Header.Get("X-Requested-With") != "" + + if req.URL.Path == "/" && isBrowser && !isAjax && !isUpgrade { + rw.Header().Set("Location", "/ui/") + rw.WriteHeader(302) + return + } + + if req.URL.Path == "/favicon.ico" { + http.ServeFileFS(rw, req, static.UI, "/ui/favicon.ico") + return + } + if strings.HasPrefix(req.URL.Path, "/ui") { path := req.URL.Path if path == "/ui" || path == "/ui/" { @@ -250,7 +265,7 @@ func (s *Server) ServeHTTP(rw http.ResponseWriter, req *http.Request) { case http.MethodPost: s.run(rw, req) case http.MethodGet: - if req.URL.Path == "/" && strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { + if req.URL.Path == "/" && isUpgrade { err := s.melody.HandleRequest(rw, req) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) diff --git a/ui/Makefile b/ui/Makefile index 0e70cf24..2213ddab 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -3,6 +3,7 @@ build: clean yarn generate rm -rf ../static/ui/_nuxt cp -rp .output/public/* ../static/ui/ + touch ../static/ui/_nuxt/_placeholder clean: yarn clean diff --git a/ui/components/left-nav.vue b/ui/components/left-nav.vue index 2b9d7da6..84290689 100644 --- a/ui/components/left-nav.vue +++ b/ui/components/left-nav.vue @@ -4,7 +4,7 @@ const gptList = await useGpts().listAll() const runList = await useRuns().findAll() const gptLinks = computed(() => { - return (gptList.value || []).map(x => { return { + return (gptList || []).map(x => { return { label: x, icon: 'i-heroicons-wrench-screwdriver', to: `/gpt/` + x.split('/').map(y => encodeURIComponent(y)).join('/'), diff --git a/ui/stores/gpts.ts b/ui/stores/gpts.ts index 809290aa..bc483017 100644 --- a/ui/stores/gpts.ts +++ b/ui/stores/gpts.ts @@ -27,8 +27,8 @@ export const useGpts = defineStore('gpts', { async listAll() { const url = useRuntimeConfig().public.api - const { data } = (await useFetch(url) as any as {data: Ref}) - return data + const data = await $fetch(url, {headers: {'X-Requested-With': 'fetch'} }) as string[] + return reactive(data) } } }) From 9af903f61c908e0aa1eb7a85d0c9450f609002a9 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 12 Feb 2024 16:52:34 -0700 Subject: [PATCH 072/774] Add program name --- pkg/engine/engine.go | 2 +- pkg/loader/loader.go | 1 + pkg/types/tool.go | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 54e82e4b..07cb02bd 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -18,7 +18,7 @@ import ( var InternalSystemPrompt = ` You are task oriented system. You receive input from a user, process the input from the given instructions, and then output the result. -Your objective is to provide consist and correct results. +Your objective is to provide consistent and correct results. You do not need to explain the steps taken, only provide the result to the given instructions. You are referred to as a tool. ` diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index fcb68d26..eb8ffa01 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -359,6 +359,7 @@ func ProgramFromSource(ctx context.Context, content, subToolName string) (types. func Program(ctx context.Context, name, subToolName string) (types.Program, error) { prg := types.Program{ + Name: name, ToolSet: types.ToolSet{}, } tool, err := resolve(ctx, &prg, &source{}, name, subToolName) diff --git a/pkg/types/tool.go b/pkg/types/tool.go index 0db773ea..6bc0b6e2 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -15,6 +15,7 @@ const ( type ToolSet map[string]Tool type Program struct { + Name string `json:"name,omitempty"` EntryToolID string `json:"entryToolId,omitempty"` ToolSet ToolSet `json:"toolSet,omitempty"` Exports map[string]string `json:"exports,omitempty"` From f1850a2d79d05a5ecca1b685d09b03a3b87fa6cc Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Mon, 12 Feb 2024 21:03:18 -0500 Subject: [PATCH 073/774] chore: add docker build ci Add Dockerfile, goreleaser config, and GitHub workflows to build docker images and publish them to ghcr. Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- .github/workflows/main.yaml | 29 ++++++++++++++++++++++-- .github/workflows/release.yaml | 15 ++++++++++++- .goreleaser.yml | 40 ++++++++++++++++++++++++++++++++++ Dockerfile | 9 ++++++++ 4 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 Dockerfile diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index bf95f9d4..798d5d2a 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -11,9 +11,10 @@ on: permissions: contents: write + packages: write jobs: - release-snapshot: + release-main: runs-on: ubuntu-22.04 steps: - name: Checkout @@ -24,7 +25,20 @@ jobs: uses: actions/setup-go@v4 with: cache: false - go-version: "1.21" + go-version: "1.22" + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + with: + buildkitd-flags: --debug + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v4 with: @@ -34,3 +48,14 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_PROJECT_TOKEN: ${{ secrets.GH_PROJECT_TOKEN }} + - name: Push Docker Images + run: | + VERSION=v$(cat releases/metadata.json | jq -r .version) + IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "$VERSION") + for i in ${IMAGES}; do + docker push $i + done + docker manifest create ghcr.io/gptscript-ai/gptscript:main ${IMAGES} + docker manifest push ghcr.io/gptscript-ai/gptscript:main + docker manifest create ghcr.io/gptscript-ai/gptscript:${VERSION} ${IMAGES} + docker manifest push ghcr.io/gptscript-ai/gptscript:${VERSION} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1ad22624..9b3b51eb 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -20,7 +20,20 @@ jobs: uses: actions/setup-go@v4 with: cache: false - go-version: "1.21" + go-version: "1.22" + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + with: + buildkitd-flags: --debug + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v4 with: diff --git a/.goreleaser.yml b/.goreleaser.yml index 99b892f5..fc9b8483 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -65,3 +65,43 @@ brews: owner: gptscript-ai name: homebrew-tap token: "{{ .Env.GH_PROJECT_TOKEN }}" + +dockers: + - use: buildx + goos: linux + goarch: amd64 + image_templates: + - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-amd64 + build_flag_templates: + - "--pull" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.source=https://github.com/gptscript-ai/gptscript" + - "--platform=linux/amd64" + - use: buildx + goos: linux + goarch: arm64 + image_templates: + - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-arm64 + build_flag_templates: + - "--pull" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.source=https://github.com/gptscript-ai/gptscript" + - "--platform=linux/arm64" + +docker_manifests: + - use: docker + name_template: ghcr.io/gptscript-ai/gptscript:v{{ .Version }} + image_templates: + - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-amd64 + - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-arm64 + - use: docker + name_template: ghcr.io/gptscript-ai/gptscript:latest + image_templates: + - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-amd64 + - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-arm64 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..9e40f485 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM golang:1.22.0-alpine3.19 AS build +RUN apk add -U --no-cache make git +COPY / /src/gptscript +WORKDIR /src/gptscript +RUN make build + +FROM alpine AS release +COPY --from=build /src/gptscript/bin /usr/local/bin/ +ENTRYPOINT ["/usr/local/bin/gptscript"] From a145d5b206f0df54908ee9bbdff784657bb9739d Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Mon, 12 Feb 2024 21:38:09 -0500 Subject: [PATCH 074/774] chore: generate versioned brew formulae Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- .goreleaser.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 99b892f5..0df6e334 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -55,7 +55,8 @@ release: prerelease: auto brews: - - description: "GPTScript CLI" + - name: gptscript@{{ .Major }}.{{ .Minor }}.{{ .Patch }} + description: "GPTScript CLI" install: | bin.install "gptscript" homepage: "https://github.com/gptscript-ai/gptscript" From b1bba71ac34ab1e9c718498d31cf8db9c2299a51 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Mon, 12 Feb 2024 22:56:40 -0500 Subject: [PATCH 075/774] chore: go back to publishing only the latest version to brew Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- .goreleaser.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 1b7495fd..fc9b8483 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -55,8 +55,7 @@ release: prerelease: auto brews: - - name: gptscript@{{ .Major }}.{{ .Minor }}.{{ .Patch }} - description: "GPTScript CLI" + - description: "GPTScript CLI" install: | bin.install "gptscript" homepage: "https://github.com/gptscript-ai/gptscript" From 7321fb20d779df84503010db6f67c7a777202222 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Tue, 13 Feb 2024 00:24:59 -0500 Subject: [PATCH 076/774] chore: upload release and main builds to s3 Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- .github/workflows/main.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 798d5d2a..d0af21d5 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -48,6 +48,17 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_PROJECT_TOKEN: ${{ secrets.GH_PROJECT_TOKEN }} + - name: Upload to S3 + uses: jakejarvis/s3-sync-action@v0.5.1 + with: + args: --acl public-read + env: + SOURCE_DIR: releases + DEST_DIR: releases + AWS_REGION: ${{ secrets.AWS_REGION }} + AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - name: Push Docker Images run: | VERSION=v$(cat releases/metadata.json | jq -r .version) From f4751f450a78fd44d7a715475312f55a02ad822d Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Tue, 13 Feb 2024 00:46:15 -0500 Subject: [PATCH 077/774] chore: temporarily disable docker ci Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- .github/workflows/main.yaml | 24 -------------------- .github/workflows/release.yaml | 13 ----------- .goreleaser.yml | 40 ---------------------------------- 3 files changed, 77 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index d0af21d5..b9ea9aa7 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -26,19 +26,6 @@ jobs: with: cache: false go-version: "1.22" - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v2 - with: - buildkitd-flags: --debug - - name: Login to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v4 with: @@ -59,14 +46,3 @@ jobs: AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - - name: Push Docker Images - run: | - VERSION=v$(cat releases/metadata.json | jq -r .version) - IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "$VERSION") - for i in ${IMAGES}; do - docker push $i - done - docker manifest create ghcr.io/gptscript-ai/gptscript:main ${IMAGES} - docker manifest push ghcr.io/gptscript-ai/gptscript:main - docker manifest create ghcr.io/gptscript-ai/gptscript:${VERSION} ${IMAGES} - docker manifest push ghcr.io/gptscript-ai/gptscript:${VERSION} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9b3b51eb..3fe23c34 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -21,19 +21,6 @@ jobs: with: cache: false go-version: "1.22" - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v2 - with: - buildkitd-flags: --debug - - name: Login to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - name: Run GoReleaser uses: goreleaser/goreleaser-action@v4 with: diff --git a/.goreleaser.yml b/.goreleaser.yml index fc9b8483..99b892f5 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -65,43 +65,3 @@ brews: owner: gptscript-ai name: homebrew-tap token: "{{ .Env.GH_PROJECT_TOKEN }}" - -dockers: - - use: buildx - goos: linux - goarch: amd64 - image_templates: - - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-amd64 - build_flag_templates: - - "--pull" - - "--label=org.opencontainers.image.created={{.Date}}" - - "--label=org.opencontainers.image.title={{.ProjectName}}" - - "--label=org.opencontainers.image.revision={{.FullCommit}}" - - "--label=org.opencontainers.image.version={{.Version}}" - - "--label=org.opencontainers.image.source=https://github.com/gptscript-ai/gptscript" - - "--platform=linux/amd64" - - use: buildx - goos: linux - goarch: arm64 - image_templates: - - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-arm64 - build_flag_templates: - - "--pull" - - "--label=org.opencontainers.image.created={{.Date}}" - - "--label=org.opencontainers.image.title={{.ProjectName}}" - - "--label=org.opencontainers.image.revision={{.FullCommit}}" - - "--label=org.opencontainers.image.version={{.Version}}" - - "--label=org.opencontainers.image.source=https://github.com/gptscript-ai/gptscript" - - "--platform=linux/arm64" - -docker_manifests: - - use: docker - name_template: ghcr.io/gptscript-ai/gptscript:v{{ .Version }} - image_templates: - - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-amd64 - - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-arm64 - - use: docker - name_template: ghcr.io/gptscript-ai/gptscript:latest - image_templates: - - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-amd64 - - ghcr.io/gptscript-ai/gptscript:v{{ .Version }}-arm64 From 7403431d849c6d439be5281fce235b54444b3e64 Mon Sep 17 00:00:00 2001 From: Vincent Fiduccia Date: Mon, 12 Feb 2024 18:23:14 -0700 Subject: [PATCH 078/774] Use localTools to get tool options Signed-off-by: Vincent Fiduccia --- ui/pages/gpt/[...gpt].vue | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ui/pages/gpt/[...gpt].vue b/ui/pages/gpt/[...gpt].vue index fbb95e16..27ff85a4 100644 --- a/ui/pages/gpt/[...gpt].vue +++ b/ui/pages/gpt/[...gpt].vue @@ -31,18 +31,21 @@ const args = ref({}) const stringArg = ref('') + const entryTool = computed(() => { + return gpt.toolSet[gpt.entryToolId] + }) + const tool = computed(() => { return gpt.toolSet[toolNameToId(toolName.value)] }) const toolOptions = computed((): SelectOption[] => { - const toolset = gpt.toolSet || [] const out: SelectOption[] = [] - for ( const t of Object.values(toolset) ) { + for ( const k in entryTool.value?.localTools || {} ) { out.push({ - label: t.name || '', - value: t.name || '' + label: k || '', + value: k }) } From 2811bbb6267625e90a367686483cf947cdf28afb Mon Sep 17 00:00:00 2001 From: Vincent Fiduccia Date: Mon, 12 Feb 2024 19:59:09 -0700 Subject: [PATCH 079/774] Cmd-Enter to run Signed-off-by: Vincent Fiduccia --- ui/pages/gpt/[...gpt].vue | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ui/pages/gpt/[...gpt].vue b/ui/pages/gpt/[...gpt].vue index 27ff85a4..1639592a 100644 --- a/ui/pages/gpt/[...gpt].vue +++ b/ui/pages/gpt/[...gpt].vue @@ -1,5 +1,6 @@ + + diff --git a/ui/components/left-nav.vue b/ui/components/left-nav.vue index 9cb6f5b2..5e1d57e1 100644 --- a/ui/components/left-nav.vue +++ b/ui/components/left-nav.vue @@ -2,7 +2,6 @@ // const router = useRouter() const gptList = await useGpts().listAll() const runList = await useRuns().findAll() -const sock = useSocket() const gptLinks = computed(() => { return (gptList || []).map(x => { return { @@ -32,7 +31,7 @@ async function remove(e: MouseEvent, id: any) { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/ui/assets/logotype.svg b/ui/assets/logotype.svg new file mode 100644 index 00000000..9f12e1d2 --- /dev/null +++ b/ui/assets/logotype.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/pages/index.vue b/ui/pages/index.vue index 2a51b1ea..c3889ec1 100644 --- a/ui/pages/index.vue +++ b/ui/pages/index.vue @@ -1,6 +1,8 @@ diff --git a/ui/stores/gpts.ts b/ui/stores/gpts.ts index bc483017..d7023121 100644 --- a/ui/stores/gpts.ts +++ b/ui/stores/gpts.ts @@ -18,7 +18,7 @@ export const useGpts = defineStore('gpts', { } const url = useRuntimeConfig().public.api + id - const data = reactive(await $fetch(url)) + const data = reactive(await $fetch(url, {baseURL: '/'})) this.list.push(data) this.map[id] = data @@ -27,7 +27,7 @@ export const useGpts = defineStore('gpts', { async listAll() { const url = useRuntimeConfig().public.api - const data = await $fetch(url, {headers: {'X-Requested-With': 'fetch'} }) as string[] + const data = await $fetch(url, {baseURL: '/', headers: {'X-Requested-With': 'fetch'} }) as string[] return reactive(data) } } diff --git a/ui/stores/runs.ts b/ui/stores/runs.ts index f72169a5..03c9bddf 100644 --- a/ui/stores/runs.ts +++ b/ui/stores/runs.ts @@ -41,7 +41,7 @@ export const useRuns = defineStore('runs', { url = addParam(url, 'tool', toolName) } - const res = await $fetch(url, {method: 'POST', body: args}) as {id: string} + const res = await $fetch(url, {baseURL: '/', method: 'POST', body: args}) as {id: string} const id = res.id const obj: Run = reactive({ diff --git a/ui/stores/socket.ts b/ui/stores/socket.ts index 96f6a643..7fdac0de 100644 --- a/ui/stores/socket.ts +++ b/ui/stores/socket.ts @@ -12,7 +12,13 @@ interface SocketState { export const useSocket = defineStore('socket', { state: () => { - const url = useRuntimeConfig().public.api.replace(/^http/,'ws') + let url = useRuntimeConfig().public.api + if ( url.startsWith('/') ) { + url = `${window.location.origin}${url}` + } + + url = url.replace(/^http/,'ws') + const sock = useWebSocket(url, { immediate: false, autoReconnect: true, From 411df5888fd3450f7df674da6f55213a0d345397 Mon Sep 17 00:00:00 2001 From: Bill Maxwell Date: Thu, 22 Feb 2024 16:37:06 -0700 Subject: [PATCH 110/774] fix - typo in error message Signed-off-by: Bill Maxwell --- pkg/engine/engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 5cdbf3e8..512a9c47 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -323,7 +323,7 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu pending, ok := state.Pending[content.ToolCall.ID] if !ok { - return nil, fmt.Errorf("missing tool call pennding for id %s, most likely a %s BUG", + return nil, fmt.Errorf("missing tool call pending for id %s, most likely a %s BUG", content.ToolCall.ID, version.ProgramName) } From 9decf24fa8e15060f05ef95ab45b2e13bd9567d5 Mon Sep 17 00:00:00 2001 From: DJ Carpenter <59489977+djcarpe@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:06:40 -0600 Subject: [PATCH 111/774] fix - update hacker-news-headlines.gpt Enable re-running by checking for the mongodb container and either starting it or running it. Signed-off-by: DJ Carpenter <59489977+djcarpe@users.noreply.github.com> --- examples/hacker-news-headlines.gpt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/examples/hacker-news-headlines.gpt b/examples/hacker-news-headlines.gpt index 97878e13..7955371b 100644 --- a/examples/hacker-news-headlines.gpt +++ b/examples/hacker-news-headlines.gpt @@ -16,7 +16,24 @@ description: starts a MongoDB database #!/usr/bin/env bash -docker run --rm -d -p 27017:27017 --name mongodb mongo:latest +# The name of your container +CONTAINER_NAME=mongodb + +# Check if the container already exists +if docker ps -a --format '{{.Names}}' | grep -Eq "^${CONTAINER_NAME}\$"; then + echo "Container ${CONTAINER_NAME} exists." + + # Check if the container is already running + if ! docker ps --format '{{.Names}}' | grep -Eq "^${CONTAINER_NAME}\$"; then + echo "Starting existing container ${CONTAINER_NAME}." + docker start ${CONTAINER_NAME} + else + echo "Container ${CONTAINER_NAME} is already running." + fi +else + echo "Container ${CONTAINER_NAME} does not exist. Running a new one." + docker run --rm -d -p 27017:27017 --name ${CONTAINER_NAME} mongo:latest +fi --- name: mongo_command From dff4f932330db6cb71d576b1d885ee035e385984 Mon Sep 17 00:00:00 2001 From: tylerslaton Date: Thu, 22 Feb 2024 16:33:41 -0500 Subject: [PATCH 112/774] feat: add documentation site Signed-off-by: tylerslaton --- Makefile | 2 + docs/.gitignore | 20 + docs/README.md | 41 + docs/babel.config.js | 3 + docs/docs/01-introduction.md | 263 + docs/docs/tools/_category_.json | 8 + docs/docs/tools/image-generation.md | 25 + docs/docs/tools/system.md | 64 + docs/docusaurus.config.js | 83 + docs/package-lock.json | 14673 ++++++++++++++++++++++++++ docs/package.json | 44 + docs/sidebars.js | 20 + docs/src/css/custom.css | 30 + docs/static/.nojekyll | 0 docs/static/img/favicon.ico | 1 + docs/static/img/logo.svg | 1 + 16 files changed, 15278 insertions(+) create mode 100644 docs/.gitignore create mode 100644 docs/README.md create mode 100644 docs/babel.config.js create mode 100644 docs/docs/01-introduction.md create mode 100644 docs/docs/tools/_category_.json create mode 100644 docs/docs/tools/image-generation.md create mode 100644 docs/docs/tools/system.md create mode 100644 docs/docusaurus.config.js create mode 100644 docs/package-lock.json create mode 100644 docs/package.json create mode 100644 docs/sidebars.js create mode 100644 docs/src/css/custom.css create mode 100644 docs/static/.nojekyll create mode 100644 docs/static/img/favicon.ico create mode 100644 docs/static/img/logo.svg diff --git a/Makefile b/Makefile index afd7fe96..7a129674 100644 --- a/Makefile +++ b/Makefile @@ -37,3 +37,5 @@ validate: tidy lint ci: build ./bin/gptscript ./scripts/ci.gpt +serve-docs: + (cd docs && npm start) diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..b2d6de30 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..0c6c2c27 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,41 @@ +# Website + +This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. + +### Installation + +``` +$ yarn +``` + +### Local Development + +``` +$ yarn start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +### Build + +``` +$ yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +### Deployment + +Using SSH: + +``` +$ USE_SSH=true yarn deploy +``` + +Not using SSH: + +``` +$ GIT_USER= yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/docs/babel.config.js b/docs/babel.config.js new file mode 100644 index 00000000..e00595da --- /dev/null +++ b/docs/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/docs/docs/01-introduction.md b/docs/docs/01-introduction.md new file mode 100644 index 00000000..8662ac8f --- /dev/null +++ b/docs/docs/01-introduction.md @@ -0,0 +1,263 @@ +--- +title: Overview +slug: / +--- + +GPTScript is a new scripting language to automate your interaction with a Large Language Model (LLM), namely OpenAI. The ultimate goal is to create a fully natural language based programming experience. The syntax of GPTScript is largely natural language, making it very easy to learn and use. +Natural language prompts can be mixed with traditional scripts such as bash and python or even external HTTP service +calls. With GPTScript you can do just about anything like [plan a vacation](https://github.com/gptscript-ai/gptscript/blob/main/examples/travel-agent.gpt), +[edit a file](https://github.com/gptscript-ai/gptscript/blob/main/examples/add-go-mod-dep.gpt), [run some SQL](https://github.com/gptscript-ai/gptscript/blob/main/examples/sqlite-download.gpt), or [build a mongodb/flask app](https://github.com/gptscript-ai/gptscript/blob/main/examples/hacker-news-headlines.gpt). + +```yaml +# example.gpt + +Tools: sys.download, sys.exec, sys.remove + +Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to a +random file. Then expand the archive to a temporary location as there is a sqlite +database in it. + +First inspect the schema of the database to understand the table structure. + +Form and run a SQL query to find the artist with the most number of albums and output +the result of that. + +When done remove the database file and the downloaded content. +``` +``` +$ gptscript ./example.gpt + +OUTPUT: + +The artist with the most number of albums in the database is Iron Maiden, with a total +of 21 albums. +``` +## Quick Start + +### 1. Install the latest release + +#### Homebrew (macOS and Linux) + +```shell +brew install gptscript-ai/tap/gptscript +``` + +#### Install Script (macOS and Linux): + +```shell +curl https://get.gptscript.ai/install.sh | sh +``` + +#### WinGet (Windows) + +```shell +winget install gptscript-ai.gptscript +``` + +#### Manually + +Download and install the archive for your platform and architecture from the [releases page](https://github.com/gptscript-ai/gptscript/releases). + +### 2. Get an API key from [OpenAI](https://platform.openai.com/api-keys). + +```shell +export OPENAI_API_KEY="your-api-key" +``` + +### 3. Run Hello World + +```shell +gptscript https://get.gptscript.ai/echo.gpt --input 'Hello, World!' + +OUTPUT: + +Hello, World! +``` +The model used by default is `gpt-4-turbo-preview` and you must have access to that model in your OpenAI account. + +### 4. Extra Credit: Examples and Run Debugging UI + +Clone examples and run debugging UI +```shell +git clone https://github.com/gptscript-ai/gptscript +cd gptscript/examples + +# Run the debugging UI +gptscript --server +``` + +## How it works + +***GPTScript is composed of tools.*** Each tool performs a series of actions similar to a function. Tools have available +to them other tools that can be invoked similar to a function call. While similar to a function, the tools are +primarily implemented with a natural language prompt. ***The interaction of the tools is determined by the AI model***, +the model determines if the tool needs to be invoked and what arguments to pass. Tools are intended to be implemented +with a natural language prompt but can also be implemented with a command or HTTP call. + +### Example +Below are two tool definitions, separated by `---`. The first tool does not require a name or description, but +every tool after name and description are required. The first tool, has the parameter `tools: bob` meaning that the tool named `bob` is available to be called if needed. + +```yaml +tools: bob + +Ask Bob how he is doing and let me know exactly what he said. + +--- +name: bob +description: I'm Bob, a friendly guy. +args: question: The question to ask Bob. + +When asked how I am doing, respond with "Thanks for asking "${question}", I'm doing great fellow friendly AI tool!" +``` +Put the above content in a file named `bob.gpt` and run the following command: +```shell +$ gptscript bob.gpt + +OUTPUT: + +Bob said, "Thanks for asking 'How are you doing?', I'm doing great fellow friendly AI tool!" +``` +Tools can be implemented by invoking a program instead of a natural language prompt. The below +example is the same as the previous example but implements Bob using python. + +```yaml +Tools: bob + +Ask Bob how he is doing and let me know exactly what he said. + +--- +Name: bob +Description: I'm Bob, a friendly guy. +Args: question: The question to ask Bob. + +#!python3 + +import os + +print(f"Thanks for asking {os.environ['question']}, I'm doing great fellow friendly AI tool!") +``` + +With these basic building blocks you can create complex scripts with AI interacting with AI, your local system, data, +or external services. + +## GPT File Reference + +### Extension +GPTScript files use the `.gpt` extension by convention. + +### File Structure +A GPTScript file has one or more tools in the file. Each tool is separated by three dashes `---` alone on a line. + +```yaml +Name: tool1 +Description: This is tool1 + +Do sample tool stuff. + +--- +Name: tool2 +Description: This is tool2 + +Do more sample tool stuff. +``` + +### Tool Definition + +A tool starts with a preamble that defines the tool's name, description, args, available tools and additional parameters. +The preamble is followed by the tool's body, which contains the instructions for the tool. Comments in +the preamble are lines starting with `#` and are ignored by the parser. Comments are not really encouraged +as the text is typically more useful in the description, argument descriptions or instructions. + +```yaml +Name: tool-name +# This is a comment in the preamble. +Description: Tool description +# This tool can invoke tool1 or tool2 if needed +Tools: tool1, tool2 +Args: arg1: The description of arg1 + +Tool instructions go here. +``` +#### Tool Parameters + +Tool parameters are key-value pairs defined at the beginning of a tool block, before any instructional text. They are specified in the format `key: value`. The parser recognizes the following keys (case-insensitive and spaces are ignored): + +`Name`: The name of the tool. + +`Model Name`: The OpenAI model to use, by default it uses "gpt-4-turbo-preview" + +`Description`: The description of the tool. It is important that the properly describes the tool's purpose as the +description is used by the LLM to determine if the tool is to be invoked. + +`Internal Prompt`: Setting this to `false` will disable the built in system prompt for this tool. GPTScript includes a +default system prompt to instruct the AI to behave more like a script engine and not a "helpful assistant." + +`Tools`: A comma-separated list of tools that are available to be called by this tool. A tool can only call the tools +that are defined here. A tool name can reference a name in the current file, or a file relative to the current directory +of the tool file, a http(s) URL, or a file in GitHub using github.com/username/repo/file.gpt format. When referencing +a file or URL the tool loaded is the first tool in the file. To reference a specific tool in a file or URL use the +syntax `tool-name from file-or-url`. + +`Args`: Arguments for the tool. Each argument is defined in the format `arg-name: description`. All arguments are essentially +strings. No other type really exists as all input and output to tools is text based. + +`Max Tokens`: Set to a number if you wish to limit the maximum number of tokens that can be generated by the LLM. + +`JSON Response`: Setting to `true` will cause the LLM to respond in a JSON format. If you set true you must also include instructions in the tool +to inform the LLM to respond in some JSON structure. + +`Temperature`: A floating-point number representing the temperature parameter. By default the temperature is 0. Set to a higher number to make the LLM more creative. + +#### Tool Body + +The tool body contains the instructions for the tool which can be a natural language prompt or +a command to execute. Commands must start with `#!` followed by the interpreter (e.g. `#!/bin/bash`, `#!python3`) +a text that will be placed in a file and passed to the interpreter. Arguments can be references in the instructions +using the format `${arg1}`. + +```yaml +name: echo-ai +description: A tool that echos the input +args: input: The input + +Just return only "${input}" + +--- +name: echo-command +description: A tool that echos the input +args: input: The input + +#!/bin/bash + +echo "${input}" +``` + +## Built in Tools + +There are several built in tools to do basic things like read/write files, download http content and execute commands. +Run `gptscript --list-tools` to list all the built-in tools. + +## Examples + +For more examples check out the [examples](https://github.com/gptscript-ai/gptscript/blob/main/examples) directory. + +## Community + +Join us on Discord: [![Discord](https://img.shields.io/discord/1204558420984864829?label=Discord)](https://discord.gg/9sSf4UyAMC) + +## License + +Copyright (c) 2023 [Acorn Labs, Inc.](http://acorn.io) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/docs/docs/tools/_category_.json b/docs/docs/tools/_category_.json new file mode 100644 index 00000000..cd568683 --- /dev/null +++ b/docs/docs/tools/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Tools", + "position": 2, + "link": { + "type": "generated-index", + "description": "Explore the various tools on offer for gptscripts" + } +} diff --git a/docs/docs/tools/image-generation.md b/docs/docs/tools/image-generation.md new file mode 100644 index 00000000..9b0f32bc --- /dev/null +++ b/docs/docs/tools/image-generation.md @@ -0,0 +1,25 @@ +# Image Generation + +## Overview + +The `image-generation` tool leverages OpenAI's DALL-E model to convert textual descriptions into images. It offers a versatile approach to creating visual content, making it suitable for a wide range of applications, from content creation to design assistance. + +For more information, check out the tool [here](https://github.com/gptscript-ai/image-generation) + +## Usage +To use the Image Generation tool, you need to make sure that the OPENAI_API_KEY environment variable is set to your OpenAI API key. You can obtain an API key from the OpenAI platform if you don't already have one. + +With that setup, you can use it in any GPTScript like so: + +:::tip +This script assumes you have the `image-generation` tool repo cloned locally and located at `./image-generation`. The ability to import tools from remote +locations is coming soon. +::: + +``` +tools: ./image-generation, sys.write + +Generate an image of a city skyline at night with a resolution of 512x512 pixels. + +Write the resulting image to a file named "city_skyline.png". +``` diff --git a/docs/docs/tools/system.md b/docs/docs/tools/system.md new file mode 100644 index 00000000..9b22e10f --- /dev/null +++ b/docs/docs/tools/system.md @@ -0,0 +1,64 @@ +# System Tools +GPTScript comes with a set of system tools that provide various core functionalities. + +## sys.abort +Aborts the operation and provides an error message. +#### Arguments +- `message`: The description of the error or unexpected result that caused abort to be called. + +## sys.download +Downloads a file from a specified URL to an optional location on disk with an option to override existing files. +#### Arguments +- `location` (optional): The on-disk location to store the downloaded file. +- `override`: If true, allows overwriting of an existing file. Default is false. +- `url`: The HTTP or HTTPS URL of the file to be downloaded. + +## sys.exec +Executes a command with the ability to specify command arguments and the working directory. +#### Arguments +- `command`: The full command to run, including all arguments. +- `directory`: The working directory for the command. Defaults to the current directory ".". + +## sys.find +Searches for files within a directory that match a given pattern using Unix glob format. +#### Arguments +- `directory`: The directory to perform the search in. Defaults to the current directory ".". +- `pattern`: The pattern to match against filenames. + +## sys.getenv +Retrieves the value of an environment variable. +#### Arguments +- `name`: The name of the environment variable to retrieve. + +## sys.http.get +Performs an HTTP GET request to the specified URL. +#### Arguments +- `url`: The URL to perform the GET request. + +## sys.http.html2text +Converts the HTML content from a given URL to plain text. +#### Arguments +- `url`: The URL of the HTML content to be converted. + +## sys.http.post +Sends an HTTP POST request with given content to a specified URL. +#### Arguments +- `content`: The content to be posted. +- `contentType`: The MIME type of the content being posted. +- `url`: The URL to which the POST request should be sent. + +## sys.read +Reads the content from a specified file. +#### Arguments +- `filename`: The name of the file from which to read content. + +## sys.remove +Removes a file from the specified location. +#### Arguments +- `location`: The path to the file that needs to be removed. + +## sys.write +Writes content to a specified file. +#### Arguments +- `content`: The content to be written to the file. +- `filename`: The filename where the content should be written. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js new file mode 100644 index 00000000..e14420c4 --- /dev/null +++ b/docs/docusaurus.config.js @@ -0,0 +1,83 @@ +// @ts-check +// `@type` JSDoc annotations allow editor autocompletion and type checking +// (when paired with `@ts-check`). +// There are various equivalent ways to declare your Docusaurus config. +// See: https://docusaurus.io/docs/api/docusaurus-config + +import { themes as prismThemes } from "prism-react-renderer"; + +/** @type {import('@docusaurus/types').Config} */ +const config = { + title: "GPTScript Docs", + tagline: "Welcome to the GPTScript Docs", + favicon: "img/favicon.ico", + baseUrl: "/", + url: "https://docs.gptscript.ai", + organizationName: "gptscript-ai", + projectName: "gptscript", + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "warn", + trailingSlash: false, + + i18n: { + defaultLocale: "en", + locales: ["en"], + }, + + presets: [ + [ + "classic", + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + docs: { + sidebarPath: "./sidebars.js", + editUrl: "https://github.com/gptscript-ai/gptscript/tree/main/docs/", + routeBasePath: "/", // Serve the docs at the site's root + }, + theme: { + customCss: "./src/css/custom.css", + }, + blog: false, + }), + ], + ], + + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + // Replace with your project's social card + image: "img/docusaurus-social-card.jpg", + navbar: { + title: "GPTScript", + style: "dark", + logo: { + alt: "GPTScript Logo", + src: "img/logo.svg", + }, + items: [ + { + href: "https://github.com/gptscript-ai/gptscript", + label: "GitHub", + position: "right", + }, + ], + }, + footer: { + style: "dark", + links: [ + { + label: "GitHub", + to: "https://github.com/gptscript-ai/gptscript", + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} Acorn Labs, Inc`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + additionalLanguages: ["cue", "docker"], + }, + }), +}; + +export default config; diff --git a/docs/package-lock.json b/docs/package-lock.json new file mode 100644 index 00000000..9bbb14b2 --- /dev/null +++ b/docs/package-lock.json @@ -0,0 +1,14673 @@ +{ + "name": "docs", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "docs", + "version": "0.0.0", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/preset-classic": "3.1.1", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.1", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.1.1", + "@docusaurus/types": "3.1.1" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.22.1.tgz", + "integrity": "sha512-Sw6IAmOCvvP6QNgY9j+Hv09mvkvEIDKjYW8ow0UDDAxSXy664RBNQk3i/0nt7gvceOJ6jGmOTimaZoY1THmU7g==", + "dependencies": { + "@algolia/cache-common": "4.22.1" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.22.1.tgz", + "integrity": "sha512-TJMBKqZNKYB9TptRRjSUtevJeQVXRmg6rk9qgFKWvOy8jhCPdyNZV1nB3SKGufzvTVbomAukFR8guu/8NRKBTA==" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.22.1.tgz", + "integrity": "sha512-ve+6Ac2LhwpufuWavM/aHjLoNz/Z/sYSgNIXsinGofWOysPilQZPUetqLj8vbvi+DHZZaYSEP9H5SRVXnpsNNw==", + "dependencies": { + "@algolia/cache-common": "4.22.1" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.22.1.tgz", + "integrity": "sha512-k8m+oegM2zlns/TwZyi4YgCtyToackkOpE+xCaKCYfBfDtdGOaVZCM5YvGPtK+HGaJMIN/DoTL8asbM3NzHonw==", + "dependencies": { + "@algolia/client-common": "4.22.1", + "@algolia/client-search": "4.22.1", + "@algolia/transporter": "4.22.1" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.22.1.tgz", + "integrity": "sha512-1ssi9pyxyQNN4a7Ji9R50nSdISIumMFDwKNuwZipB6TkauJ8J7ha/uO60sPJFqQyqvvI+px7RSNRQT3Zrvzieg==", + "dependencies": { + "@algolia/client-common": "4.22.1", + "@algolia/client-search": "4.22.1", + "@algolia/requester-common": "4.22.1", + "@algolia/transporter": "4.22.1" + } + }, + "node_modules/@algolia/client-common": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.22.1.tgz", + "integrity": "sha512-IvaL5v9mZtm4k4QHbBGDmU3wa/mKokmqNBqPj0K7lcR8ZDKzUorhcGp/u8PkPC/e0zoHSTvRh7TRkGX3Lm7iOQ==", + "dependencies": { + "@algolia/requester-common": "4.22.1", + "@algolia/transporter": "4.22.1" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.22.1.tgz", + "integrity": "sha512-sl+/klQJ93+4yaqZ7ezOttMQ/nczly/3GmgZXJ1xmoewP5jmdP/X/nV5U7EHHH3hCUEHeN7X1nsIhGPVt9E1cQ==", + "dependencies": { + "@algolia/client-common": "4.22.1", + "@algolia/requester-common": "4.22.1", + "@algolia/transporter": "4.22.1" + } + }, + "node_modules/@algolia/client-search": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.22.1.tgz", + "integrity": "sha512-yb05NA4tNaOgx3+rOxAmFztgMTtGBi97X7PC3jyNeGiwkAjOZc2QrdZBYyIdcDLoI09N0gjtpClcackoTN0gPA==", + "dependencies": { + "@algolia/client-common": "4.22.1", + "@algolia/requester-common": "4.22.1", + "@algolia/transporter": "4.22.1" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, + "node_modules/@algolia/logger-common": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.22.1.tgz", + "integrity": "sha512-OnTFymd2odHSO39r4DSWRFETkBufnY2iGUZNrMXpIhF5cmFE8pGoINNPzwg02QLBlGSaLqdKy0bM8S0GyqPLBg==" + }, + "node_modules/@algolia/logger-console": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.22.1.tgz", + "integrity": "sha512-O99rcqpVPKN1RlpgD6H3khUWylU24OXlzkavUAMy6QZd1776QAcauE3oP8CmD43nbaTjBexZj2nGsBH9Tc0FVA==", + "dependencies": { + "@algolia/logger-common": "4.22.1" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.22.1.tgz", + "integrity": "sha512-dtQGYIg6MteqT1Uay3J/0NDqD+UciHy3QgRbk7bNddOJu+p3hzjTRYESqEnoX/DpEkaNYdRHUKNylsqMpgwaEw==", + "dependencies": { + "@algolia/requester-common": "4.22.1" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.22.1.tgz", + "integrity": "sha512-dgvhSAtg2MJnR+BxrIFqlLtkLlVVhas9HgYKMk2Uxiy5m6/8HZBL40JVAMb2LovoPFs9I/EWIoFVjOrFwzn5Qg==" + }, + "node_modules/@algolia/requester-node-http": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.22.1.tgz", + "integrity": "sha512-JfmZ3MVFQkAU+zug8H3s8rZ6h0ahHZL/SpMaSasTCGYR5EEJsCc8SI5UZ6raPN2tjxa5bxS13BRpGSBUens7EA==", + "dependencies": { + "@algolia/requester-common": "4.22.1" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.22.1.tgz", + "integrity": "sha512-kzWgc2c9IdxMa3YqA6TN0NW5VrKYYW/BELIn7vnLyn+U/RFdZ4lxxt9/8yq3DKV5snvoDzzO4ClyejZRdV3lMQ==", + "dependencies": { + "@algolia/cache-common": "4.22.1", + "@algolia/logger-common": "4.22.1", + "@algolia/requester-common": "4.22.1" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", + "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.9", + "@babel/parser": "^7.23.9", + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.23.10", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz", + "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", + "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", + "dependencies": { + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", + "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", + "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", + "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", + "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "dependencies": { + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz", + "integrity": "sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", + "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", + "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.9.tgz", + "integrity": "sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", + "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz", + "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@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-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@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-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.9", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.8", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.6", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.9", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.23.4", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", + "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.23.3", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "node_modules/@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.9.tgz", + "integrity": "sha512-oeOFTrYWdWXCvXGB5orvMTJ6gCZ9I6FBjR+M38iKNXCsPxr4xT0RTdg5uz1H7QP8pp74IzPtwritEr+JscqHXQ==", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", + "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", + "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", + "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/css": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz", + "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==" + }, + "node_modules/@docsearch/react": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz", + "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==", + "dependencies": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.5.2", + "algoliasearch": "^4.19.1" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.1.1.tgz", + "integrity": "sha512-2nQfKFcf+MLEM7JXsXwQxPOmQAR6ytKMZVSx7tVi9HEm9WtfwBH1fp6bn8Gj4zLUhjWKCLoysQ9/Wm+EZCQ4yQ==", + "dependencies": { + "@babel/core": "^7.23.3", + "@babel/generator": "^7.23.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.22.9", + "@babel/preset-env": "^7.22.9", + "@babel/preset-react": "^7.22.5", + "@babel/preset-typescript": "^7.22.5", + "@babel/runtime": "^7.22.6", + "@babel/runtime-corejs3": "^7.22.6", + "@babel/traverse": "^7.22.8", + "@docusaurus/cssnano-preset": "3.1.1", + "@docusaurus/logger": "3.1.1", + "@docusaurus/mdx-loader": "3.1.1", + "@docusaurus/react-loadable": "5.5.2", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-common": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "@slorber/static-site-generator-webpack-plugin": "^4.0.7", + "@svgr/webpack": "^6.5.1", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.1.3", + "babel-plugin-dynamic-import-node": "^2.3.3", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "clean-css": "^5.3.2", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "copy-webpack-plugin": "^11.0.0", + "core-js": "^3.31.1", + "css-loader": "^6.8.1", + "css-minimizer-webpack-plugin": "^4.2.2", + "cssnano": "^5.1.15", + "del": "^6.1.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "html-minifier-terser": "^7.2.0", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.5.3", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "mini-css-extract-plugin": "^2.7.6", + "postcss": "^8.4.26", + "postcss-loader": "^7.3.3", + "prompts": "^2.4.2", + "react-dev-utils": "^12.0.1", + "react-helmet-async": "^1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "rtl-detect": "^1.0.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.5", + "shelljs": "^0.8.5", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "url-loader": "^4.1.1", + "webpack": "^5.88.1", + "webpack-bundle-analyzer": "^4.9.0", + "webpack-dev-server": "^4.15.1", + "webpack-merge": "^5.9.0", + "webpackbar": "^5.0.2" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.1.1.tgz", + "integrity": "sha512-LnoIDjJWbirdbVZDMq+4hwmrTl2yHDnBf9MLG9qyExeAE3ac35s4yUhJI8yyTCdixzNfKit4cbXblzzqMu4+8g==", + "dependencies": { + "cssnano-preset-advanced": "^5.3.10", + "postcss": "^8.4.26", + "postcss-sort-media-queries": "^4.4.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.1.1.tgz", + "integrity": "sha512-BjkNDpQzewcTnST8trx4idSoAla6zZ3w22NqM/UMcFtvYJgmoE4layuTzlfql3VFPNuivvj7BOExa/+21y4X2Q==", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.1.1.tgz", + "integrity": "sha512-xN2IccH9+sv7TmxwsDJNS97BHdmlqWwho+kIVY4tcCXkp+k4QuzvWBeunIMzeayY4Fu13A6sAjHGv5qm72KyGA==", + "dependencies": { + "@babel/parser": "^7.22.7", + "@babel/traverse": "^7.22.8", + "@docusaurus/logger": "3.1.1", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^1.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.1.tgz", + "integrity": "sha512-xBJyx0TMfAfVZ9ZeIOb1awdXgR4YJMocIEzTps91rq+hJDFJgJaylDtmoRhUxkwuYmNK1GJpW95b7DLztSBJ3A==", + "dependencies": { + "@docusaurus/react-loadable": "5.5.2", + "@docusaurus/types": "3.1.1", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "*", + "react-loadable": "npm:@docusaurus/react-loadable@5.5.2" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.1.1.tgz", + "integrity": "sha512-ew/3VtVoG3emoAKmoZl7oKe1zdFOsI0NbcHS26kIxt2Z8vcXKCUgK9jJJrz0TbOipyETPhqwq4nbitrY3baibg==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/logger": "3.1.1", + "@docusaurus/mdx-loader": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-common": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "cheerio": "^1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "reading-time": "^1.5.0", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.1.1.tgz", + "integrity": "sha512-lhFq4E874zw0UOH7ujzxnCayOyAt0f9YPVYSb9ohxrdCM8B4szxitUw9rIX4V9JLLHVoqIJb6k+lJJ1jrcGJ0A==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/logger": "3.1.1", + "@docusaurus/mdx-loader": "3.1.1", + "@docusaurus/module-type-aliases": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.1.1.tgz", + "integrity": "sha512-NQHncNRAJbyLtgTim9GlEnNYsFhuCxaCNkMwikuxLTiGIPH7r/jpb7O3f3jUMYMebZZZrDq5S7om9a6rvB/YCA==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/mdx-loader": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.1.1.tgz", + "integrity": "sha512-xWeMkueM9wE/8LVvl4+Qf1WqwXmreMjI5Kgr7GYCDoJ8zu4kD+KaMhrh7py7MNM38IFvU1RfrGKacCEe2DRRfQ==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils": "3.1.1", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^1.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.1.1.tgz", + "integrity": "sha512-+q2UpWTqVi8GdlLoSlD5bS/YpxW+QMoBwrPrUH/NpvpuOi0Of7MTotsQf9JWd3hymZxl2uu1o3PIrbpxfeDFDQ==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.1.1.tgz", + "integrity": "sha512-0mMPiBBlQ5LFHTtjxuvt/6yzh8v7OxLi3CbeEsxXZpUzcKO/GC7UA1VOWUoBeQzQL508J12HTAlR3IBU9OofSw==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.1.1.tgz", + "integrity": "sha512-d07bsrMLdDIryDtY17DgqYUbjkswZQr8cLWl4tzXrt5OR/T/zxC1SYKajzB3fd87zTu5W5klV5GmUwcNSMXQXA==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.1.1.tgz", + "integrity": "sha512-iJ4hCaMmDaUqRv131XJdt/C/jJQx8UreDWTRqZKtNydvZVh/o4yXGRRFOplea1D9b/zpwL1Y+ZDwX7xMhIOTmg==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/logger": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-common": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.1.1.tgz", + "integrity": "sha512-jG4ys/hWYf69iaN/xOmF+3kjs4Nnz1Ay3CjFLDtYa8KdxbmUhArA9HmP26ru5N0wbVWhY+6kmpYhTJpez5wTyg==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/plugin-content-blog": "3.1.1", + "@docusaurus/plugin-content-docs": "3.1.1", + "@docusaurus/plugin-content-pages": "3.1.1", + "@docusaurus/plugin-debug": "3.1.1", + "@docusaurus/plugin-google-analytics": "3.1.1", + "@docusaurus/plugin-google-gtag": "3.1.1", + "@docusaurus/plugin-google-tag-manager": "3.1.1", + "@docusaurus/plugin-sitemap": "3.1.1", + "@docusaurus/theme-classic": "3.1.1", + "@docusaurus/theme-common": "3.1.1", + "@docusaurus/theme-search-algolia": "3.1.1", + "@docusaurus/types": "3.1.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/react-loadable": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", + "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "dependencies": { + "@types/react": "*", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.1.1.tgz", + "integrity": "sha512-GiPE/jbWM8Qv1A14lk6s9fhc0LhPEQ00eIczRO4QL2nAQJZXkjPG6zaVx+1cZxPFWbAsqSjKe2lqkwF3fGkQ7Q==", + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/mdx-loader": "3.1.1", + "@docusaurus/module-type-aliases": "3.1.1", + "@docusaurus/plugin-content-blog": "3.1.1", + "@docusaurus/plugin-content-docs": "3.1.1", + "@docusaurus/plugin-content-pages": "3.1.1", + "@docusaurus/theme-common": "3.1.1", + "@docusaurus/theme-translations": "3.1.1", + "@docusaurus/types": "3.1.1", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-common": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.43", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.4.26", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.1.1.tgz", + "integrity": "sha512-38urZfeMhN70YaXkwIGXmcUcv2CEYK/2l4b05GkJPrbEbgpsIZM3Xc+Js2ehBGGZmfZq8GjjQ5RNQYG+MYzCYg==", + "dependencies": { + "@docusaurus/mdx-loader": "3.1.1", + "@docusaurus/module-type-aliases": "3.1.1", + "@docusaurus/plugin-content-blog": "3.1.1", + "@docusaurus/plugin-content-docs": "3.1.1", + "@docusaurus/plugin-content-pages": "3.1.1", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-common": "3.1.1", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.1.1.tgz", + "integrity": "sha512-tBH9VY5EpRctVdaAhT+b1BY8y5dyHVZGFXyCHgTrvcXQy5CV4q7serEX7U3SveNT9zksmchPyct6i1sFDC4Z5g==", + "dependencies": { + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "3.1.1", + "@docusaurus/logger": "3.1.1", + "@docusaurus/plugin-content-docs": "3.1.1", + "@docusaurus/theme-common": "3.1.1", + "@docusaurus/theme-translations": "3.1.1", + "@docusaurus/utils": "3.1.1", + "@docusaurus/utils-validation": "3.1.1", + "algoliasearch": "^4.18.0", + "algoliasearch-helper": "^3.13.3", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.1.1.tgz", + "integrity": "sha512-xvWQFwjxHphpJq5fgk37FXCDdAa2o+r7FX8IpMg+bGZBNXyWBu3MjZ+G4+eUVNpDhVinTc+j6ucL0Ain5KCGrg==", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/types": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz", + "integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "^1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.1.1.tgz", + "integrity": "sha512-ZJfJa5cJQtRYtqijsPEnAZoduW6sjAQ7ZCWSZavLcV10Fw0Z3gSaPKA/B4micvj2afRZ4gZxT7KfYqe5H8Cetg==", + "dependencies": { + "@docusaurus/logger": "3.1.1", + "@svgr/webpack": "^6.5.1", + "escape-string-regexp": "^4.0.0", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "resolve-pathname": "^3.0.0", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/types": { + "optional": true + } + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.1.1.tgz", + "integrity": "sha512-eGne3olsIoNfPug5ixjepZAIxeYFzHHnor55Wb2P57jNbtVaFvij/T+MS8U0dtZRFi50QU+UPmRrXdVUM8uyMg==", + "dependencies": { + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/types": { + "optional": true + } + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.1.1.tgz", + "integrity": "sha512-KlY4P9YVDnwL+nExvlIpu79abfEv6ZCHuOX4ZQ+gtip+Wxj0daccdReIWWtqxM/Fb5Cz1nQvUCc7VEtT8IBUAA==", + "dependencies": { + "@docusaurus/logger": "3.1.1", + "@docusaurus/utils": "3.1.1", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", + "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-to-js": "^2.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", + "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", + "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.24", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", + "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@slorber/static-site-generator-webpack-plugin": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz", + "integrity": "sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA==", + "dependencies": { + "eval": "^0.1.8", + "p-map": "^4.0.0", + "webpack-sources": "^3.2.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", + "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", + "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", + "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", + "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", + "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", + "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", + "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", + "@svgr/babel-plugin-remove-jsx-attribute": "*", + "@svgr/babel-plugin-remove-jsx-empty-expression": "*", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.5.1", + "@svgr/babel-plugin-svg-dynamic-title": "^6.5.1", + "@svgr/babel-plugin-svg-em-dimensions": "^6.5.1", + "@svgr/babel-plugin-transform-react-native-svg": "^6.5.1", + "@svgr/babel-plugin-transform-svg-component": "^6.5.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", + "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", + "dependencies": { + "@babel/core": "^7.19.6", + "@svgr/babel-preset": "^6.5.1", + "@svgr/plugin-jsx": "^6.5.1", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", + "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", + "dependencies": { + "@babel/types": "^7.20.0", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", + "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", + "dependencies": { + "@babel/core": "^7.19.6", + "@svgr/babel-preset": "^6.5.1", + "@svgr/hast-util-to-babel-ast": "^6.5.1", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "^6.0.0" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", + "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", + "dependencies": { + "cosmiconfig": "^7.0.1", + "deepmerge": "^4.2.2", + "svgo": "^2.8.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", + "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", + "dependencies": { + "@babel/core": "^7.19.6", + "@babel/plugin-transform-react-constant-elements": "^7.18.12", + "@babel/preset-env": "^7.19.4", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@svgr/core": "^6.5.1", + "@svgr/plugin-jsx": "^6.5.1", + "@svgr/plugin-svgo": "^6.5.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", + "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.4.tgz", + "integrity": "sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/mdast": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", + "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.11.tgz", + "integrity": "sha512-HM5bwOaIQJIQbAYfax35HCKxx7a3KrK3nBtIqJgSOitivTD1y3oW9P3rxY9RkXYPUk7y/AjAohfHKmFpGE79zw==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "20.11.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", + "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prismjs": { + "version": "1.26.3", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", + "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/qs": { + "version": "6.9.11", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/react": { + "version": "18.2.57", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.57.tgz", + "integrity": "sha512-ZvQsktJgSYrQiMirAN60y4O/LRevIV8hUzSOSNB6gfR3/o3wCBFQx3sPwIYtuDMeiVgsSS3UzCV26tEzgnfvQw==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.22.1.tgz", + "integrity": "sha512-jwydKFQJKIx9kIZ8Jm44SdpigFwRGPESaxZBaHSV0XWN2yBJAOT4mT7ppvlrpA4UGzz92pqFnVKr/kaZXrcreg==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.22.1", + "@algolia/cache-common": "4.22.1", + "@algolia/cache-in-memory": "4.22.1", + "@algolia/client-account": "4.22.1", + "@algolia/client-analytics": "4.22.1", + "@algolia/client-common": "4.22.1", + "@algolia/client-personalization": "4.22.1", + "@algolia/client-search": "4.22.1", + "@algolia/logger-common": "4.22.1", + "@algolia/logger-console": "4.22.1", + "@algolia/requester-browser-xhr": "4.22.1", + "@algolia/requester-common": "4.22.1", + "@algolia/requester-node-http": "4.22.1", + "@algolia/transporter": "4.22.1" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.16.2", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.16.2.tgz", + "integrity": "sha512-Yl/Gu5Cq4Z5s/AJ0jR37OPI1H3+z7PHz657ibyaXgMOaWvPlZ3OACN13N+7HCLPUlB0BN+8BtmrG/CqTilowBA==", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.17", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", + "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.22.2", + "caniuse-lite": "^1.0.30001578", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", + "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.5.0", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", + "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0", + "core-js-compat": "^3.34.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", + "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "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" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001589", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz", + "integrity": "sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "node_modules/combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compressible/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/copy-text-to-clipboard": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", + "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "dependencies": { + "browserslist": "^4.22.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.0.tgz", + "integrity": "sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-loader": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", + "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.4", + "postcss-modules-scope": "^3.1.1", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz", + "integrity": "sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA==", + "dependencies": { + "cssnano": "^5.1.8", + "jest-worker": "^29.1.2", + "postcss": "^8.4.17", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "dependencies": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.10.tgz", + "integrity": "sha512-fnYJyCS9jgMU+cmHO1rPSPf9axbQyD7iUhLO5Df6O4G+fKIOMps+ZbU0PdGFejFBBZ3Pftf18fn1eG7MAPUSWQ==", + "dependencies": { + "autoprefixer": "^10.4.12", + "cssnano-preset-default": "^5.2.14", + "postcss-discard-unused": "^5.1.0", + "postcss-merge-idents": "^5.1.1", + "postcss-reduce-idents": "^5.2.0", + "postcss-zindex": "^5.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/detect-port": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", + "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + } + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.679", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.679.tgz", + "integrity": "sha512-NhQMsz5k0d6m9z3qAxnsOR/ebal4NAGsrNVRwcDo4Kc/zQ7KdsTKZUxZoygHcVRb0QDW3waEDIcE3isZ79RP6g==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", + "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", + "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", + "dependencies": { + "@types/estree": "^1.0.0", + "is-plain-obj": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/express/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "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" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "dependencies": { + "punycode": "^1.3.2" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "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" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.2.tgz", + "integrity": "sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", + "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", + "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==" + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", + "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", + "dependencies": { + "inline-style-parser": "0.2.2" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "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" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.43", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.43.tgz", + "integrity": "sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.12.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz", + "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", + "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", + "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.0.tgz", + "integrity": "sha512-A8AJHlR7/wPQ3+Jre1+1rq040fX9A4Q1jG8JxmSNp/PLPHg80A6475wxTp3KzHpApFH6yWxFotHrJQA3dXP6/w==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz", + "integrity": "sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", + "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", + "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", + "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", + "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", + "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", + "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz", + "integrity": "sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "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" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-unused": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz", + "integrity": "sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-loader/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss-merge-idents": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz", + "integrity": "sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw==", + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", + "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", + "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz", + "integrity": "sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", + "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", + "dependencies": { + "sort-css-media-queries": "2.1.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.16" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/postcss-zindex": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-5.1.0.tgz", + "integrity": "sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", + "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", + "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/pupa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", + "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-helmet-async": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-json-view-lite": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.2.1.tgz", + "integrity": "sha512-Itc0g86fytOmKZoIoJyGgvNqohWSbh3NXIKNgH6W6FT9PC1ck4xas1tT3Rr/b3UlFXyA9Jjaw9QSXdZy2JwGMQ==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", + "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "dependencies": { + "@types/react": "*", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", + "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reading-time": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", + "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", + "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", + "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rtl-detect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", + "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" + }, + "node_modules/rtlcss": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", + "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/search-insights": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.13.0.tgz", + "integrity": "sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==", + "peer": true + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/send/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", + "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "fast-url-parser": "1.1.3", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "2.2.1", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", + "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/sitemap": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", + "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz", + "integrity": "sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==", + "engines": { + "node": ">= 6.3.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "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" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "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" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", + "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/svgo/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/svgo/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/svgo/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.2.tgz", + "integrity": "sha512-sHXmLSkImesJ4p5apTeT63DsV4Obe1s37qT8qvwHRmVxKTBH7Rv9Wr26VcAMmLbmk9UliiwK8z+657NyJHHy/w==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/url-loader/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", + "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpack": { + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", + "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "is-plain-object": "^5.0.0", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpackbar": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", + "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.3", + "pretty-time": "^1.1.0", + "std-env": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000..aad0f56f --- /dev/null +++ b/docs/package.json @@ -0,0 +1,44 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids" + }, + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/preset-classic": "3.1.1", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.1", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.1.1", + "@docusaurus/types": "3.1.1" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=18.0" + } +} diff --git a/docs/sidebars.js b/docs/sidebars.js new file mode 100644 index 00000000..a5ffdcb0 --- /dev/null +++ b/docs/sidebars.js @@ -0,0 +1,20 @@ +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + */ + +// @ts-check + +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const sidebars = { + // By default, Docusaurus generates a sidebar from the docs folder structure + sidebar: [{ type: "autogenerated", dirName: "." }], +}; + +export default sidebars; diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css new file mode 100644 index 00000000..2bc6a4cf --- /dev/null +++ b/docs/src/css/custom.css @@ -0,0 +1,30 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #2e8555; + --ifm-color-primary-dark: #29784c; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205d3b; + --ifm-color-primary-light: #33925d; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-lightest: #3cad6e; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} diff --git a/docs/static/.nojekyll b/docs/static/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/docs/static/img/favicon.ico b/docs/static/img/favicon.ico new file mode 100644 index 00000000..b49a0cd5 --- /dev/null +++ b/docs/static/img/favicon.ico @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/logo.svg b/docs/static/img/logo.svg new file mode 100644 index 00000000..b49a0cd5 --- /dev/null +++ b/docs/static/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file From 27341f80098abc80923526d6489c093b995f9fab Mon Sep 17 00:00:00 2001 From: tylerslaton Date: Fri, 23 Feb 2024 12:37:51 -0500 Subject: [PATCH 113/774] fix: address issue with override param Signed-off-by: tylerslaton --- pkg/builtin/builtin.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 77fcebf8..cab5c082 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -381,7 +381,7 @@ func SysDownload(ctx context.Context, env []string, input string) (_ string, err var params struct { URL string `json:"url,omitempty"` Location string `json:"location,omitempty"` - Override bool `json:"override,omitempty"` + Override string `json:"override,omitempty"` } if err := json.Unmarshal([]byte(input), ¶ms); err != nil { return "", err @@ -405,7 +405,7 @@ func SysDownload(ctx context.Context, env []string, input string) (_ string, err params.Location = f.Name() } - if checkExists && !params.Override { + if checkExists && params.Override != "true" { if _, err := os.Stat(params.Location); err == nil { return "", fmt.Errorf("file %s already exists and can not be overwritten", params.Location) } else if err != nil && !errors.Is(err, fs.ErrNotExist) { From 632639d237fd0198a422afc6fd420b326a0f4547 Mon Sep 17 00:00:00 2001 From: Taylor Price Date: Fri, 23 Feb 2024 12:34:12 -0700 Subject: [PATCH 114/774] fix: provide PAT instead of workflow generated token Signed-off-by: Taylor Price --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 532cdb2b..eec0ef83 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -42,7 +42,7 @@ jobs: run: | $latestRelease = Invoke-RestMethod -Uri https://api.github.com/repos/gptscript-ai/gptscript/releases/latest $url = $latestRelease.assets | Where-Object { $_.name -eq ("gptscript-" + $latestRelease.tag_name + "-windows-amd64.zip") } | Select-Object -ExpandProperty browser_download_url - ./wingetcreate.exe update --submit --token "${{ secrets.GITHUB_TOKEN }}" --urls $url --version "${{ github.event.release.tag_name }}" gptscript-ai.gptscript + ./wingetcreate.exe update --submit --token "${{ secrets.WINGET_GH_TOKEN }}" --urls $url --version "${{ github.event.release.tag_name }}" gptscript-ai.gptscript env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From d41990a610fdbea56b241e7a1c8b12df83c48e5e Mon Sep 17 00:00:00 2001 From: Taylor Price Date: Fri, 23 Feb 2024 13:23:29 -0700 Subject: [PATCH 115/774] fix: action is kicked off by tag push, not release Signed-off-by: Taylor Price --- .github/workflows/release.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index eec0ef83..ffbd882f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -40,9 +40,6 @@ jobs: Invoke-WebRequest -Uri 'https://aka.ms/wingetcreate/latest' -OutFile 'wingetcreate.exe' - name: Create WinGet Package Update Pull Request run: | - $latestRelease = Invoke-RestMethod -Uri https://api.github.com/repos/gptscript-ai/gptscript/releases/latest - $url = $latestRelease.assets | Where-Object { $_.name -eq ("gptscript-" + $latestRelease.tag_name + "-windows-amd64.zip") } | Select-Object -ExpandProperty browser_download_url - ./wingetcreate.exe update --submit --token "${{ secrets.WINGET_GH_TOKEN }}" --urls $url --version "${{ github.event.release.tag_name }}" gptscript-ai.gptscript - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - + $latestRelease = Invoke-RestMethod -Uri https://api.github.com/repos/gptscript-ai/gptscript/releases/latest + $url = $latestRelease.assets | Where-Object { $_.name -eq ("gptscript-" + $latestRelease.tag_name + "-windows-amd64.zip") } | Select-Object -ExpandProperty browser_download_url + ./wingetcreate.exe update --submit --token "${{ secrets.WINGET_GH_TOKEN }}" --urls $url --version "$latestRelease.tag_name" gptscript-ai.gptscript From 24746bc9d14cc45a6294fe3add94dc1f399b34c4 Mon Sep 17 00:00:00 2001 From: Taylor Price Date: Fri, 23 Feb 2024 13:33:59 -0700 Subject: [PATCH 116/774] fix: get proper tag name for current action Signed-off-by: Taylor Price --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ffbd882f..2e7cba5c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -42,4 +42,4 @@ jobs: run: | $latestRelease = Invoke-RestMethod -Uri https://api.github.com/repos/gptscript-ai/gptscript/releases/latest $url = $latestRelease.assets | Where-Object { $_.name -eq ("gptscript-" + $latestRelease.tag_name + "-windows-amd64.zip") } | Select-Object -ExpandProperty browser_download_url - ./wingetcreate.exe update --submit --token "${{ secrets.WINGET_GH_TOKEN }}" --urls $url --version "$latestRelease.tag_name" gptscript-ai.gptscript + ./wingetcreate.exe update --submit --token "${{ secrets.WINGET_GH_TOKEN }}" --urls $url --version "${{ github.ref_name }}" gptscript-ai.gptscript From 118ea596d2d78870026e0dc1d38cbc53e0da9e44 Mon Sep 17 00:00:00 2001 From: Taylor Price Date: Fri, 23 Feb 2024 13:59:25 -0700 Subject: [PATCH 117/774] fix: get proper urls for current tag, regardless if it is "latest" Signed-off-by: Taylor Price --- .github/workflows/release.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 2e7cba5c..1d727b60 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -40,6 +40,5 @@ jobs: Invoke-WebRequest -Uri 'https://aka.ms/wingetcreate/latest' -OutFile 'wingetcreate.exe' - name: Create WinGet Package Update Pull Request run: | - $latestRelease = Invoke-RestMethod -Uri https://api.github.com/repos/gptscript-ai/gptscript/releases/latest - $url = $latestRelease.assets | Where-Object { $_.name -eq ("gptscript-" + $latestRelease.tag_name + "-windows-amd64.zip") } | Select-Object -ExpandProperty browser_download_url + $url = "${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/gptscript-${{ github.ref_name }}-windows-amd64.zip" ./wingetcreate.exe update --submit --token "${{ secrets.WINGET_GH_TOKEN }}" --urls $url --version "${{ github.ref_name }}" gptscript-ai.gptscript From 5a91c64055c24856dad11c7b884af88fd1e07b01 Mon Sep 17 00:00:00 2001 From: Bill Maxwell Date: Fri, 23 Feb 2024 13:24:46 -0700 Subject: [PATCH 118/774] enhance - add sys.file.stat built in tool created a built in tool that stats a file and returns the size, mode and mod time. Signed-off-by: Bill Maxwell --- docs/docs/tools/system.md | 42 +++++++++++++++++++++++++++++++++++++++ pkg/builtin/builtin.go | 25 +++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/docs/docs/tools/system.md b/docs/docs/tools/system.md index 9b22e10f..bc76318c 100644 --- a/docs/docs/tools/system.md +++ b/docs/docs/tools/system.md @@ -1,64 +1,106 @@ # System Tools + GPTScript comes with a set of system tools that provide various core functionalities. ## sys.abort + Aborts the operation and provides an error message. + #### Arguments + - `message`: The description of the error or unexpected result that caused abort to be called. ## sys.download + Downloads a file from a specified URL to an optional location on disk with an option to override existing files. + #### Arguments + - `location` (optional): The on-disk location to store the downloaded file. - `override`: If true, allows overwriting of an existing file. Default is false. - `url`: The HTTP or HTTPS URL of the file to be downloaded. ## sys.exec + Executes a command with the ability to specify command arguments and the working directory. + #### Arguments + - `command`: The full command to run, including all arguments. - `directory`: The working directory for the command. Defaults to the current directory ".". ## sys.find + Searches for files within a directory that match a given pattern using Unix glob format. + #### Arguments + - `directory`: The directory to perform the search in. Defaults to the current directory ".". - `pattern`: The pattern to match against filenames. ## sys.getenv + Retrieves the value of an environment variable. + #### Arguments + - `name`: The name of the environment variable to retrieve. ## sys.http.get + Performs an HTTP GET request to the specified URL. + #### Arguments + - `url`: The URL to perform the GET request. ## sys.http.html2text + Converts the HTML content from a given URL to plain text. + #### Arguments + - `url`: The URL of the HTML content to be converted. ## sys.http.post + Sends an HTTP POST request with given content to a specified URL. + #### Arguments + - `content`: The content to be posted. - `contentType`: The MIME type of the content being posted. - `url`: The URL to which the POST request should be sent. ## sys.read + Reads the content from a specified file. + #### Arguments + - `filename`: The name of the file from which to read content. ## sys.remove + Removes a file from the specified location. + #### Arguments + - `location`: The path to the file that needs to be removed. +## sys.stat + +Retrieves the status of a file, such as size, permissions, and last modified time. + +#### Arguments + +- `filepath`: The path to the file for which to retrieve status. + ## sys.write + Writes content to a specified file. + #### Arguments + - `content`: The content to be written to the file. - `filename`: The filename where the content should be written. diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index cab5c082..09df28df 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -118,6 +118,15 @@ var tools = map[string]types.Tool{ }, BuiltinFunc: SysRemove, }, + "sys.stat": { + Parameters: types.Parameters{ + Description: "Gets size, modfied time, and mode of the specified file", + Arguments: types.ObjectSchema( + "filepath", "The complete path and filename of the file", + ), + }, + BuiltinFunc: SysStat, + }, } func SysProgram() *types.Program { @@ -377,6 +386,22 @@ func SysRemove(ctx context.Context, env []string, input string) (string, error) return fmt.Sprintf("Removed file: %s", params.Location), os.Remove(params.Location) } +func SysStat(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Filepath string `json:"filepath,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + stat, err := os.Stat(params.Filepath) + if err != nil { + return "", err + } + + return fmt.Sprintf("File %s mode: %s, size: %d bytes, modtime: %s", params.Filepath, stat.Mode().String(), stat.Size(), stat.ModTime().String()), nil +} + func SysDownload(ctx context.Context, env []string, input string) (_ string, err error) { var params struct { URL string `json:"url,omitempty"` From a2daea4d7c2160c7fca09d545043b0519879a1c6 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Wed, 21 Feb 2024 02:50:07 -0500 Subject: [PATCH 119/774] feat: add sys.append built-in Add a new built-in tool called `sys.append` that appends content to a file instead of truncating it. Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- pkg/builtin/builtin.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index cab5c082..be14bf73 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -37,6 +37,15 @@ var tools = map[string]types.Tool{ }, BuiltinFunc: SysWrite, }, + "sys.append": { + Parameters: types.Parameters{ + Description: "Appends the contents to a file", + Arguments: types.ObjectSchema( + "filename", "The name of the file to append to", + "content", "The content to append"), + }, + BuiltinFunc: SysAppend, + }, "sys.http.get": { Parameters: types.Parameters{ Description: "Download the contents of a http or https URL", @@ -258,6 +267,33 @@ func SysWrite(ctx context.Context, env []string, input string) (string, error) { return "", os.WriteFile(params.Filename, data, 0644) } +func SysAppend(ctx context.Context, env []string, input string) (string, error) { + var params struct { + Filename string `json:"filename,omitempty"` + Content string `json:"content,omitempty"` + } + if err := json.Unmarshal([]byte(input), ¶ms); err != nil { + return "", err + } + + f, err := os.OpenFile(params.Filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + if err != nil { + return "", err + } + + // Attempt to append to the file and close it immediately. + // Write is guaranteed to return an error when n != len([]byte(params.Content)) + n, err := f.Write([]byte(params.Content)) + if err := errors.Join(err, f.Close()); err != nil { + return "", err + } + + msg := fmt.Sprintf("Appended %d bytes to file %s", n, params.Filename) + log.Debugf(msg) + + return "", err +} + func fixQueries(u string) (string, error) { url, err := url.Parse(u) if err != nil { From 90e52e4c24982221166eb605cc732d304eb8fa90 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Wed, 21 Feb 2024 03:02:35 -0500 Subject: [PATCH 120/774] enhance: synchronize file manipulation for built-ins Use named locks to prevent concurrent writes to files manipulated by built-in tools. Locks are named after the file they protect. Lock acquisition has no guaranteed order. A more complex solution should be considered if a guaranteed order is desired; e.g. FIFO. Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- go.mod | 1 + go.sum | 2 ++ pkg/builtin/builtin.go | 17 +++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/go.mod b/go.mod index 49acb47b..e71473ac 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.0 replace github.com/sashabaranov/go-openai => github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a require ( + github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb github.com/adrg/xdg v0.4.0 diff --git a/go.sum b/go.sum index f8d6702e..f55d6b1e 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 h1:+tu3HOoMXB7RXEINRVIpxJCT+KdYiI7LAEAUrOw3dIU= +github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69/go.mod h1:L1AbZdiDllfyYH5l5OkAaZtk7VkWe89bPJFmnDBNHxg= github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd h1:Zbau2J6sEPl1H4gqnEx4/TI55eZncQR5cjfPOcG2lxE= github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd/go.mod h1:13nTO3svO8zTD3j9E5c86tCtK5YrKsK5sxca4Lwkbc0= github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d h1:hfpNQkJ4I2b8+DbMr8m97gG67ku0uPsMzUfskVu3cHU= diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index be14bf73..8d6882bd 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -15,6 +15,7 @@ import ( "sort" "strings" + "github.com/BurntSushi/locker" "github.com/gptscript-ai/gptscript/pkg/types" "github.com/jaytaylor/html2text" ) @@ -242,6 +243,10 @@ func SysRead(ctx context.Context, env []string, input string) (string, error) { return "", err } + // Lock the file to prevent concurrent writes from other tool calls. + locker.RLock(params.Filename) + defer locker.RUnlock(params.Filename) + log.Debugf("Reading file %s", params.Filename) data, err := os.ReadFile(params.Filename) if err != nil { @@ -260,6 +265,10 @@ func SysWrite(ctx context.Context, env []string, input string) (string, error) { return "", err } + // Lock the file to prevent concurrent writes from other tool calls. + locker.Lock(params.Filename) + defer locker.Unlock(params.Filename) + data := []byte(params.Content) msg := fmt.Sprintf("Wrote %d bytes to file %s", len(data), params.Filename) log.Debugf(msg) @@ -276,6 +285,10 @@ func SysAppend(ctx context.Context, env []string, input string) (string, error) return "", err } + // Lock the file to prevent concurrent writes from other tool calls. + locker.Lock(params.Filename) + defer locker.Unlock(params.Filename) + f, err := os.OpenFile(params.Filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return "", err @@ -410,6 +423,10 @@ func SysRemove(ctx context.Context, env []string, input string) (string, error) return "", err } + // Lock the file to prevent concurrent writes from other tool calls. + locker.Lock(params.Location) + defer locker.Unlock(params.Location) + return fmt.Sprintf("Removed file: %s", params.Location), os.Remove(params.Location) } From d4981fac8fbc705261f5cf9944db7a525421aec8 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:04:22 -0500 Subject: [PATCH 121/774] style: remove unnecessary log formatting calls Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- pkg/builtin/builtin.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 8d6882bd..c21ac4a3 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -270,8 +270,7 @@ func SysWrite(ctx context.Context, env []string, input string) (string, error) { defer locker.Unlock(params.Filename) data := []byte(params.Content) - msg := fmt.Sprintf("Wrote %d bytes to file %s", len(data), params.Filename) - log.Debugf(msg) + log.Debugf("Wrote %d bytes to file %s", len(data), params.Filename) return "", os.WriteFile(params.Filename, data, 0644) } @@ -301,10 +300,9 @@ func SysAppend(ctx context.Context, env []string, input string) (string, error) return "", err } - msg := fmt.Sprintf("Appended %d bytes to file %s", n, params.Filename) - log.Debugf(msg) + log.Debugf("Appended %d bytes to file %s", n, params.Filename) - return "", err + return "", nil } func fixQueries(u string) (string, error) { From 7e00a8e42352ccfc397b42528b79b28a970ec123 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 24 Feb 2024 00:44:09 -0700 Subject: [PATCH 122/774] Drop unneeded code as vision is being moved to a tool --- Makefile | 2 + pkg/builtin/defaults.go | 9 +--- pkg/engine/engine.go | 1 - pkg/openai/client.go | 60 +++++++------------------ pkg/parser/parser.go | 5 --- pkg/types/completion.go | 28 ------------ pkg/types/tool.go | 4 -- pkg/vision/image.go | 99 ----------------------------------------- pkg/vision/schema.go | 39 ---------------- 9 files changed, 19 insertions(+), 228 deletions(-) delete mode 100644 pkg/vision/image.go delete mode 100644 pkg/vision/schema.go diff --git a/Makefile b/Makefile index 7a129674..b2686912 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +.DEFAULT_GOAL := build + all: build-ui build build-ui: diff --git a/pkg/builtin/defaults.go b/pkg/builtin/defaults.go index 04410075..6b31ca90 100644 --- a/pkg/builtin/defaults.go +++ b/pkg/builtin/defaults.go @@ -6,17 +6,12 @@ import ( ) var ( - DefaultModel = openai.DefaultModel - DefaultVisionModel = openai.DefaultVisionModel + DefaultModel = openai.DefaultModel ) func SetDefaults(tool types.Tool) types.Tool { if tool.Parameters.ModelName == "" { - if tool.Parameters.Vision { - tool.Parameters.ModelName = DefaultVisionModel - } else { - tool.Parameters.ModelName = DefaultModel - } + tool.Parameters.ModelName = DefaultModel } return tool } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 512a9c47..3a5a37d9 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -173,7 +173,6 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { completion := types.CompletionRequest{ Model: tool.Parameters.ModelName, - Vision: tool.Parameters.Vision, MaxToken: tool.Parameters.MaxTokens, JSONResponse: tool.Parameters.JSONResponse, Cache: tool.Parameters.Cache, diff --git a/pkg/openai/client.go b/pkg/openai/client.go index a8b08076..00d528e7 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -16,12 +16,10 @@ import ( "github.com/gptscript-ai/gptscript/pkg/cache" "github.com/gptscript-ai/gptscript/pkg/hash" "github.com/gptscript-ai/gptscript/pkg/types" - "github.com/gptscript-ai/gptscript/pkg/vision" "github.com/sashabaranov/go-openai" ) const ( - DefaultVisionModel = openai.GPT4VisionPreview DefaultModel = openai.GPT4TurboPreview DefaultPromptParameter = "defaultPromptParameter" ) @@ -171,15 +169,8 @@ func toToolCall(call types.CompletionToolCall) openai.ToolCall { } } -func toMessages(cache *cache.Client, request types.CompletionRequest) (result []openai.ChatCompletionMessage, err error) { +func toMessages(request types.CompletionRequest) (result []openai.ChatCompletionMessage, err error) { for _, message := range request.Messages { - if request.Vision { - message, err = vision.ToVisionMessage(cache, message) - if err != nil { - return nil, err - } - } - chatMessage := openai.ChatCompletionMessage{ Role: string(message.Role), } @@ -192,25 +183,6 @@ func toMessages(cache *cache.Client, request types.CompletionRequest) (result [] if content.ToolCall != nil { chatMessage.ToolCalls = append(chatMessage.ToolCalls, toToolCall(*content.ToolCall)) } - if content.Image != nil { - url, err := vision.ImageToURL(cache, request.Vision, *content.Image) - if err != nil { - return nil, err - } - if request.Vision { - chatMessage.MultiContent = append(chatMessage.MultiContent, openai.ChatMessagePart{ - Type: openai.ChatMessagePartTypeImageURL, - ImageURL: &openai.ChatMessageImageURL{ - URL: url, - }, - }) - } else { - chatMessage.MultiContent = append(chatMessage.MultiContent, openai.ChatMessagePart{ - Type: openai.ChatMessagePartTypeText, - Text: fmt.Sprintf("Image URL %s", url), - }) - } - } if content.Text != "" { chatMessage.MultiContent = append(chatMessage.MultiContent, openai.ChatMessagePart{ Type: openai.ChatMessagePartTypeText, @@ -251,7 +223,7 @@ type Status struct { } func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- Status) (*types.CompletionMessage, error) { - msgs, err := toMessages(c.cache, messageRequest) + msgs, err := toMessages(messageRequest) if err != nil { return nil, err } @@ -277,21 +249,19 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } } - if !messageRequest.Vision { - for _, tool := range messageRequest.Tools { - params := tool.Function.Parameters - if params != nil && params.Type == "object" && params.Properties == nil { - params.Properties = map[string]types.Property{} - } - request.Tools = append(request.Tools, openai.Tool{ - Type: openai.ToolType(tool.Type), - Function: openai.FunctionDefinition{ - Name: tool.Function.Name, - Description: tool.Function.Description, - Parameters: params, - }, - }) + for _, tool := range messageRequest.Tools { + params := tool.Function.Parameters + if params != nil && params.Type == "object" && params.Properties == nil { + params.Properties = map[string]types.Property{} } + request.Tools = append(request.Tools, openai.Tool{ + Type: openai.ToolType(tool.Type), + Function: openai.FunctionDefinition{ + Name: tool.Function.Name, + Description: tool.Function.Description, + Parameters: params, + }, + }) } id := fmt.Sprint(atomic.AddInt64(&completionID, 1)) @@ -368,7 +338,7 @@ func appendMessage(msg types.CompletionMessage, response openai.ChatCompletionSt if delta.Content != "" { found := false for i, content := range msg.Content { - if content.ToolCall != nil || content.Image != nil { + if content.ToolCall != nil { continue } msg.Content[i] = types.ContentPart{ diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 15c84bb5..a8274204 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -98,11 +98,6 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { if err := addArg(value, tool); err != nil { return false, err } - case "vision": - tool.Parameters.Vision, err = toBool(value) - if err != nil { - return false, err - } case "maxtoken": fallthrough case "maxtokens": diff --git a/pkg/types/completion.go b/pkg/types/completion.go index 26375ca4..90f6db08 100644 --- a/pkg/types/completion.go +++ b/pkg/types/completion.go @@ -13,7 +13,6 @@ type CompletionToolType string type CompletionRequest struct { Model string - Vision bool Tools []CompletionTool Messages []CompletionMessage MaxToken int @@ -77,17 +76,6 @@ func (in CompletionMessage) String() string { if content.ToolCall != nil { buf.WriteString(fmt.Sprintf("tool call %s -> %s", content.ToolCall.Function.Name, content.ToolCall.Function.Arguments)) } - if content.Image != nil { - buf.WriteString("image: ") - if content.Image.URL != "" { - buf.WriteString(content.Image.URL) - } - if len(content.Image.Base64) > 50 { - buf.WriteString(content.Image.Base64[:50] + "...") - } else { - buf.WriteString(content.Image.Base64) - } - } } return buf.String() } @@ -95,22 +83,6 @@ func (in CompletionMessage) String() string { type ContentPart struct { Text string `json:"text,omitempty"` ToolCall *CompletionToolCall `json:"toolCall,omitempty"` - Image *ImageURL `json:"image,omitempty"` -} - -type ImageURLDetail string - -const ( - ImageURLDetailHigh ImageURLDetail = "high" - ImageURLDetailLow ImageURLDetail = "low" - ImageURLDetailAuto ImageURLDetail = "auto" -) - -type ImageURL struct { - Base64 string `json:"base64,omitempty"` - ContentType string `json:"contentType,omitempty"` - URL string `json:"url,omitempty"` - Detail ImageURLDetail `json:"detail,omitempty"` } type CompletionToolCall struct { diff --git a/pkg/types/tool.go b/pkg/types/tool.go index c71cff46..c6d76713 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -26,7 +26,6 @@ type BuiltinFunc func(ctx context.Context, env []string, input string) (string, type Parameters struct { Name string `json:"name,omitempty"` Description string `json:"description,omitempty"` - Vision bool `json:"vision,omitempty"` MaxTokens int `json:"maxTokens,omitempty"` ModelName string `json:"modelName,omitempty"` JSONResponse bool `json:"jsonResponse,omitempty"` @@ -59,9 +58,6 @@ func (t Tool) String() string { if len(t.Parameters.Tools) != 0 { _, _ = fmt.Fprintf(buf, "Tools: %s\n", strings.Join(t.Parameters.Tools, ", ")) } - if t.Parameters.Vision { - _, _ = fmt.Fprintln(buf, "Vision: true") - } if t.Parameters.MaxTokens != 0 { _, _ = fmt.Fprintf(buf, "Max Tokens: %d\n", t.Parameters.MaxTokens) } diff --git a/pkg/vision/image.go b/pkg/vision/image.go deleted file mode 100644 index 055178d4..00000000 --- a/pkg/vision/image.go +++ /dev/null @@ -1,99 +0,0 @@ -package vision - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "os" - "strings" - - "github.com/gptscript-ai/gptscript/pkg/cache" - "github.com/gptscript-ai/gptscript/pkg/hash" - "github.com/gptscript-ai/gptscript/pkg/types" -) - -var ( - urlBase = os.Getenv("cached://") -) - -func ToVisionMessage(c *cache.Client, message types.CompletionMessage) (types.CompletionMessage, error) { - if len(message.Content) != 1 || !strings.HasPrefix(message.Content[0].Text, "{") { - return message, nil - } - - var ( - input inputMessage - content = message.Content[0] - ) - if err := json.Unmarshal([]byte(content.Text), &input); err != nil { - return message, nil - } - - content.Text = input.Text - - if input.URL != "" { - b64, ok, err := Base64FromStored(c, input.URL) - if err != nil { - return message, err - } - if b64 == "" || !ok { - content.Image = &types.ImageURL{ - URL: input.URL, - } - } else { - input.Base64 = b64 - } - } - - if input.Base64 != "" && input.ContentType != "" { - content.Image = &types.ImageURL{ - Base64: input.Base64, - ContentType: input.ContentType, - } - } - - message.Content = []types.ContentPart{ - content, - } - - return message, nil -} - -func Base64FromStored(cache *cache.Client, url string) (string, bool, error) { - if !strings.HasPrefix(url, urlBase) { - return "", false, nil - } - parts := strings.Split(url, "/") - if len(parts) < 2 { - return "", false, nil - } - name := parts[len(parts)-1] - - cached, ok, err := cache.Get(name) - if err != nil || !ok { - return "", ok, err - } - - return base64.StdEncoding.EncodeToString(cached), true, nil -} - -func ImageToURL(c *cache.Client, vision bool, message types.ImageURL) (string, error) { - if message.URL != "" { - return message.URL, nil - } - - if vision { - return fmt.Sprintf("data:%s;base64,%s", message.ContentType, message.Base64), nil - } - - data, err := base64.StdEncoding.DecodeString(message.Base64) - if err != nil { - return "", err - } - - id := "i" + hash.Encode(message)[:12] - if err := c.Store(id, data); err != nil { - return "", err - } - return fmt.Sprintf("%s/%s", urlBase, id), nil -} diff --git a/pkg/vision/schema.go b/pkg/vision/schema.go deleted file mode 100644 index 1fb41d9e..00000000 --- a/pkg/vision/schema.go +++ /dev/null @@ -1,39 +0,0 @@ -package vision - -import ( - "github.com/gptscript-ai/gptscript/pkg/types" -) - -var ( - Schema = types.JSONSchema{ - Property: types.Property{ - Type: "object", - }, - Properties: map[string]types.Property{ - "base64": { - Description: "The base64 encoded value of the image if an image URL is not specified", - Type: "string", - }, - "contentType": { - Description: `The content type of the image such as "image/jpeg" or "image/png"`, - Type: "string", - }, - "text": { - Description: "Instructions on how the passed image should be analyzed", - Type: "string", - }, - "url": { - Description: "The URL to the image to be processed. This should be set if base64 is not set", - Type: "string", - }, - }, - Defs: map[string]types.JSONSchema{}, - } -) - -type inputMessage struct { - Text string `json:"text,omitempty"` - Base64 string `json:"base64,omitempty"` - ContentType string `json:"contentType,omitempty"` - URL string `json:"url,omitempty"` -} From 046d340784105f1a7e115ae9da64a4ed31cc6293 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 24 Feb 2024 21:06:02 -0700 Subject: [PATCH 123/774] Refactor client code to make way for additionl AI API backends --- go.mod | 2 +- go.sum | 4 +- pkg/builtin/defaults.go | 12 ++++- pkg/cache/cache.go | 12 +++++ pkg/cli/gptscript.go | 61 ++++++++++++++++++++---- pkg/engine/cmd.go | 7 ++- pkg/engine/engine.go | 75 ++++++++---------------------- pkg/hash/sha256.go | 10 ++++ pkg/llm/registry.go | 54 +++++++++++++++++++++ pkg/openai/client.go | 98 +++++++++++++++++++++------------------ pkg/runner/runner.go | 38 ++++----------- pkg/server/server.go | 65 ++++++++++++-------------- pkg/system/prompt.go | 56 ++++++++++++++++++++++ pkg/test/examples_test.go | 12 ++++- pkg/types/completion.go | 41 +++++++++------- 15 files changed, 341 insertions(+), 206 deletions(-) create mode 100644 pkg/llm/registry.go create mode 100644 pkg/system/prompt.go diff --git a/go.mod b/go.mod index e71473ac..4347ea7b 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/gptscript-ai/gptscript go 1.22.0 -replace github.com/sashabaranov/go-openai => github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a +replace github.com/sashabaranov/go-openai => github.com/gptscript-ai/go-openai v0.0.0-20240227161457-daa30caa3185 require ( github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 diff --git a/go.sum b/go.sum index f55d6b1e..ab8fa286 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a h1:AdBbQ1ODOYK5AwCey4VFEmKeu9gG4PCzuO80pQmgupE= -github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= +github.com/gptscript-ai/go-openai v0.0.0-20240227161457-daa30caa3185 h1:+TfC9DYtWuexdL7x1lIdD1HP61IStb3ZTj/byBdiWs0= +github.com/gptscript-ai/go-openai v0.0.0-20240227161457-daa30caa3185/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/hexops/autogold v0.8.1/go.mod h1:97HLDXyG23akzAoRYJh/2OBs3kd80eHyKPvZw0S5ZBY= github.com/hexops/autogold v1.3.1 h1:YgxF9OHWbEIUjhDbpnLhgVsjUDsiHDTyDfy2lrfdlzo= github.com/hexops/autogold v1.3.1/go.mod h1:sQO+mQUCVfxOKPht+ipDSkJ2SCJ7BNJVHZexsXqWMx4= diff --git a/pkg/builtin/defaults.go b/pkg/builtin/defaults.go index 6b31ca90..ac264ae6 100644 --- a/pkg/builtin/defaults.go +++ b/pkg/builtin/defaults.go @@ -6,12 +6,20 @@ import ( ) var ( - DefaultModel = openai.DefaultModel + defaultModel = openai.DefaultModel ) +func GetDefaultModel() string { + return defaultModel +} + +func SetDefaultModel(model string) { + defaultModel = model +} + func SetDefaults(tool types.Tool) types.Tool { if tool.Parameters.ModelName == "" { - tool.Parameters.ModelName = DefaultModel + tool.Parameters.ModelName = GetDefaultModel() } return tool } diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 3c23673d..ab44fedf 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -1,6 +1,7 @@ package cache import ( + "context" "errors" "io/fs" "os" @@ -35,6 +36,17 @@ func complete(opts ...Options) (result Options) { return } +type noCacheKey struct{} + +func IsNoCache(ctx context.Context) bool { + v, _ := ctx.Value(noCacheKey{}).(bool) + return v +} + +func WithNoCache(ctx context.Context) context.Context { + return context.WithValue(ctx, noCacheKey{}, true) +} + func New(opts ...Options) (*Client, error) { opt := complete(opts...) if err := os.MkdirAll(opt.CacheDir, 0755); err != nil { diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index cdfbbfe7..bee280bd 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -10,8 +10,10 @@ import ( "github.com/acorn-io/cmd" "github.com/gptscript-ai/gptscript/pkg/assemble" "github.com/gptscript-ai/gptscript/pkg/builtin" + "github.com/gptscript-ai/gptscript/pkg/cache" "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/input" + "github.com/gptscript-ai/gptscript/pkg/llm" "github.com/gptscript-ai/gptscript/pkg/loader" "github.com/gptscript-ai/gptscript/pkg/monitor" "github.com/gptscript-ai/gptscript/pkg/mvl" @@ -26,10 +28,13 @@ import ( type ( DisplayOptions monitor.Options + CacheOptions cache.Options + OpenAIOptions openai.Options ) type GPTScript struct { - runner.Options + CacheOptions + OpenAIOptions DisplayOptions Debug bool `usage:"Enable debug logging"` Quiet *bool `usage:"No output logging" short:"q"` @@ -41,6 +46,8 @@ type GPTScript struct { ListTools bool `usage:"List built-in tools and exit"` Server bool `usage:"Start server"` ListenAddress string `usage:"Server listen address" default:"127.0.0.1:9090"` + + _client llm.Client `usage:"-"` } func New() *cobra.Command { @@ -67,6 +74,33 @@ func (r *GPTScript) Customize(cmd *cobra.Command) { } } +func (r *GPTScript) getClient(ctx context.Context) (llm.Client, error) { + if r._client != nil { + return r._client, nil + } + + cacheClient, err := cache.New(cache.Options(r.CacheOptions)) + if err != nil { + return nil, err + } + + oaClient, err := openai.NewClient(openai.Options(r.OpenAIOptions), openai.Options{ + Cache: cacheClient, + }) + if err != nil { + return nil, err + } + + registry := llm.NewRegistry() + + if err := registry.AddClient(ctx, oaClient); err != nil { + return nil, err + } + + r._client = registry + return r._client, nil +} + func (r *GPTScript) listTools() error { var lines []string for _, tool := range builtin.ListTools() { @@ -77,12 +111,12 @@ func (r *GPTScript) listTools() error { } func (r *GPTScript) listModels(ctx context.Context) error { - c, err := openai.NewClient(openai.Options(r.OpenAIOptions)) + c, err := r.getClient(ctx) if err != nil { return err } - models, err := c.ListModules(ctx) + models, err := c.ListModels(ctx) if err != nil { return err } @@ -95,6 +129,10 @@ func (r *GPTScript) listModels(ctx context.Context) error { } func (r *GPTScript) Pre(*cobra.Command, []string) error { + if r.DefaultModel != "" { + builtin.SetDefaultModel(r.DefaultModel) + } + if r.Quiet == nil { if term.IsTerminal(int(os.Stdout.Fd())) { r.Quiet = new(bool) @@ -126,9 +164,11 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { } if r.Server { - s, err := server.New(server.Options{ - CacheOptions: r.CacheOptions, - OpenAIOptions: r.OpenAIOptions, + c, err := r.getClient(cmd.Context()) + if err != nil { + return err + } + s, err := server.New(c, server.Options{ ListenAddress: r.ListenAddress, }) if err != nil { @@ -176,9 +216,12 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error { return assemble.Assemble(prg, out) } - runner, err := runner.New(r.Options, runner.Options{ - CacheOptions: r.CacheOptions, - OpenAIOptions: r.OpenAIOptions, + client, err := r.getClient(cmd.Context()) + if err != nil { + return err + } + + runner, err := runner.New(client, runner.Options{ MonitorFactory: monitor.NewConsole(monitor.Options(r.DisplayOptions), monitor.Options{ DisplayProgress: !*r.Quiet, }), diff --git a/pkg/engine/cmd.go b/pkg/engine/cmd.go index fd89b412..1a06712a 100644 --- a/pkg/engine/cmd.go +++ b/pkg/engine/cmd.go @@ -12,7 +12,6 @@ import ( "sync/atomic" "github.com/google/shlex" - "github.com/gptscript-ai/gptscript/pkg/openai" "github.com/gptscript-ai/gptscript/pkg/types" "github.com/gptscript-ai/gptscript/pkg/version" ) @@ -21,7 +20,7 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) id := fmt.Sprint(atomic.AddInt64(&completionID, 1)) defer func() { - e.Progress <- openai.Status{ + e.Progress <- types.CompletionStatus{ CompletionID: id, Response: map[string]any{ "output": cmdOut, @@ -31,7 +30,7 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) }() if tool.BuiltinFunc != nil { - e.Progress <- openai.Status{ + e.Progress <- types.CompletionStatus{ CompletionID: id, Request: map[string]any{ "command": []string{tool.ID}, @@ -47,7 +46,7 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) } defer stop() - e.Progress <- openai.Status{ + e.Progress <- types.CompletionStatus{ CompletionID: id, Request: map[string]any{ "command": cmd.Args, diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 3a5a37d9..83be656d 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -4,46 +4,16 @@ import ( "context" "encoding/json" "fmt" - "os" "sync" "sync/atomic" - "github.com/gptscript-ai/gptscript/pkg/openai" + "github.com/gptscript-ai/gptscript/pkg/system" "github.com/gptscript-ai/gptscript/pkg/types" "github.com/gptscript-ai/gptscript/pkg/version" ) -// InternalSystemPrompt is added to all threads. Changing this is very dangerous as it has a -// terrible global effect and changes the behavior of all scripts. -var InternalSystemPrompt = ` -You are task oriented system. -You receive input from a user, process the input from the given instructions, and then output the result. -Your objective is to provide consistent and correct results. -You do not need to explain the steps taken, only provide the result to the given instructions. -You are referred to as a tool. -` - -var DefaultToolSchema = types.JSONSchema{ - Property: types.Property{ - Type: "object", - }, - Properties: map[string]types.Property{ - openai.DefaultPromptParameter: { - Description: "Prompt to send to the tool or assistant. This may be instructions or question.", - Type: "string", - }, - }, - Required: []string{openai.DefaultPromptParameter}, -} - var completionID int64 -func init() { - if p := os.Getenv("GPTSCRIPT_INTERNAL_SYSTEM_PROMPT"); p != "" { - InternalSystemPrompt = p - } -} - type ErrToolNotFound struct { ToolName string } @@ -52,10 +22,14 @@ func (e *ErrToolNotFound) Error() string { return fmt.Sprintf("tool not found: %s", e.ToolName) } +type Model interface { + Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- types.CompletionStatus) (*types.CompletionMessage, error) +} + type Engine struct { - Client *openai.Client + Model Model Env []string - Progress chan<- openai.Status + Progress chan<- types.CompletionStatus } type State struct { @@ -172,18 +146,12 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { } completion := types.CompletionRequest{ - Model: tool.Parameters.ModelName, - MaxToken: tool.Parameters.MaxTokens, - JSONResponse: tool.Parameters.JSONResponse, - Cache: tool.Parameters.Cache, - Temperature: tool.Parameters.Temperature, - } - - if InternalSystemPrompt != "" && (tool.Parameters.InternalPrompt == nil || *tool.Parameters.InternalPrompt) { - completion.Messages = append(completion.Messages, types.CompletionMessage{ - Role: types.CompletionMessageRoleTypeSystem, - Content: types.Text(InternalSystemPrompt), - }) + Model: tool.Parameters.ModelName, + MaxTokens: tool.Parameters.MaxTokens, + JSONResponse: tool.Parameters.JSONResponse, + Cache: tool.Parameters.Cache, + Temperature: tool.Parameters.Temperature, + InternalSystemPrompt: tool.Parameters.InternalPrompt, } for _, subToolName := range tool.Parameters.Tools { @@ -193,10 +161,9 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { } args := subTool.Parameters.Arguments if args == nil && !subTool.IsCommand() { - args = &DefaultToolSchema + args = &system.DefaultToolSchema } completion.Tools = append(completion.Tools, types.CompletionTool{ - Type: types.CompletionToolTypeFunction, Function: types.CompletionFunctionDefinition{ Name: subToolName, Description: subTool.Parameters.Description, @@ -207,12 +174,8 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { if tool.Instructions != "" { completion.Messages = append(completion.Messages, types.CompletionMessage{ - Role: types.CompletionMessageRoleTypeSystem, - Content: []types.ContentPart{ - { - Text: tool.Instructions, - }, - }, + Role: types.CompletionMessageRoleTypeSystem, + Content: types.Text(tool.Instructions), }) } @@ -230,7 +193,7 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { func (e *Engine) complete(ctx context.Context, state *State) (*Return, error) { var ( - progress = make(chan openai.Status) + progress = make(chan types.CompletionStatus) ret = Return{ State: state, Calls: map[string]Call{}, @@ -241,6 +204,7 @@ func (e *Engine) complete(ctx context.Context, state *State) (*Return, error) { // ensure we aren't writing to the channel anymore on exit wg.Add(1) defer wg.Wait() + defer close(progress) go func() { defer wg.Done() @@ -251,8 +215,7 @@ func (e *Engine) complete(ctx context.Context, state *State) (*Return, error) { } }() - resp, err := e.Client.Call(ctx, state.Completion, progress) - close(progress) + resp, err := e.Model.Call(ctx, state.Completion, progress) if err != nil { return nil, err } diff --git a/pkg/hash/sha256.go b/pkg/hash/sha256.go index d941b152..be171281 100644 --- a/pkg/hash/sha256.go +++ b/pkg/hash/sha256.go @@ -6,6 +6,16 @@ import ( "encoding/json" ) +func Digest(obj any) string { + data, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + hash := sha256.Sum224(data) + return hex.EncodeToString(hash[:]) +} + func Encode(obj any) string { data, err := json.Marshal(obj) if err != nil { diff --git a/pkg/llm/registry.go b/pkg/llm/registry.go new file mode 100644 index 00000000..20a3ae3b --- /dev/null +++ b/pkg/llm/registry.go @@ -0,0 +1,54 @@ +package llm + +import ( + "context" + "fmt" + "sort" + + "github.com/gptscript-ai/gptscript/pkg/types" +) + +type Client interface { + Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- types.CompletionStatus) (*types.CompletionMessage, error) + ListModels(ctx context.Context) (result []string, _ error) +} + +type Registry struct { + clientsByModel map[string]Client +} + +func NewRegistry() *Registry { + return &Registry{ + clientsByModel: map[string]Client{}, + } +} + +func (r *Registry) AddClient(ctx context.Context, client Client) error { + models, err := client.ListModels(ctx) + if err != nil { + return err + } + for _, model := range models { + r.clientsByModel[model] = client + } + return nil +} + +func (r *Registry) ListModels(_ context.Context) (result []string, _ error) { + for k := range r.clientsByModel { + result = append(result, k) + } + sort.Strings(result) + return result, nil +} + +func (r *Registry) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- types.CompletionStatus) (*types.CompletionMessage, error) { + if messageRequest.Model == "" { + return nil, fmt.Errorf("model is required") + } + client, ok := r.clientsByModel[messageRequest.Model] + if !ok { + return nil, fmt.Errorf("model not found: %s", messageRequest.Model) + } + return client.Call(ctx, messageRequest, status) +} diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 00d528e7..28f92680 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -15,13 +15,13 @@ import ( "github.com/gptscript-ai/gptscript/pkg/cache" "github.com/gptscript-ai/gptscript/pkg/hash" + "github.com/gptscript-ai/gptscript/pkg/system" "github.com/gptscript-ai/gptscript/pkg/types" "github.com/sashabaranov/go-openai" ) const ( - DefaultModel = openai.GPT4TurboPreview - DefaultPromptParameter = "defaultPromptParameter" + DefaultModel = openai.GPT4TurboPreview ) var ( @@ -31,19 +31,21 @@ var ( ) type Client struct { - url string - key string - c *openai.Client - cache *cache.Client + url string + key string + defaultModel string + c *openai.Client + cache *cache.Client } type Options struct { - BaseURL string `usage:"OpenAI base URL" name:"openai-base-url" env:"OPENAI_BASE_URL"` - APIKey string `usage:"OpenAI API KEY" name:"openai-api-key" env:"OPENAI_API_KEY"` - APIVersion string `usage:"OpenAI API Version (for Azure)" name:"openai-api-version" env:"OPENAI_API_VERSION"` - APIType openai.APIType `usage:"OpenAI API Type (valid: OPEN_AI, AZURE, AZURE_AD)" name:"openai-api-type" env:"OPENAI_API_TYPE"` - OrgID string `usage:"OpenAI organization ID" name:"openai-org-id" env:"OPENAI_ORG_ID"` - Cache *cache.Client + BaseURL string `usage:"OpenAI base URL" name:"openai-base-url" env:"OPENAI_BASE_URL"` + APIKey string `usage:"OpenAI API KEY" name:"openai-api-key" env:"OPENAI_API_KEY"` + APIVersion string `usage:"OpenAI API Version (for Azure)" name:"openai-api-version" env:"OPENAI_API_VERSION"` + APIType openai.APIType `usage:"OpenAI API Type (valid: OPEN_AI, AZURE, AZURE_AD)" name:"openai-api-type" env:"OPENAI_API_TYPE"` + OrgID string `usage:"OpenAI organization ID" name:"openai-org-id" env:"OPENAI_ORG_ID"` + DefaultModel string `usage:"Default LLM model to use" default:"gpt-4-turbo-preview"` + Cache *cache.Client } func complete(opts ...Options) (result Options, err error) { @@ -54,6 +56,7 @@ func complete(opts ...Options) (result Options, err error) { result.Cache = types.FirstSet(opt.Cache, result.Cache) result.APIVersion = types.FirstSet(opt.APIVersion, result.APIVersion) result.APIType = types.FirstSet(opt.APIType, result.APIType) + result.DefaultModel = types.FirstSet(opt.DefaultModel, result.DefaultModel) } if result.Cache == nil { @@ -70,7 +73,7 @@ func complete(opts ...Options) (result Options, err error) { result.APIKey = key } - if result.APIKey == "" { + if result.APIKey == "" && result.BaseURL == "" { return result, fmt.Errorf("OPENAI_API_KEY is not set. Please set the OPENAI_API_KEY environment variable") } @@ -94,12 +97,13 @@ func NewClient(opts ...Options) (*Client, error) { cfg.APIType = types.FirstSet(opt.APIType, cfg.APIType) return &Client{ - c: openai.NewClientWithConfig(cfg), - cache: opt.Cache, + c: openai.NewClientWithConfig(cfg), + cache: opt.Cache, + defaultModel: opt.DefaultModel, }, nil } -func (c *Client) ListModules(ctx context.Context) (result []string, _ error) { +func (c *Client) ListModels(ctx context.Context) (result []string, _ error) { models, err := c.c.ListModels(ctx) if err != nil { return nil, err @@ -138,7 +142,10 @@ func (c *Client) seed(request openai.ChatCompletionRequest) int { return hash.Seed(newRequest) } -func (c *Client) fromCache(messageRequest types.CompletionRequest, request openai.ChatCompletionRequest) (result []openai.ChatCompletionStreamResponse, _ bool, _ error) { +func (c *Client) fromCache(ctx context.Context, messageRequest types.CompletionRequest, request openai.ChatCompletionRequest) (result []openai.ChatCompletionStreamResponse, _ bool, _ error) { + if cache.IsNoCache(ctx) { + return nil, false, nil + } if messageRequest.Cache != nil && !*messageRequest.Cache { return nil, false, nil } @@ -161,7 +168,7 @@ func toToolCall(call types.CompletionToolCall) openai.ToolCall { return openai.ToolCall{ Index: call.Index, ID: call.ID, - Type: openai.ToolType(call.Type), + Type: openai.ToolTypeFunction, Function: openai.FunctionCall{ Name: call.Function.Name, Arguments: call.Function.Arguments, @@ -170,6 +177,13 @@ func toToolCall(call types.CompletionToolCall) openai.ToolCall { } func toMessages(request types.CompletionRequest) (result []openai.ChatCompletionMessage, err error) { + if request.InternalSystemPrompt == nil || *request.InternalSystemPrompt { + result = append(result, openai.ChatCompletionMessage{ + Role: openai.ChatMessageRoleSystem, + Content: system.InternalSystemPrompt, + }) + } + for _, message := range request.Messages { chatMessage := openai.ChatCompletionMessage{ Role: string(message.Role), @@ -198,13 +212,8 @@ func toMessages(request types.CompletionRequest) (result []openai.ChatCompletion chatMessage.Content = chatMessage.MultiContent[0].Text chatMessage.MultiContent = nil - if strings.Contains(chatMessage.Content, DefaultPromptParameter) && strings.HasPrefix(chatMessage.Content, "{") { - data := map[string]any{} - if err := json.Unmarshal([]byte(chatMessage.Content), &data); err == nil && len(data) == 1 { - if v, _ := data[DefaultPromptParameter].(string); v != "" { - chatMessage.Content = v - } - } + if prompt, ok := system.IsDefaultPrompt(chatMessage.Content); ok { + chatMessage.Content = prompt } } @@ -213,16 +222,10 @@ func toMessages(request types.CompletionRequest) (result []openai.ChatCompletion return } -type Status struct { - CompletionID string - Request any - Response any - Cached bool - Chunks any - PartialResponse *types.CompletionMessage -} - -func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- Status) (*types.CompletionMessage, error) { +func (c *Client) Call(ctx context.Context, messageRequest types.CompletionRequest, status chan<- types.CompletionStatus) (*types.CompletionMessage, error) { + if messageRequest.Model == "" { + messageRequest.Model = c.defaultModel + } msgs, err := toMessages(messageRequest) if err != nil { return nil, err @@ -235,8 +238,9 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques request := openai.ChatCompletionRequest{ Model: messageRequest.Model, Messages: msgs, - MaxTokens: messageRequest.MaxToken, + MaxTokens: messageRequest.MaxTokens, Temperature: messageRequest.Temperature, + Grammar: messageRequest.Grammar, } if request.Temperature == nil { @@ -255,7 +259,7 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques params.Properties = map[string]types.Property{} } request.Tools = append(request.Tools, openai.Tool{ - Type: openai.ToolType(tool.Type), + Type: openai.ToolTypeFunction, Function: openai.FunctionDefinition{ Name: tool.Function.Name, Description: tool.Function.Description, @@ -265,14 +269,14 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } id := fmt.Sprint(atomic.AddInt64(&completionID, 1)) - status <- Status{ + status <- types.CompletionStatus{ CompletionID: id, Request: request, } var cacheResponse bool request.Seed = ptr(c.seed(request)) - response, ok, err := c.fromCache(messageRequest, request) + response, ok, err := c.fromCache(ctx, messageRequest, request) if err != nil { return nil, err } else if !ok { @@ -289,7 +293,7 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques result = appendMessage(result, response) } - status <- Status{ + status <- types.CompletionStatus{ CompletionID: id, Chunks: response, Response: result, @@ -328,7 +332,6 @@ func appendMessage(msg types.CompletionMessage, response openai.ChatCompletionSt tc.ToolCall.Index = tool.Index } tc.ToolCall.ID = override(tc.ToolCall.ID, tool.ID) - tc.ToolCall.Type = types.CompletionToolType(override(string(tc.ToolCall.Type), string(tool.Type))) tc.ToolCall.Function.Name += tool.Function.Name tc.ToolCall.Function.Arguments += tool.Function.Arguments @@ -364,7 +367,10 @@ func override(left, right string) string { return left } -func (c *Client) store(key string, responses []openai.ChatCompletionStreamResponse) error { +func (c *Client) store(ctx context.Context, key string, responses []openai.ChatCompletionStreamResponse) error { + if cache.IsNoCache(ctx) { + return nil + } buf := &bytes.Buffer{} gz := gzip.NewWriter(buf) err := json.NewEncoder(gz).Encode(responses) @@ -377,11 +383,11 @@ func (c *Client) store(key string, responses []openai.ChatCompletionStreamRespon return c.cache.Store(key, buf.Bytes()) } -func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, transactionID string, partial chan<- Status) (responses []openai.ChatCompletionStreamResponse, _ error) { +func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, transactionID string, partial chan<- types.CompletionStatus) (responses []openai.ChatCompletionStreamResponse, _ error) { cacheKey := c.cacheKey(request) request.Stream = true - partial <- Status{ + partial <- types.CompletionStatus{ CompletionID: transactionID, PartialResponse: &types.CompletionMessage{ Role: types.CompletionMessageRoleTypeAssistant, @@ -400,14 +406,14 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest, for { response, err := stream.Recv() if err == io.EOF { - return responses, c.store(cacheKey, responses) + return responses, c.store(ctx, cacheKey, responses) } else if err != nil { return nil, err } slog.Debug("stream", "content", response.Choices[0].Delta.Content) if partial != nil { partialMessage = appendMessage(partialMessage, response) - partial <- Status{ + partial <- types.CompletionStatus{ CompletionID: transactionID, PartialResponse: &partialMessage, } diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index d277ff4f..7c55ccba 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -5,9 +5,7 @@ import ( "sync" "time" - "github.com/gptscript-ai/gptscript/pkg/cache" "github.com/gptscript-ai/gptscript/pkg/engine" - "github.com/gptscript-ai/gptscript/pkg/openai" "github.com/gptscript-ai/gptscript/pkg/types" "golang.org/x/sync/errgroup" ) @@ -21,21 +19,12 @@ type Monitor interface { Stop(output string, err error) } -type ( - CacheOptions cache.Options - OpenAIOptions openai.Options -) - type Options struct { - CacheOptions - OpenAIOptions MonitorFactory MonitorFactory `usage:"-"` } -func complete(opts ...Options) (cacheOpts []cache.Options, oaOpts []openai.Options, result Options) { +func complete(opts ...Options) (result Options) { for _, opt := range opts { - cacheOpts = append(cacheOpts, cache.Options(opt.CacheOptions)) - oaOpts = append(oaOpts, openai.Options(opt.OpenAIOptions)) result.MonitorFactory = types.FirstSet(opt.MonitorFactory, result.MonitorFactory) } if result.MonitorFactory == nil { @@ -45,26 +34,15 @@ func complete(opts ...Options) (cacheOpts []cache.Options, oaOpts []openai.Optio } type Runner struct { - c *openai.Client + c engine.Model factory MonitorFactory } -func New(opts ...Options) (*Runner, error) { - cacheOpts, oaOpts, opt := complete(opts...) - cacheClient, err := cache.New(cacheOpts...) - if err != nil { - return nil, err - } - - oaClient, err := openai.NewClient(append(oaOpts, openai.Options{ - Cache: cacheClient, - })...) - if err != nil { - return nil, err - } +func New(client engine.Model, opts ...Options) (*Runner, error) { + opt := complete(opts...) return &Runner{ - c: oaClient, + c: client, factory: opt.MonitorFactory, }, nil } @@ -111,7 +89,7 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp defer progressClose() e := engine.Engine{ - Client: r.c, + Model: r.c, Progress: progress, Env: env, } @@ -166,8 +144,8 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp } } -func streamProgress(callCtx *engine.Context, monitor Monitor) (chan openai.Status, func()) { - progress := make(chan openai.Status) +func streamProgress(callCtx *engine.Context, monitor Monitor) (chan types.CompletionStatus, func()) { + progress := make(chan types.CompletionStatus) wg := sync.WaitGroup{} wg.Add(1) diff --git a/pkg/server/server.go b/pkg/server/server.go index 60ee1c2c..802164f0 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -16,6 +16,8 @@ import ( "github.com/acorn-io/broadcaster" "github.com/gptscript-ai/gptscript/pkg/builtin" + "github.com/gptscript-ai/gptscript/pkg/cache" + "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/loader" "github.com/gptscript-ai/gptscript/pkg/runner" "github.com/gptscript-ai/gptscript/pkg/types" @@ -25,18 +27,12 @@ import ( ) type Options struct { - runner.CacheOptions - runner.OpenAIOptions ListenAddress string } -func complete(opts []Options) (runnerOpts []runner.Options, result Options) { +func complete(opts []Options) (result Options) { for _, opt := range opts { result.ListenAddress = types.FirstSet(opt.ListenAddress, result.ListenAddress) - runnerOpts = append(runnerOpts, runner.Options{ - CacheOptions: opt.CacheOptions, - OpenAIOptions: opt.OpenAIOptions, - }) } if result.ListenAddress == "" { result.ListenAddress = "127.0.0.1:9090" @@ -44,27 +40,15 @@ func complete(opts []Options) (runnerOpts []runner.Options, result Options) { return } -func New(opts ...Options) (*Server, error) { +func New(model engine.Model, opts ...Options) (*Server, error) { events := broadcaster.New[Event]() - runnerOpts, opt := complete(opts) - r, err := runner.New(append(runnerOpts, runner.Options{ + opt := complete(opts) + r, err := runner.New(model, runner.Options{ MonitorFactory: &SessionFactory{ events: events, }, - })...) - if err != nil { - return nil, err - } - - noCacheRunner, err := runner.New(append(runnerOpts, runner.Options{ - CacheOptions: runner.CacheOptions{ - Cache: new(bool), - }, - MonitorFactory: &SessionFactory{ - events: events, - }, - })...) + }) if err != nil { return nil, err } @@ -73,7 +57,6 @@ func New(opts ...Options) (*Server, error) { melody: melody.New(), events: events, runner: r, - noCacheRunner: noCacheRunner, listenAddress: opt.ListenAddress, }, nil } @@ -91,7 +74,6 @@ type Server struct { ctx context.Context melody *melody.Melody runner *runner.Runner - noCacheRunner *runner.Runner events *broadcaster.Broadcaster[Event] listenAddress string } @@ -168,16 +150,10 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { return } - runner := s.runner - if req.URL.Query().Has("nocache") { - runner = s.noCacheRunner - } - - id := fmt.Sprint(atomic.AddInt64(&execID, 1)) - if req.URL.Query().Has("async") { - ctx := context.WithValue(s.ctx, execKey{}, id) + id, ctx := s.getContext(req) + if isAsync(req) { go func() { - _, _ = runner.Run(ctx, prg, os.Environ(), string(body)) + _, _ = s.runner.Run(ctx, prg, os.Environ(), string(body)) }() rw.Header().Set("Content-Type", "application/json") err := json.NewEncoder(rw).Encode(map[string]any{ @@ -187,8 +163,7 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { http.Error(rw, err.Error(), http.StatusInternalServerError) } } else { - ctx := context.WithValue(req.Context(), execKey{}, id) - out, err := runner.Run(ctx, prg, os.Environ(), string(body)) + out, err := s.runner.Run(ctx, prg, os.Environ(), string(body)) if err == nil { _, _ = rw.Write([]byte(out)) } else { @@ -197,6 +172,24 @@ func (s *Server) run(rw http.ResponseWriter, req *http.Request) { } } +func isAsync(req *http.Request) bool { + return req.URL.Query().Has("async") +} + +func (s *Server) getContext(req *http.Request) (string, context.Context) { + ctx := req.Context() + if req.URL.Query().Has("async") { + ctx = s.ctx + } + + id := fmt.Sprint(atomic.AddInt64(&execID, 1)) + ctx = context.WithValue(ctx, execKey{}, id) + if req.URL.Query().Has("nocache") { + ctx = cache.WithNoCache(ctx) + } + return id, ctx +} + func (s *Server) Start(ctx context.Context) error { s.ctx = ctx s.melody.HandleConnect(s.Connect) diff --git a/pkg/system/prompt.go b/pkg/system/prompt.go new file mode 100644 index 00000000..4de97b85 --- /dev/null +++ b/pkg/system/prompt.go @@ -0,0 +1,56 @@ +package system + +import ( + "encoding/json" + "os" + "strings" + + "github.com/gptscript-ai/gptscript/pkg/types" +) + +// InternalSystemPrompt is added to all threads. Changing this is very dangerous as it has a +// terrible global effect and changes the behavior of all scripts. +var InternalSystemPrompt = ` +You are task oriented system. +You receive input from a user, process the input from the given instructions, and then output the result. +Your objective is to provide consistent and correct results. +You do not need to explain the steps taken, only provide the result to the given instructions. +You are referred to as a tool. +` + +// DefaultPromptParameter is used as the key in a json map to indication that we really wanted +// to just send pure text but the interface required JSON (as that is the fundamental interface of tools in OpenAI) +var DefaultPromptParameter = "defaultPromptParameter" + +var DefaultToolSchema = types.JSONSchema{ + Property: types.Property{ + Type: "object", + }, + Properties: map[string]types.Property{ + DefaultPromptParameter: { + Description: "Prompt to send to the tool or assistant. This may be instructions or question.", + Type: "string", + }, + }, + Required: []string{DefaultPromptParameter}, +} + +func init() { + if p := os.Getenv("GPTSCRIPT_INTERNAL_SYSTEM_PROMPT"); p != "" { + InternalSystemPrompt = p + } +} + +// IsDefaultPrompt Checks if the content is a json blob that has the defaultPromptParameter in it. If so +// it will extract out the value and return it. If not it will return the original content as is and false. +func IsDefaultPrompt(content string) (string, bool) { + if strings.Contains(content, DefaultPromptParameter) && strings.HasPrefix(content, "{") { + data := map[string]any{} + if err := json.Unmarshal([]byte(content), &data); err == nil && len(data) == 1 { + if v, _ := data[DefaultPromptParameter].(string); v != "" { + return v, true + } + } + } + return content, false +} diff --git a/pkg/test/examples_test.go b/pkg/test/examples_test.go index 2a02507a..bc0e3e85 100644 --- a/pkg/test/examples_test.go +++ b/pkg/test/examples_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gptscript-ai/gptscript/pkg/loader" + "github.com/gptscript-ai/gptscript/pkg/openai" "github.com/gptscript-ai/gptscript/pkg/runner" "github.com/hexops/autogold/v2" "github.com/stretchr/testify/require" @@ -23,9 +24,13 @@ func TestExamples(t *testing.T) { "fac.gpt", "helloworld.gpt", } + + client, err := openai.NewClient() + require.NoError(t, err) + for _, entry := range tests { t.Run(entry, func(t *testing.T) { - r, err := runner.New() + r, err := runner.New(client) require.NoError(t, err) prg, err := loader.Program(context.Background(), filepath.Join(examplePath, entry), "") @@ -42,7 +47,10 @@ func TestExamples(t *testing.T) { func TestEcho(t *testing.T) { RequireOpenAPIKey(t) - r, err := runner.New() + client, err := openai.NewClient() + require.NoError(t, err) + + r, err := runner.New(client) require.NoError(t, err) prg, err := loader.Program(context.Background(), filepath.Join(examplePath, "echo.gpt"), "") diff --git a/pkg/types/completion.go b/pkg/types/completion.go index 90f6db08..7d7d927e 100644 --- a/pkg/types/completion.go +++ b/pkg/types/completion.go @@ -5,24 +5,19 @@ import ( "strings" ) -const ( - CompletionToolTypeFunction CompletionToolType = "function" -) - -type CompletionToolType string - type CompletionRequest struct { - Model string - Tools []CompletionTool - Messages []CompletionMessage - MaxToken int - Temperature *float32 - JSONResponse bool - Cache *bool + Model string + InternalSystemPrompt *bool + Tools []CompletionTool + Messages []CompletionMessage + MaxTokens int + Temperature *float32 + JSONResponse bool + Grammar string + Cache *bool } type CompletionTool struct { - Type CompletionToolType `json:"type"` Function CompletionFunctionDefinition `json:"function,omitempty"` } @@ -44,9 +39,20 @@ const ( type CompletionMessageRoleType string type CompletionMessage struct { - Role CompletionMessageRoleType `json:"role,omitempty"` - Content []ContentPart `json:"content,omitempty" column:"name=Message,jsonpath=.spec.content"` - ToolCall *CompletionToolCall `json:"toolCall,omitempty"` + Role CompletionMessageRoleType `json:"role,omitempty"` + Content []ContentPart `json:"content,omitempty" column:"name=Message,jsonpath=.spec.content"` + // ToolCall should be set for only messages of type "tool" and Content[0].Text should be set as the + // result of the call describe by this field + ToolCall *CompletionToolCall `json:"toolCall,omitempty"` +} + +type CompletionStatus struct { + CompletionID string + Request any + Response any + Cached bool + Chunks any + PartialResponse *CompletionMessage } func (in CompletionMessage) IsToolCall() bool { @@ -88,7 +94,6 @@ type ContentPart struct { type CompletionToolCall struct { Index *int `json:"index,omitempty"` ID string `json:"id,omitempty"` - Type CompletionToolType `json:"type,omitempty"` Function CompletionFunctionCall `json:"function,omitempty"` } From b1db1e22b44f62e29476432a6742b808ac171aa8 Mon Sep 17 00:00:00 2001 From: tylerslaton Date: Fri, 23 Feb 2024 16:28:29 -0500 Subject: [PATCH 124/774] feat: refactor docs and add content around tools and authoring - chore: add note about adding local model support - docs: add image-generator cookbook - docs: add gen-docs.gpt and a make target for it Signed-off-by: tylerslaton --- Makefile | 5 +- README.md | 21 ++- docs/docs/01-overview.md | 41 ++++++ docs/docs/02-getting-started.md | 61 ++++++++ docs/docs/100-tools/01-using.md | 53 +++++++ docs/docs/100-tools/02-authoring.md | 112 +++++++++++++++ .../03-offerings/01-image-generation.md} | 27 ++-- .../03-offerings/02-system.md} | 9 ++ .../100-tools/03-offerings/_category_.json | 8 ++ .../100-tools.md} | 134 +----------------- docs/docs/100-tools/_category_.json | 3 + docs/docs/101-cookbook/_category_.json | 11 ++ docs/docs/101-cookbook/image-generator.md | 48 +++++++ docs/docs/tools/_category_.json | 8 -- docs/docusaurus.config.js | 9 ++ docs/package.json | 6 +- scripts/gen-docs.gpt | 14 ++ 17 files changed, 416 insertions(+), 154 deletions(-) create mode 100644 docs/docs/01-overview.md create mode 100644 docs/docs/02-getting-started.md create mode 100644 docs/docs/100-tools/01-using.md create mode 100644 docs/docs/100-tools/02-authoring.md rename docs/docs/{tools/image-generation.md => 100-tools/03-offerings/01-image-generation.md} (56%) rename docs/docs/{tools/system.md => 100-tools/03-offerings/02-system.md} (94%) create mode 100644 docs/docs/100-tools/03-offerings/_category_.json rename docs/docs/{01-introduction.md => 100-tools/100-tools.md} (55%) create mode 100644 docs/docs/100-tools/_category_.json create mode 100644 docs/docs/101-cookbook/_category_.json create mode 100644 docs/docs/101-cookbook/image-generator.md delete mode 100644 docs/docs/tools/_category_.json create mode 100644 scripts/gen-docs.gpt diff --git a/Makefile b/Makefile index b2686912..ebee145d 100644 --- a/Makefile +++ b/Makefile @@ -39,5 +39,8 @@ validate: tidy lint ci: build ./bin/gptscript ./scripts/ci.gpt +gen-docs: build + ./bin/gptscript ./scripts/gen-docs.gpt + serve-docs: - (cd docs && npm start) + (cd docs && npm i && npm start) diff --git a/README.md b/README.md index d5b3746b..29ec48f3 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,14 @@ ## Overview -GPTScript is a new scripting language to automate your interaction with a Large Language Model (LLM), namely OpenAI. The ultimate goal is to create a fully natural language based programming experience. The syntax of GPTScript is largely natural language, making it very easy to learn and use. +GPTScript is a new scripting language to automate your interaction with a Large Language Model (LLM), namely OpenAI. The ultimate goal is to create a natural language programming experience. The syntax of GPTScript is largely natural language, making it very easy to learn and use. Natural language prompts can be mixed with traditional scripts such as bash and python or even external HTTP service -calls. With GPTScript you can do just about anything like [plan a vacation](./examples/travel-agent.gpt), +calls. With GPTScript you can do just about anything, like [plan a vacation](./examples/travel-agent.gpt), [edit a file](./examples/add-go-mod-dep.gpt), [run some SQL](./examples/sqlite-download.gpt), or [build a mongodb/flask app](./examples/hacker-news-headlines.gpt). +| :memo: | We are currently exploring options for interacting with local models using GPTScript. | +|-|:-| + ```yaml # example.gpt @@ -59,10 +62,18 @@ Download and install the archive for your platform and architecture from the [re ### 2. Get an API key from [OpenAI](https://platform.openai.com/api-keys). +#### macOS and Linux + ```shell export OPENAI_API_KEY="your-api-key" ``` +#### Windows + +```powershell +$env:OPENAI = 'your-api-key' +``` + ### 3. Run Hello World ```shell @@ -175,7 +186,7 @@ Description: Tool description # This tool can invoke tool1 or tool2 if needed Tools: tool1, tool2 Args: arg1: The description of arg1 - + Tool instructions go here. ``` #### Tool Parameters @@ -228,7 +239,7 @@ description: A tool that echos the input args: input: The input #!/bin/bash - + echo "${input}" ``` @@ -247,7 +258,7 @@ Join us on Discord: [![Discord](https://img.shields.io/discord/12045584209848648 ## License -Copyright (c) 2023 [Acorn Labs, Inc.](http://acorn.io) +Copyright (c) 2024 [Acorn Labs, Inc.](http://acorn.io) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/docs/docs/01-overview.md b/docs/docs/01-overview.md new file mode 100644 index 00000000..ab484afe --- /dev/null +++ b/docs/docs/01-overview.md @@ -0,0 +1,41 @@ +--- +title: Overview +slug: / +--- + +GPTScript is a new scripting language to automate your interaction with a Large Language Model (LLM), namely OpenAI. The ultimate goal is to create a natural language programming experience. The syntax of GPTScript is largely natural language, making it very easy to learn and use. Natural language prompts can be mixed with traditional scripts such as bash and python or even external HTTP service calls. With GPTScript you can do just about anything, like [plan a vacation](https://github.com/gptscript-ai/gptscript/blob/main/examples/travel-agent.gpt), [edit a file](https://github.com/gptscript-ai/gptscript/blob/main/examples/add-go-mod-dep.gpt), [run some SQL](https://github.com/gptscript-ai/gptscript/blob/main/examples/sqlite-download.gpt), or [build a mongodb/flask app](https://github.com/gptscript-ai/gptscript/blob/main/examples/hacker-news-headlines.gpt). + +:::note +We are currently exploring options for interacting with local models using GPTScript. +::: + +```yaml +# example.gpt + +Tools: sys.download, sys.exec, sys.remove + +Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to a +random file. Then expand the archive to a temporary location as there is a sqlite +database in it. + +First inspect the schema of the database to understand the table structure. + +Form and run a SQL query to find the artist with the most number of albums and output +the result of that. + +When done remove the database file and the downloaded content. +``` +``` +$ gptscript ./example.gpt + +OUTPUT: + +The artist with the most number of albums in the database is Iron Maiden, with a total +of 21 albums. +``` + +For more examples check out the [examples](https://github.com/gptscript-ai/gptscript/blob/main/examples) directory. + +## Community + +Join us on Discord: [![Discord](https://img.shields.io/discord/1204558420984864829?label=Discord)](https://discord.gg/9sSf4UyAMC) diff --git a/docs/docs/02-getting-started.md b/docs/docs/02-getting-started.md new file mode 100644 index 00000000..b7f925b3 --- /dev/null +++ b/docs/docs/02-getting-started.md @@ -0,0 +1,61 @@ +# Getting Started + +### 1. Install the latest release + +#### Homebrew (macOS and Linux) + +```shell +brew install gptscript-ai/tap/gptscript +``` + +#### Install Script (macOS and Linux): + +```shell +curl https://get.gptscript.ai/install.sh | sh +``` + +#### WinGet (Windows) + +```shell +winget install gptscript-ai.gptscript +``` + +#### Manually + +Download and install the archive for your platform and architecture from the [releases page](https://github.com/gptscript-ai/gptscript/releases). + +### 2. Get an API key from [OpenAI](https://platform.openai.com/api-keys). + +#### macOS and Linux + +```shell +export OPENAI_API_KEY="your-api-key" +``` + +#### Windows + +```powershell +$env:OPENAI = 'your-api-key' +``` + +### 3. Run Hello World + +```shell +gptscript https://get.gptscript.ai/echo.gpt --input 'Hello, World!' + +OUTPUT: + +Hello, World! +``` +The model used by default is `gpt-4-turbo-preview` and you must have access to that model in your OpenAI account. + +### 4. Extra Credit: Examples and Run Debugging UI + +Clone examples and run debugging UI +```shell +git clone https://github.com/gptscript-ai/gptscript +cd gptscript/examples + +# Run the debugging UI +gptscript --server +``` diff --git a/docs/docs/100-tools/01-using.md b/docs/docs/100-tools/01-using.md new file mode 100644 index 00000000..a2485dc7 --- /dev/null +++ b/docs/docs/100-tools/01-using.md @@ -0,0 +1,53 @@ +# Using Tools +In GPTScript, tools are used to extend the capabilities of a script. The idea behind them is that AI performs better when it has very specific instructions for a given task. Tools are a way to break-up the problem into smaller and more focused pieces where each tool is responsible for a specific task. A typical flow like this is to have a main script that imports a set of tools it can use to accomplish its goal. + +GPTScripts can utilize tools in one of three ways: +1. Built-in system tools +2. In-script tools +3. External tools + +### System Tools +All GPTScripts have access to system tools, like `sys.read` and `sys.write`, that can be used without any additional configuration. + +```yaml +tools: sys.read, sys.write + +Read all of the files in my current directory, do not recurse over any subdirectories, and give me a description of this directory's contents. +``` + +System tools are a set of core tools that come packaged with GPTScript by default. + +### In-Script Tools +Things get more interesting when you start to use custom tools. + +The most basic example of this is an in-script tool that is defined in the same file as the main script. This is useful for breaking up a large script into smaller, more manageable pieces. + +```yaml +tools: random-number + +Select a number at random and, based on the results, write a poem about it. + +--- +name: random-number +description: Generate a random number between 1 and 100. + +Select a number at random between 1 and 100 and return only the number. +``` + +### External Tools + +This is where the real power of GPTScript starts to become evident. For this example lets use the external [image-generation](https://github.com/gptscript-ai/image-generation) and [search](https://github.com/gptscript-ai/search) tools to generate an image and then search the web for similar images. + +:::note +There will be better packaging and distribution for external tools in the future. For now, this assumes you have the tools cloned locally and are pointing to their repos directly. +::: + +```yaml +tools: ./image-generation/tool.gpt, ./vision/tool.gpt, sys.read + +Generate an image of a city skyline at night and write the resulting image to a file called city_skyline.png. + +Take this image and write a description of it in the style of pirate. +``` + +External tools are tools that are defined by a `tool.gpt` file in their root directory. They can be imported into a GPTScript by specifying the path to the tool's root directory. diff --git a/docs/docs/100-tools/02-authoring.md b/docs/docs/100-tools/02-authoring.md new file mode 100644 index 00000000..11a20cff --- /dev/null +++ b/docs/docs/100-tools/02-authoring.md @@ -0,0 +1,112 @@ +# Authoring Tools + +You can author your own tools for your use or to share with others. The process for authoring a tool is as simple as creating a `tool.gpt` file in the root directory of your project. This file is itself a GPTScript that defines the tool's name, description, and what it should do. + +Here's an example of the `tool.gpt` file for the `image-generation` tool: + +```yaml +description: I am a tool that can generate images based on arguments that are sent to me. I return a list of URLs to the generated images. +args: prompt: (required) The text prompt based on which the GPT model will generate a response +args: model: (optional) The model to use for image generation. Defaults to "dall-e-3". +args: size: (optional) The size of the image to generate, format WxH (e.g. 1024x1024). Defaults to 1024x1024. +args: quality: (optional) The quality of the generated image. Allowed values are "standard" or "hd". Default is "standard". +args: number: (optional) The number of images to generate. Defaults to 1. + +#!/usr/bin/env python3 ./cli.py --prompt="${prompt}" --model="${model}" --size="${size}" --quality="${quality}" --number="${number}" +``` + +At the bottom you'll notice a shebang line that specifies the command to run when the tool is invoked. This is the exact command that will be executed when the tool is used in a GPTScript. Doing this with tools allows for a high degree of reliability that the tool would not otherwise have. + +:::tip +Every arg becomes an environment variable when the tool is invoked. +::: + +## Binary Tools +GPTScript can call binaries and scripts located on your system or externally. This is done by defining a `tool.gpt` file in the same directory that the binary or script is located. In that `tool.gpt` file, you call it directly using the `#!` directive. + +For example: + +```yaml +description: This is a tool that calls a binary. +args: arg1: The first argument. + +#!/usr/bin/env ./path/to/binary --arg1="${arg1}" +``` + +## Shell +You can call shell scripts directly using the `#!` directive. For example: + +```yaml +description: This is a tool that calls a shell script. +args: arg1: The first argument. + +#!/usr/bin/env sh +echo "Hello, world!" +./path/to/script.sh --arg1="${arg1}" +``` + +## Python +You can call Python scripts directly, for example: + +```yaml +description: This is a tool that calls a Python script. +args: arg1: The first argument. + +#!/usr/bin/env python3 ./path/to/script.py --arg1="${arg1}" +``` + +If you need to bootstrap a Python environment, you can use a virtual environment. For example: + +```yaml +description: This is a tool that calls a Python script in a virtual environment. +args: arg1: The first argument. + +#!/usr/bin/env sh +python3 -m venv .venv +pip3 install -r requirements.txt +python3 ./path/to/script.py --arg1="${arg1}" +``` + +## Node + +You can call Node.js scripts directly, for example: + +```yaml +description: This is a tool that calls a Node.js script. +args: arg1: The first argument. + +#!/usr/bin/env node ./path/to/script.js --arg1="${arg1}" +``` + +If you need to bootstrap a Node.js environment, you can use call npm in the `tool.gpt` file. For example: + +```yaml +description: This is a tool that calls a Node.js script with a package manager. +args: arg1: The first argument. + +#!/usr/bin/env sh +npm install +node ./path/to/script.js --arg1="${arg1}" +``` + +## Golang + +You can call Golang binaries directly, for example: + +```yaml +description: This is a tool that calls a Golang binary. +args: arg1: The first argument. + +#!/usr/bin/env ./path/to/binary --arg1="${arg1}" +``` + +If you need to bootstrap a Golang binary, you can the go CLI to build it before running it. For example: + +```yaml +description: This is a tool that calls a Golang binary. +args: arg1: The first argument. + +#!/usr/bin/env sh +go build -o ./path/to/binary +./path/to/binary --arg1="${arg1}" +``` diff --git a/docs/docs/tools/image-generation.md b/docs/docs/100-tools/03-offerings/01-image-generation.md similarity index 56% rename from docs/docs/tools/image-generation.md rename to docs/docs/100-tools/03-offerings/01-image-generation.md index 9b0f32bc..c637fb5f 100644 --- a/docs/docs/tools/image-generation.md +++ b/docs/docs/100-tools/03-offerings/01-image-generation.md @@ -1,23 +1,34 @@ # Image Generation -## Overview - The `image-generation` tool leverages OpenAI's DALL-E model to convert textual descriptions into images. It offers a versatile approach to creating visual content, making it suitable for a wide range of applications, from content creation to design assistance. For more information, check out the tool [here](https://github.com/gptscript-ai/image-generation) +## Installation +We are working on an process where installation of tools will be as simple as +referencing the tool's link in your GPTScript. For now, you can follow the steps below to install the image-generation tool. + +1. Clone the image-generation tool repository [from GitHub](https://github.com/gptscript-ai/image-generation). + +```shell +git clone https://github.com/gptscript-ai/image-generation +``` + +2. Run `make bootstrap` to setup the python venv and install the required dependencies. + +```shell +make bootstrap +``` + +3. Reference `/tool.gpt` in your GPTScript. + ## Usage To use the Image Generation tool, you need to make sure that the OPENAI_API_KEY environment variable is set to your OpenAI API key. You can obtain an API key from the OpenAI platform if you don't already have one. With that setup, you can use it in any GPTScript like so: -:::tip -This script assumes you have the `image-generation` tool repo cloned locally and located at `./image-generation`. The ability to import tools from remote -locations is coming soon. -::: - ``` -tools: ./image-generation, sys.write +tools: ./image-generation/tool.gpt, sys.download, sys.write Generate an image of a city skyline at night with a resolution of 512x512 pixels. diff --git a/docs/docs/tools/system.md b/docs/docs/100-tools/03-offerings/02-system.md similarity index 94% rename from docs/docs/tools/system.md rename to docs/docs/100-tools/03-offerings/02-system.md index bc76318c..9575b9e5 100644 --- a/docs/docs/tools/system.md +++ b/docs/docs/100-tools/03-offerings/02-system.md @@ -104,3 +104,12 @@ Writes content to a specified file. - `content`: The content to be written to the file. - `filename`: The filename where the content should be written. + +## sys.append + +Appends the contents to a file. + +#### Arguments + +- `content`: The content to append. +- `filename`: The name of the file to append to. diff --git a/docs/docs/100-tools/03-offerings/_category_.json b/docs/docs/100-tools/03-offerings/_category_.json new file mode 100644 index 00000000..700c3642 --- /dev/null +++ b/docs/docs/100-tools/03-offerings/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Offerings", + "collapsible": true, + "link": { + "type": "generated-index", + "title": "Offerings" + } +} diff --git a/docs/docs/01-introduction.md b/docs/docs/100-tools/100-tools.md similarity index 55% rename from docs/docs/01-introduction.md rename to docs/docs/100-tools/100-tools.md index 8662ac8f..e172cbff 100644 --- a/docs/docs/01-introduction.md +++ b/docs/docs/100-tools/100-tools.md @@ -1,97 +1,7 @@ ---- -title: Overview -slug: / ---- - -GPTScript is a new scripting language to automate your interaction with a Large Language Model (LLM), namely OpenAI. The ultimate goal is to create a fully natural language based programming experience. The syntax of GPTScript is largely natural language, making it very easy to learn and use. -Natural language prompts can be mixed with traditional scripts such as bash and python or even external HTTP service -calls. With GPTScript you can do just about anything like [plan a vacation](https://github.com/gptscript-ai/gptscript/blob/main/examples/travel-agent.gpt), -[edit a file](https://github.com/gptscript-ai/gptscript/blob/main/examples/add-go-mod-dep.gpt), [run some SQL](https://github.com/gptscript-ai/gptscript/blob/main/examples/sqlite-download.gpt), or [build a mongodb/flask app](https://github.com/gptscript-ai/gptscript/blob/main/examples/hacker-news-headlines.gpt). - -```yaml -# example.gpt - -Tools: sys.download, sys.exec, sys.remove - -Download https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip to a -random file. Then expand the archive to a temporary location as there is a sqlite -database in it. - -First inspect the schema of the database to understand the table structure. - -Form and run a SQL query to find the artist with the most number of albums and output -the result of that. - -When done remove the database file and the downloaded content. -``` -``` -$ gptscript ./example.gpt - -OUTPUT: - -The artist with the most number of albums in the database is Iron Maiden, with a total -of 21 albums. -``` -## Quick Start - -### 1. Install the latest release - -#### Homebrew (macOS and Linux) - -```shell -brew install gptscript-ai/tap/gptscript -``` - -#### Install Script (macOS and Linux): - -```shell -curl https://get.gptscript.ai/install.sh | sh -``` - -#### WinGet (Windows) - -```shell -winget install gptscript-ai.gptscript -``` - -#### Manually - -Download and install the archive for your platform and architecture from the [releases page](https://github.com/gptscript-ai/gptscript/releases). - -### 2. Get an API key from [OpenAI](https://platform.openai.com/api-keys). +# Tools -```shell -export OPENAI_API_KEY="your-api-key" -``` - -### 3. Run Hello World - -```shell -gptscript https://get.gptscript.ai/echo.gpt --input 'Hello, World!' - -OUTPUT: - -Hello, World! -``` -The model used by default is `gpt-4-turbo-preview` and you must have access to that model in your OpenAI account. - -### 4. Extra Credit: Examples and Run Debugging UI - -Clone examples and run debugging UI -```shell -git clone https://github.com/gptscript-ai/gptscript -cd gptscript/examples - -# Run the debugging UI -gptscript --server -``` - -## How it works - -***GPTScript is composed of tools.*** Each tool performs a series of actions similar to a function. Tools have available -to them other tools that can be invoked similar to a function call. While similar to a function, the tools are -primarily implemented with a natural language prompt. ***The interaction of the tools is determined by the AI model***, -the model determines if the tool needs to be invoked and what arguments to pass. Tools are intended to be implemented +***GPTScript is composed of tools.*** Each tool performs a series of actions similar to a function. Tools have available to them other tools that can be invoked similar to a function call. While similar to a function, the tools are +primarily implemented with a natural language prompt. ***The interaction of the tools is determined by the AI model***, the model determines if the tool needs to be invoked and what arguments to pass. Tools are intended to be implemented with a natural language prompt but can also be implemented with a command or HTTP call. ### Example @@ -110,14 +20,17 @@ args: question: The question to ask Bob. When asked how I am doing, respond with "Thanks for asking "${question}", I'm doing great fellow friendly AI tool!" ``` + + Put the above content in a file named `bob.gpt` and run the following command: -```shell +```sh $ gptscript bob.gpt OUTPUT: Bob said, "Thanks for asking 'How are you doing?', I'm doing great fellow friendly AI tool!" ``` + Tools can be implemented by invoking a program instead of a natural language prompt. The below example is the same as the previous example but implements Bob using python. @@ -141,10 +54,6 @@ print(f"Thanks for asking {os.environ['question']}, I'm doing great fellow frien With these basic building blocks you can create complex scripts with AI interacting with AI, your local system, data, or external services. -## GPT File Reference - -### Extension -GPTScript files use the `.gpt` extension by convention. ### File Structure A GPTScript file has one or more tools in the file. Each tool is separated by three dashes `---` alone on a line. @@ -232,32 +141,3 @@ args: input: The input echo "${input}" ``` - -## Built in Tools - -There are several built in tools to do basic things like read/write files, download http content and execute commands. -Run `gptscript --list-tools` to list all the built-in tools. - -## Examples - -For more examples check out the [examples](https://github.com/gptscript-ai/gptscript/blob/main/examples) directory. - -## Community - -Join us on Discord: [![Discord](https://img.shields.io/discord/1204558420984864829?label=Discord)](https://discord.gg/9sSf4UyAMC) - -## License - -Copyright (c) 2023 [Acorn Labs, Inc.](http://acorn.io) - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/docs/docs/100-tools/_category_.json b/docs/docs/100-tools/_category_.json new file mode 100644 index 00000000..51a6b95d --- /dev/null +++ b/docs/docs/100-tools/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "Tools" +} diff --git a/docs/docs/101-cookbook/_category_.json b/docs/docs/101-cookbook/_category_.json new file mode 100644 index 00000000..64bd7f52 --- /dev/null +++ b/docs/docs/101-cookbook/_category_.json @@ -0,0 +1,11 @@ +{ + "label": "Cookbook", + "collapsible": true, + "link": { + "type": "generated-index", + "title": "Cookbook" + }, + "customProps": { + "description": "Explore the various things you can do with GPTScript and how to do them." + } +} diff --git a/docs/docs/101-cookbook/image-generator.md b/docs/docs/101-cookbook/image-generator.md new file mode 100644 index 00000000..10c96ee8 --- /dev/null +++ b/docs/docs/101-cookbook/image-generator.md @@ -0,0 +1,48 @@ +# Image Generator + +In this example, let's say that we want to create an image generator tool that will take a prompt from the user and generate an image based on that prompt but +in a specific style that we tell the tool to use. + +1. Clone the image-generation tool repository from Github. + + ```shell + git clone https://github.com/gptscript-ai/image-generation + ``` + +2. Bootstrap the tool. + + ```shell + make bootstrap + ``` + +3. Create a file called `painter.gpt`. + + ```yaml + tools: ./image-generation/tool.gpt, sys.download, sys.write + args: prompt: (required) The prompt to use for generating the image. + + Generate the ${prompt} in the style of a 17th century impressionist oil painting. + + Write the resulting image to a file named "painting.png". + ``` + +4. Run the script. + + ```shell + gptscript painter.gpt --prompt "a city skyline at night" + ``` + +This will generate an image of a city skyline at night in the style of a 17th century impressionist oil painting and write the resulting image to a file named `painting.png`. + +## Recap +In this example, we have created a GPTScript that leverages the `image-generation` tool to generate an image based on a prompt. We gave it some flexibility by specifiying an argument `prompt` that the user can provide when running the script. We also specified gave the script a specific style of the image that we want to generate, that being a 17th century impressionist oil painter. + +Notable things to point out: +#### Tools +The `tools` directive was used here to reference the `image-generation` tool and the `sys.download` and `sys.write` system tools. GPTScript will know the tools availble to it and will use them when it sees fit in the script. + +#### Args +We used the `args` directive to specify the `prompt` argument that the user can provide when running the script. This is a required argument and the user must provide it when running the script. + +#### Interpolation +The `${prompt}` syntax can we used to reference the `prompt` argument in the script. This is a made-up syntax and can be replaced with any other syntax that you prefer. The LLM should be able to understand the syntax and use the argument in the script. diff --git a/docs/docs/tools/_category_.json b/docs/docs/tools/_category_.json deleted file mode 100644 index cd568683..00000000 --- a/docs/docs/tools/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Tools", - "position": 2, - "link": { - "type": "generated-index", - "description": "Explore the various tools on offer for gptscripts" - } -} diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index e14420c4..7b67a9ae 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -60,6 +60,11 @@ const config = { label: "GitHub", position: "right", }, + { + href: "https://discord.gg/9sSf4UyAMC", + label: "Discord", + position: "right", + }, ], }, footer: { @@ -69,6 +74,10 @@ const config = { label: "GitHub", to: "https://github.com/gptscript-ai/gptscript", }, + { + label: "Discord", + to: "https://discord.gg/9sSf4UyAMC", + }, ], copyright: `Copyright © ${new Date().getFullYear()} Acorn Labs, Inc`, }, diff --git a/docs/package.json b/docs/package.json index aad0f56f..7c16660a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -27,11 +27,7 @@ "@docusaurus/types": "3.1.1" }, "browserslist": { - "production": [ - ">0.5%", - "not dead", - "not op_mini all" - ], + "production": [">0.5%", "not dead", "not op_mini all"], "development": [ "last 3 chrome version", "last 3 firefox version", diff --git a/scripts/gen-docs.gpt b/scripts/gen-docs.gpt new file mode 100644 index 00000000..f82d52cc --- /dev/null +++ b/scripts/gen-docs.gpt @@ -0,0 +1,14 @@ +tools: system-tools-state, sys.read, sys.write + +Do the following in order: +1. Get the current state of system tools +2. Update the ./docs/docs/100-tools/03-offerings/02-system.md file to + reflect the latest changes. The file should not change structure and + should add any new content at the end of the file in the same format. + +--- +name: system-tools-state +tools: sys.exec +description: Get the current state of system tools + +#!/usr/bin/env go run main.go --list-tools From 04b4d98deba25d173292c4ca14bc626e027fe1e7 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:16:57 -0500 Subject: [PATCH 125/774] docs: add basic vision tool cookbook Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- docs/docs/101-cookbook/vision.md | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs/docs/101-cookbook/vision.md diff --git a/docs/docs/101-cookbook/vision.md b/docs/docs/101-cookbook/vision.md new file mode 100644 index 00000000..5b04d397 --- /dev/null +++ b/docs/docs/101-cookbook/vision.md @@ -0,0 +1,48 @@ +# Vision + +In this example, let's say that we want to create a `.gpt` script that uses vision to describe an image on the internet in a certain style. + +1. Clone the vision tool repository from Github + + ```shell + git clone https://github.com/gptscript-ai/vision + ``` + +2. Install the tool's dependencies + + ```shell + npm install + ``` + +3. Create a file called `describe.gpt`. + + ```yaml + Tools: sys.write, ./vision/tool.gpt + Args: url: (required) URL of the image to describe. + + Describe the image at ${url} as if you were the narrator of a Wes Anderson film and write it to a file named description.txt. + ``` + +4. Run the script. + + ```shell + gptscript describe.gpt --url "https://github.com/gptscript-ai/vision/blob/main/examples/eiffel-tower.png?raw=true" + ``` + +## Recap + +In this example, we have created a GPTScript that leverages the `vision` tool to describe an image at a given URL. We gave it some flexibility by specifiying an argument `url` that the user can provide when running the script. We also specified gave the script a specific style to generate the description with. + +Notable things to point out: + +#### Tools + +The `tools` directive was used here to reference the `vision` and the `sys.write` tools. GPTScript will know the tools availble to it and will use them when it sees fit in the script. + +#### Args + +We used the `args` directive to specify the `url` argument that the user can provide when running the script. This is a required argument and the user must provide it when running the script. + +#### Interpolation + +The `${url}` syntax can we used to reference the `url` argument in the script. This is a made-up syntax and can be replaced with any other syntax that you prefer. The LLM should be able to understand the syntax and use the argument in the script. From 335490164ee5691a6b0f358e904d6c5dc2562ae5 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:39:52 -0500 Subject: [PATCH 126/774] docs: move discord pill to top of readme Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- README.md | 2 ++ docs/docs/01-overview.md | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 29ec48f3..8f8193b9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # GPTScript +[![Discord](https://img.shields.io/discord/1204558420984864829?label=Discord)](https://discord.gg/9sSf4UyAMC) + ## Overview GPTScript is a new scripting language to automate your interaction with a Large Language Model (LLM), namely OpenAI. The ultimate goal is to create a natural language programming experience. The syntax of GPTScript is largely natural language, making it very easy to learn and use. diff --git a/docs/docs/01-overview.md b/docs/docs/01-overview.md index ab484afe..e5893170 100644 --- a/docs/docs/01-overview.md +++ b/docs/docs/01-overview.md @@ -3,6 +3,8 @@ title: Overview slug: / --- +[![Discord](https://img.shields.io/discord/1204558420984864829?label=Discord)](https://discord.gg/9sSf4UyAMC) + GPTScript is a new scripting language to automate your interaction with a Large Language Model (LLM), namely OpenAI. The ultimate goal is to create a natural language programming experience. The syntax of GPTScript is largely natural language, making it very easy to learn and use. Natural language prompts can be mixed with traditional scripts such as bash and python or even external HTTP service calls. With GPTScript you can do just about anything, like [plan a vacation](https://github.com/gptscript-ai/gptscript/blob/main/examples/travel-agent.gpt), [edit a file](https://github.com/gptscript-ai/gptscript/blob/main/examples/add-go-mod-dep.gpt), [run some SQL](https://github.com/gptscript-ai/gptscript/blob/main/examples/sqlite-download.gpt), or [build a mongodb/flask app](https://github.com/gptscript-ai/gptscript/blob/main/examples/hacker-news-headlines.gpt). :::note @@ -35,7 +37,3 @@ of 21 albums. ``` For more examples check out the [examples](https://github.com/gptscript-ai/gptscript/blob/main/examples) directory. - -## Community - -Join us on Discord: [![Discord](https://img.shields.io/discord/1204558420984864829?label=Discord)](https://discord.gg/9sSf4UyAMC) From 0bafbaa45b45f677edaf2770c466ab83ceb1028b Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Wed, 28 Feb 2024 12:13:41 -0500 Subject: [PATCH 127/774] fix: add a timeout to builtin HTTP functions Signed-off-by: Grant Linville --- pkg/builtin/builtin.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 827af758..62c526b5 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -14,6 +14,7 @@ import ( "path/filepath" "sort" "strings" + "time" "github.com/BurntSushi/locker" "github.com/gptscript-ai/gptscript/pkg/types" @@ -336,8 +337,10 @@ func SysHTTPGet(ctx context.Context, env []string, input string) (_ string, err return "", err } + c := http.Client{Timeout: 10 * time.Second} + log.Debugf("http get %s", params.URL) - resp, err := http.Get(params.URL) + resp, err := c.Get(params.URL) if err != nil { return "", err } @@ -387,7 +390,9 @@ func SysHTTPPost(ctx context.Context, env []string, input string) (_ string, err req.Header.Set("Content-Type", params.ContentType) } - resp, err := http.DefaultClient.Do(req) + c := http.Client{Timeout: 10 * time.Second} + + resp, err := c.Do(req) if err != nil { return "", err } From 366808423d1f3b451a413fc2d93923907be9d027 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Wed, 28 Feb 2024 14:56:32 -0500 Subject: [PATCH 128/774] docs: Internet search tools (#77) Signed-off-by: Grant Linville --- docs/docs/tools/internet-search.md | 107 +++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 docs/docs/tools/internet-search.md diff --git a/docs/docs/tools/internet-search.md b/docs/docs/tools/internet-search.md new file mode 100644 index 00000000..b8992e97 --- /dev/null +++ b/docs/docs/tools/internet-search.md @@ -0,0 +1,107 @@ +# Internet Search + +## Overview + +There are a few different Internet search tools for GPTScript: + +- `bing` +- `bing-image` +- `brave` +- `brave-image` +- `duckduckgo` +- `google` +- `google-image` + +Each of these tools use the corresponding search engine's API to perform searches and return results that +the LLM can process. The number of results returned will depend on the +search engine. This is the format of the results: + +Web search format: +``` +Title: the title of the web page +URL: the link to the web page +Description: a short snippet from the web page + +Title: ... +URL: ... +Description: ... + + +``` + +Image search format: +``` +Title: the title of the image +Source: the link to the web page where the image came from +Image URL: the link to the image + +Title: ... +Source: ... +Image URL: ... + + +``` + +The tools are developed in the [gptscript-ai/search repo](https://github.com/gptscript-ai/search). + +## Setup + +:::note +This will become easier in the future, once packaging for remote GPTScript tools has been implemented. +::: + +To set up your local environment to use these tools, do the following: + +```bash +# Clone the repo +git clone https://github.com/gptscript-ai/search.git + +# Build the Go binary +make build +``` + +Now you can reference the search tools by the relative path to the `tool.gpt` file in the cloned repo, like this: + +```yaml +tools: google-image from ./search/tool.gpt, sys.download + +Search for images of pandas and download one. +``` + +:::tip +You must always specify which tool you are specifically importing from the tool.gpt file, as shown +in the example above. If no tool is specified, it will default to the first tool defined in the file, +which currently is `bing`. +::: + +Specific instructions for each search engine follow. + +## Bing + +The `bing` and `bing-image` tools return search results from the [Bing Web Search API](https://www.microsoft.com/en-us/bing/apis/bing-web-search-api). + +The environment variable `GPTSCRIPT_BING_SEARCH_TOKEN` must be set to your API key in order for it to work. + +## Brave + +The `brave` and `brave-image` tools return search results from the [Brave Search API](https://brave.com/search/api/). + +The environment variable `GPTSCRIPT_BRAVE_SEARCH_TOKEN` must be set to your API key in order for it to work. + +## DuckDuckGo + +The `duckduckgo` tool returns search results from the [DuckDuckGo HTML-only Site](https://html.duckduckgo.com). + +No API key is required to use this tool. + +By default, this tool will make an HTTP request to DuckDuckGo and parse the results. +If you do this enough times, it will start to get rate limited. +Rate limits can be more easily avoided by using Google Chrome in headless mode. +The tool will do this if the `GPTSCRIPT_USE_CHROME` environment variable is set to `true`. + +## Google + +The `google` and `google-image` tools return search results from the [Google Custom Search JSON API](https://developers.google.com/custom-search/v1/overview). + +The environment variable `GPTSCRIPT_GOOGLE_SEARCH_TOKEN` must be set to your API key in order for it to work, +and `GPTSCRIPT_GOOGLE_SEARCH_ENGINE_ID` must be set to your Programmable Search Engine's engine ID. From 635f704ab98b6a75a5d6e2459108985c090a244c Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Wed, 28 Feb 2024 18:17:56 -0500 Subject: [PATCH 129/774] docs: reorganize tool docs (#86) Signed-off-by: Grant Linville --- docs/docs/100-tools/03-offerings/{02-system.md => 01-system.md} | 0 .../{01-image-generation.md => 02-image-generation.md} | 0 .../03-offerings/03-internet-search.md} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename docs/docs/100-tools/03-offerings/{02-system.md => 01-system.md} (100%) rename docs/docs/100-tools/03-offerings/{01-image-generation.md => 02-image-generation.md} (100%) rename docs/docs/{tools/internet-search.md => 100-tools/03-offerings/03-internet-search.md} (100%) diff --git a/docs/docs/100-tools/03-offerings/02-system.md b/docs/docs/100-tools/03-offerings/01-system.md similarity index 100% rename from docs/docs/100-tools/03-offerings/02-system.md rename to docs/docs/100-tools/03-offerings/01-system.md diff --git a/docs/docs/100-tools/03-offerings/01-image-generation.md b/docs/docs/100-tools/03-offerings/02-image-generation.md similarity index 100% rename from docs/docs/100-tools/03-offerings/01-image-generation.md rename to docs/docs/100-tools/03-offerings/02-image-generation.md diff --git a/docs/docs/tools/internet-search.md b/docs/docs/100-tools/03-offerings/03-internet-search.md similarity index 100% rename from docs/docs/tools/internet-search.md rename to docs/docs/100-tools/03-offerings/03-internet-search.md From 954fa75b4cbef83645faa0e8e2d7f578cad0dc5b Mon Sep 17 00:00:00 2001 From: Atulpriya Sharma Date: Thu, 29 Feb 2024 23:03:36 +0530 Subject: [PATCH 130/774] Add Recipe Generator sample application to examples (#84) * Add Recipe Generate sample application --- examples/recipegenerator/README.md | 62 +++++++++++ examples/recipegenerator/app.py | 44 ++++++++ examples/recipegenerator/index.js | 104 ++++++++++++++++++ examples/recipegenerator/package.json | 20 ++++ examples/recipegenerator/recipegenerator.gpt | 15 +++ examples/recipegenerator/requirements.txt | 2 + examples/recipegenerator/templates/index.html | 102 +++++++++++++++++ examples/recipegenerator/tool.gpt | 11 ++ 8 files changed, 360 insertions(+) create mode 100644 examples/recipegenerator/README.md create mode 100644 examples/recipegenerator/app.py create mode 100644 examples/recipegenerator/index.js create mode 100644 examples/recipegenerator/package.json create mode 100755 examples/recipegenerator/recipegenerator.gpt create mode 100644 examples/recipegenerator/requirements.txt create mode 100644 examples/recipegenerator/templates/index.html create mode 100644 examples/recipegenerator/tool.gpt diff --git a/examples/recipegenerator/README.md b/examples/recipegenerator/README.md new file mode 100644 index 00000000..9ccf18bb --- /dev/null +++ b/examples/recipegenerator/README.md @@ -0,0 +1,62 @@ +# Recipe Generator Application + +## Overview + +This Flask application leverages GPTScript and GPTScript Vision to suggest recipes based on an image uploaded by the user. By analyzing the image, the application can identify ingredients and propose a suitable recipe. + +## Features + +- Image upload functionality. +- Automatic ingredient recognition from images. +- Recipe suggestion based on identified ingredients. + +## Installation + +### Prerequisites + +- Python 3.8 or later +- Node.js and npm +- Flask +- Other Python and Node.js dependencies listed in `requirements.txt` and `package.json` respectively. + +### Steps + +1. Clone the repository: + + ``` bash + git clone https://github.com/gptscript-ai/gptscript.git + ``` + +2. Navigate to the `examples/recipegenerator` directory and install the dependencies: + + Python: + + ```bash + pip install -r requirements.txt + ``` + + Node: + + ```bash + npm install + ``` + +3. Setup `OPENAI_API_KEY` (Eg: `export OPENAI_API_KEY="yourapikey123456"`). You can get your [API key here](https://platform.openai.com/api-keys). + +4. Run the Flask application using `flask run` or `python app.py` + +## Usage + +1. Open your web browser and navigate to `http://127.0.0.1:5000/`. +2. Use the web interface to upload an image with some grocery items. +3. The application will process the image, identify potential ingredients, and suggest a recipe based on the analysis. +4. View the suggested recipe, try it and let us know how it turned out to be! + +## Under the hood + +Below are the processes that take place when you execute the application: + +- The Python app places the uploaded image as `grocery.png` in the current working directory. +- It then executes `recipegenerator.gpt` which internally calls `tools.gpt` to perform image analysis to identify the items from the uploaded image. +- The identified ingredients from the image will be stored in a `response.json` file. +- The recipegenerator will then read this response file, generate a recipe and add it to a recipe.md file. \ No newline at end of file diff --git a/examples/recipegenerator/app.py b/examples/recipegenerator/app.py new file mode 100644 index 00000000..db75c4aa --- /dev/null +++ b/examples/recipegenerator/app.py @@ -0,0 +1,44 @@ +from flask import Flask, request, render_template, jsonify +import subprocess +import os + +app = Flask(__name__) + +# Setting the base directory +base_dir = os.path.dirname(os.path.abspath(__file__)) +app.config['UPLOAD_FOLDER'] = base_dir + +SCRIPT_PATH = os.path.join(base_dir, 'recipegenerator.gpt') +GROCERY_PHOTO_FILE_NAME = 'grocery.png' # The expected file name +RECIPE_FILE_NAME = 'recipe.md' # The output file name + +@app.route('/', methods=['GET']) +def index(): + return render_template('index.html') + +@app.route('/upload', methods=['POST']) +def upload_file(): + if 'file' not in request.files: + return jsonify({'error': 'No file part'}), 400 + file = request.files['file'] + if file.filename == '': + return jsonify({'error': 'No selected file'}), 400 + if file: + filename = os.path.join(app.config['UPLOAD_FOLDER'], GROCERY_PHOTO_FILE_NAME) + file.save(filename) + try: + # Execute the script to generate the recipe + subprocess.Popen(f"gptscript {SCRIPT_PATH}", shell=True, stdout=subprocess.PIPE, cwd=base_dir).stdout.read() + + # Read recipe.md file + recipe_file_path = os.path.join(app.config['UPLOAD_FOLDER'], RECIPE_FILE_NAME) + with open(recipe_file_path, 'r') as recipe_file: + recipe_content = recipe_file.read() + + # Return recipe content + return jsonify({'recipe': recipe_content}) + except Exception as e: + return jsonify({'error': str(e)}), 500 + +if __name__ == '__main__': + app.run(debug=False) diff --git a/examples/recipegenerator/index.js b/examples/recipegenerator/index.js new file mode 100644 index 00000000..d25c475a --- /dev/null +++ b/examples/recipegenerator/index.js @@ -0,0 +1,104 @@ +import { Command, Option } from 'commander'; +import { fileTypeFromBuffer } from 'file-type'; +import { URL } from 'whatwg-url'; +import fs from 'fs'; +import OpenAI from 'openai'; + + +async function main() { + const program = new Command(); + + program.description('Utility for processing images with the OpenAI API'); + + program.addOption(new Option('--openai-api-key ', 'OpenAI API Key') + .env('OPENAI_API_KEY') + .makeOptionMandatory() + ); + + program.addOption(new Option('--openai-base-url ', 'OpenAI base URL') + .env('OPENAI_BASE_URL') + ); + + program.addOption(new Option('--openai-org-id ', 'OpenAI Org ID to use') + .env('OPENAI_ORG_ID') + ); + + program.addOption(new Option('--max-tokens ', 'Max tokens to use') + .default(2048) + .env('MAX_TOKENS') + ); + + program.addOption(new Option('--model ', 'Model to process images with') + .env('MODEL') + .choices(['gpt-4-vision-preview']) + .default('gpt-4-vision-preview') + ); + + program.addOption(new Option('--detail ', 'Fidelity to use when processing images') + .env('DETAIL') + .choices(['low', 'high', 'auto']) + .default('auto') + ); + + program.argument('', 'Prompt to send to the vision model'); + + program.argument('', 'List of image URIs to process. Supports file:// and https:// protocols. Images must be jpeg or png.'); + + program.action(run); + await program.parseAsync(); +} + +async function run(prompt, images, opts) { + let content = [] + for (let image of images) { + content.push({ + type: "image_url", + image_url: { + detail: opts.detail, + url: await resolveImageURL(image) + } + }) + } + + const openai = new OpenAI(opts.openaiApiKey, opts.baseUrl, opts.orgId); + const response = await openai.chat.completions.create({ + model: opts.model, + max_tokens: opts.maxTokens, + messages: [ + { + role: 'user', + content: [ + { type: "text", text: prompt }, + ...content + ] + }, + ] + }); + + console.log(JSON.stringify(response, null, 4)); +} + +async function resolveImageURL(image) { + const uri = new URL(image) + switch (uri.protocol) { + case 'http:': + case 'https:': + return image; + case 'file:': + const filePath = image.slice(7) + const data = fs.readFileSync(filePath) + const mime = (await fileTypeFromBuffer(data)).mime + if (mime != 'image/jpeg' && mime != 'image/png') { + throw new Error('Unsupported mimetype') + } + const base64 = data.toString('base64') + return `data:${mime};base64,${base64}` + default: + throw new Error('Unsupported protocol') + } +} + +main(); + + + diff --git a/examples/recipegenerator/package.json b/examples/recipegenerator/package.json new file mode 100644 index 00000000..f0adea04 --- /dev/null +++ b/examples/recipegenerator/package.json @@ -0,0 +1,20 @@ +{ + "name": "vision", + "version": "0.0.1", + "description": "Utility for processing images with the OpenAI API", + "exports": "./index.js", + "type": "module", + "scripts": { + "start": "node index.js" + }, + "bin": "index.js", + "keywords": [], + "author": "", + "dependencies": { + "commander": "^9.0.0", + "file-type": "^19.0.0", + "openai": "^4.28.0", + "whatwg-url": "^14.0.0" + } + } + \ No newline at end of file diff --git a/examples/recipegenerator/recipegenerator.gpt b/examples/recipegenerator/recipegenerator.gpt new file mode 100755 index 00000000..5d8d5823 --- /dev/null +++ b/examples/recipegenerator/recipegenerator.gpt @@ -0,0 +1,15 @@ +tools: sys.find, sys.read, sys.write, recipegenerator, tool.gpt + +Perform the following steps in order: + +1. Give me a list of 5 to 10 ingredients from the picture grocery.png located in the current directory and put those extracted ingredients into a list. +2. Based on these ingredients list, suggest me one recipe that is quick to cook and create a new recipe.md file with the recipe + + +--- +name: recipegenerator +description: Generate a recipe from the list of ingredients +args: ingredients: a list of available ingredients. +tools: sys.read + +Generate 1 new recipe based on the ingredients list \ No newline at end of file diff --git a/examples/recipegenerator/requirements.txt b/examples/recipegenerator/requirements.txt new file mode 100644 index 00000000..8882dd85 --- /dev/null +++ b/examples/recipegenerator/requirements.txt @@ -0,0 +1,2 @@ +Flask==2.0.1 +Werkzeug==2.2.2 diff --git a/examples/recipegenerator/templates/index.html b/examples/recipegenerator/templates/index.html new file mode 100644 index 00000000..62a80ebc --- /dev/null +++ b/examples/recipegenerator/templates/index.html @@ -0,0 +1,102 @@ + + + + + + Recipe Generator + + + + + + + + +
+

Recipe Generator

+
+

Don't know what to do with what's in your shopping cart? Well, click a picture and upload the image to Recipe Generator that will give you interesting ideas of what you can cook from those ingredients! This is built using GPTScript.

+
+
+ +
+
+
+
+ + +
+
+
+
+
+ +
+ + + + + diff --git a/examples/recipegenerator/tool.gpt b/examples/recipegenerator/tool.gpt new file mode 100644 index 00000000..6bb59bf8 --- /dev/null +++ b/examples/recipegenerator/tool.gpt @@ -0,0 +1,11 @@ +Name: vision +Description: Analyze a set of images using a given prompt and vision model. +Args: detail: Fidelity to process images at. One of ["high", "low", "auto"]. Default is "auto". +Args: max-tokens: The maximum number of tokens. Default is 2048. +Args: model: The name of the model to use. Default is "gpt-4-vision-preview". +Args: prompt: The text prompt based on which the GPT model will generate a response. +Args: images: Space-delimited list of image URIs to analyze. Valid URI protocols are "http" and "https" for remote images, and "file" for local images. Only supports jpeg and png. + +#!/bin/bash + +node index.js "${PROMPT}" ${IMAGES} From 46e0f13e503b8c0bb01499997887b19bcc2155f4 Mon Sep 17 00:00:00 2001 From: sheng-liang Date: Thu, 29 Feb 2024 09:35:42 -0800 Subject: [PATCH 131/774] Create README-USECASES.md (#90) * Added README-USECASES.md --- docs/README-USECASES.md | 93 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 docs/README-USECASES.md diff --git a/docs/README-USECASES.md b/docs/README-USECASES.md new file mode 100644 index 00000000..3d290eb3 --- /dev/null +++ b/docs/README-USECASES.md @@ -0,0 +1,93 @@ +# Use Cases of GPTScript + +## Retrieval + +Retrieval-Augmented Generation (RAG) leverages a knowledge base outside of the training data before consulting the LLM to generate a response. +The following GPTScript implements RAG: + +```yaml +name: rag +description: implements retrieval-augmented generation +args: prompt: a string +tools: query + +First query the ${prompt} in the knowledge base, then construsts an answer to ${prompt} based on the result of the query. + +--- + +name: query +description: queries the prompt in the knowledge base +args: prompt: a string + +... (implementation of knowledge base query follows) ... +``` + +The idea behind RAG is simple. Its core logic can be implemented in one GPTScript statement: `First query the ${prompt} in the knowledge base, then construsts an answer to ${prompt} based on the result of the query.` The real work of building RAG lies in the tool that queries your knowledge base. + +You construct the appropriate query tool based on the type of knowledge base you have. + +| Knowledge Base | Query Tool | +|------|------| +| A vector database storing common document types such as text, HTML, PDF, and Word | Integrate with LlamaIndex for vector database support [Link to example]| +| Use the public or private internet to supply up-to-date knowledge | Implement query tools using a search engine, as shown in [`search.gpt`](../examples/search.gpt)| +| A structured database supporting SQL such as sqlite, MySQL, PostgreSQL, and Oracle DB | Implement query tools using database command line tools such as `sqlite` and `mysql` [Link to example]| +| An ElasticSearch/OpenSearch database storing logs or other text files | Implement query tools using database command line tools [Link to example]| +| Other databases such as graph or time series databases | Implement query tools using database command line tools [Link to example]| + +## Task Automation + +### Planning + +Here is a GPTScript that produces a detailed travel itenirary based on inputs from a user: [`travel-agent.gpt`](../examples/travel-agent.gpt) + +### Web UI Automation + +Here is a GPTScript that automates data gathering and analysis of web sites by interacting with a chrome web browser. [Link to example here] + +### CLI Automation + +Here is a GPTScript that automates Kubernetes operations by driving the `kubectl` command line. [Link to example here] + +## Agents and Assistants + +Agents and assistants are synonyms. They are software programs that leverage LLM to carry out tasks. + +In GPTScript, agents and assistants are implemented using tools. Tools can use other tools. Tools can be implemented using natural language prompts or using traditional programming languages such as Python or JavaScript. You can therefore build arbitrarily complex agents and assistants in GPTScript. Here is an example of an assistant that leverages an HTTP client, MongoDB, and Python code generation to display Hacker News headlines: [`hacker-news-headlines.gpt`](../examples/hacker-news-headlines.gpt) + +## Data Analysis + +Depending on the context window supported by the LLM, you can either send a large amount of data to the LLM to analyze in one shot or supply data in batches. + +### Summarization + +Here is a GPTScript that sends a large document in batches to the LLM and produces a summary of the entire document. [Link to example here] + +Here is a GPTScript that reads the content of a large SQL database and produces a summary of the entire database. [Link to example here] + +### Tagging + +Here is a GPTScript that performs sentiment analysis on the input text. [Link to example here] + +### CSV Files + +Here is a GPTScript that summarizes the content of a CSV file. [Link to example here] + +### Understanding Code + +Here is a GPTScript that summarizes the the code stored under the current directory: [`describe-code.gpt`](../examples/describe-code.gpt) + +## Audio, Image, and Vision + +[More details to come] + +## Memory Management + +LLMs are stateless. That's why GPTScript by default caches LLM invocations. LLM apps need to keep memory outside of the model. + +GPTScript provides a means to manage memory that persists across multiple LLM invocations. The relevant information can be extracted and passed into the LLM as part of the context. In addition, LLM can utilize tools to obtain additional data from the memory maintained in GPTScript. + +[More details to follow.] + +## Chatbots + +GPTScript in combination with Rubra UI provide you with a turn-key implementation of chatbots. [More details to follow] From 3623521cce9bfe8de2fd855a12c936d860923a1c Mon Sep 17 00:00:00 2001 From: Craig Jellick Date: Thu, 29 Feb 2024 15:13:59 -0700 Subject: [PATCH 132/774] Delete examples/edit.gpt (#87) This is a dupe of add-go-mod-dep.gpt Signed-off-by: Craig Jellick --- examples/edit.gpt | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 examples/edit.gpt diff --git a/examples/edit.gpt b/examples/edit.gpt deleted file mode 100644 index 72629de6..00000000 --- a/examples/edit.gpt +++ /dev/null @@ -1,3 +0,0 @@ -tools: sys.read, sys.write - -Edit the go.mod file and add k8s.io/api version v0.29.0 as a dependency From 1db7708450034596d0169443226ab25b44ce8e74 Mon Sep 17 00:00:00 2001 From: Craig Jellick Date: Thu, 29 Feb 2024 15:24:20 -0700 Subject: [PATCH 133/774] Ignore common node and python files (#97) These are going to start showing up in the examples. If you run the recipegenerator example, you would see these as changes. Signed-off-by: Craig Jellick --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 53eee279..12d2326c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ /bin /.idea /static/ui +**/node_modules/ +**/package-lock.json +**/__pycache__ From c8eae2a8d45edd34c1943d092d6ea25b5ff4fc92 Mon Sep 17 00:00:00 2001 From: Oscar Ward Date: Thu, 29 Feb 2024 14:35:36 -0800 Subject: [PATCH 134/774] enhance: add support for azure deployment name mapping (#78) --- .gitignore | 1 + README.md | 9 +++++++++ go.mod | 4 +--- go.sum | 4 ++-- pkg/openai/client.go | 28 ++++++++++++++++++++-------- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 12d2326c..73f4d464 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ **/node_modules/ **/package-lock.json **/__pycache__ +/docs/yarn.lock diff --git a/README.md b/README.md index 8f8193b9..99a19a6f 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,15 @@ Download and install the archive for your platform and architecture from the [re export OPENAI_API_KEY="your-api-key" ``` +Alternatively Azure OpenAI can be utilized + +```shell +export OPENAI_API_KEY="your-api-key" +export OPENAI_BASE_URL="your-endpiont" +export OPENAI_API_TYPE="AZURE" +export OPENAI_AZURE_DEPLOYMENT="your-deployment-name" +``` + #### Windows ```powershell diff --git a/go.mod b/go.mod index 4347ea7b..1d73035b 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/gptscript-ai/gptscript go 1.22.0 -replace github.com/sashabaranov/go-openai => github.com/gptscript-ai/go-openai v0.0.0-20240227161457-daa30caa3185 - require ( github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d @@ -14,7 +12,7 @@ require ( github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 github.com/olahol/melody v1.1.4 github.com/rs/cors v1.10.1 - github.com/sashabaranov/go-openai v1.18.3 + github.com/sashabaranov/go-openai v1.20.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index ab8fa286..4ad85942 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,6 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gptscript-ai/go-openai v0.0.0-20240227161457-daa30caa3185 h1:+TfC9DYtWuexdL7x1lIdD1HP61IStb3ZTj/byBdiWs0= -github.com/gptscript-ai/go-openai v0.0.0-20240227161457-daa30caa3185/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/hexops/autogold v0.8.1/go.mod h1:97HLDXyG23akzAoRYJh/2OBs3kd80eHyKPvZw0S5ZBY= github.com/hexops/autogold v1.3.1 h1:YgxF9OHWbEIUjhDbpnLhgVsjUDsiHDTyDfy2lrfdlzo= github.com/hexops/autogold v1.3.1/go.mod h1:sQO+mQUCVfxOKPht+ipDSkJ2SCJ7BNJVHZexsXqWMx4= @@ -97,6 +95,8 @@ github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/samber/slog-logrus v1.0.0 h1:SsrN0p9akjCEaYd42Q5GtisMdHm0q11UD4fp4XCZi04= github.com/samber/slog-logrus v1.0.0/go.mod h1:ZTdPCmVWljwlfjz6XflKNvW4TcmYlexz4HMUOO/42bI= +github.com/sashabaranov/go-openai v1.20.1 h1:cFnTixAtc0I0cCBFr8gkvEbGCm6Rjf2JyoVWCjXwy9g= +github.com/sashabaranov/go-openai v1.20.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 28f92680..1590f29c 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -27,6 +27,7 @@ const ( var ( key = os.Getenv("OPENAI_API_KEY") url = os.Getenv("OPENAI_URL") + azureModel = os.Getenv("OPENAI_AZURE_DEPLOYMENT") completionID int64 ) @@ -80,6 +81,15 @@ func complete(opts ...Options) (result Options, err error) { return result, err } +func AzureMapperFunction(model string) string { + if azureModel == "" { + return model + } + return map[string]string{ + openai.GPT4TurboPreview: azureModel, + }[model] +} + func NewClient(opts ...Options) (*Client, error) { opt, err := complete(opts...) if err != nil { @@ -89,6 +99,7 @@ func NewClient(opts ...Options) (*Client, error) { cfg := openai.DefaultConfig(opt.APIKey) if strings.Contains(string(opt.APIType), "AZURE") { cfg = openai.DefaultAzureConfig(key, url) + cfg.AzureModelMapperFunc = AzureMapperFunction } cfg.BaseURL = types.FirstSet(opt.BaseURL, cfg.BaseURL) @@ -236,15 +247,16 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } request := openai.ChatCompletionRequest{ - Model: messageRequest.Model, - Messages: msgs, - MaxTokens: messageRequest.MaxTokens, - Temperature: messageRequest.Temperature, - Grammar: messageRequest.Grammar, + Model: messageRequest.Model, + Messages: msgs, + MaxTokens: messageRequest.MaxTokens, } - if request.Temperature == nil { - request.Temperature = new(float32) + if messageRequest.Temperature == nil { + // this is a hack because the field is marked as omitempty, so we need it to be set to a non-zero value but arbitrarily small + request.Temperature = 1e-08 + } else { + request.Temperature = *messageRequest.Temperature } if messageRequest.JSONResponse { @@ -260,7 +272,7 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques } request.Tools = append(request.Tools, openai.Tool{ Type: openai.ToolTypeFunction, - Function: openai.FunctionDefinition{ + Function: &openai.FunctionDefinition{ Name: tool.Function.Name, Description: tool.Function.Description, Parameters: params, From 701b9c8eb5010110be284f0e71c44f44376e106a Mon Sep 17 00:00:00 2001 From: Craig Jellick Date: Thu, 29 Feb 2024 15:55:16 -0700 Subject: [PATCH 135/774] Add vision usecase (#98) Signed-off-by: Craig Jellick --- docs/README-USECASES.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/README-USECASES.md b/docs/README-USECASES.md index 3d290eb3..ff848ae0 100644 --- a/docs/README-USECASES.md +++ b/docs/README-USECASES.md @@ -76,7 +76,10 @@ Here is a GPTScript that summarizes the content of a CSV file. [Link to example Here is a GPTScript that summarizes the the code stored under the current directory: [`describe-code.gpt`](../examples/describe-code.gpt) -## Audio, Image, and Vision +## Vision, Image, and Audio + +### Vision +Here is an example of a web app that leverages GPTScript to recognize ingredients in a photo and suggest a recipe based on them: [recipe-generator](../examples/recipegenerator). [More details to come] From 6126d2721de78b0a1255a16e7c14fdbf1eb68e21 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 29 Feb 2024 16:41:24 -0700 Subject: [PATCH 136/774] Set working directory of tool calls to the directory of the file --- pkg/cli/gptscript.go | 2 +- pkg/engine/cmd.go | 3 + pkg/engine/engine.go | 3 +- pkg/engine/http.go | 17 +++ pkg/loader/loader.go | 22 +-- pkg/mvl/log.go | 5 +- pkg/runner/log.go | 5 + pkg/runner/runner.go | 24 +++- pkg/test/examples_test.go | 70 ---------- pkg/test/testdata/TestEcho.golden | 1 - pkg/test/testdata/TestExamples/fac.gpt.golden | 1 - .../TestExamples/helloworld.gpt.golden | 1 - pkg/tests/runner_test.go | 26 ++++ pkg/tests/testdata/TestCwd.golden | 91 ++++++++++++ pkg/tests/testdata/TestCwd/call1.golden | 33 +++++ pkg/tests/testdata/TestCwd/call2.golden | 62 +++++++++ pkg/tests/testdata/TestCwd/call3.golden | 91 ++++++++++++ pkg/tests/testdata/TestCwd/data.txt | 1 + pkg/tests/testdata/TestCwd/subtool/sub.txt | 1 + pkg/tests/testdata/TestCwd/subtool/test.gpt | 6 + pkg/tests/testdata/TestCwd/test.gpt | 13 ++ pkg/tests/tester/runner.go | 130 ++++++++++++++++++ pkg/types/tool.go | 1 + 23 files changed, 518 insertions(+), 91 deletions(-) create mode 100644 pkg/runner/log.go delete mode 100644 pkg/test/examples_test.go delete mode 100644 pkg/test/testdata/TestEcho.golden delete mode 100644 pkg/test/testdata/TestExamples/fac.gpt.golden delete mode 100644 pkg/test/testdata/TestExamples/helloworld.gpt.golden create mode 100644 pkg/tests/runner_test.go create mode 100644 pkg/tests/testdata/TestCwd.golden create mode 100644 pkg/tests/testdata/TestCwd/call1.golden create mode 100644 pkg/tests/testdata/TestCwd/call2.golden create mode 100644 pkg/tests/testdata/TestCwd/call3.golden create mode 100644 pkg/tests/testdata/TestCwd/data.txt create mode 100644 pkg/tests/testdata/TestCwd/subtool/sub.txt create mode 100644 pkg/tests/testdata/TestCwd/subtool/test.gpt create mode 100644 pkg/tests/testdata/TestCwd/test.gpt create mode 100644 pkg/tests/tester/runner.go diff --git a/pkg/cli/gptscript.go b/pkg/cli/gptscript.go index bee280bd..f2833256 100644 --- a/pkg/cli/gptscript.go +++ b/pkg/cli/gptscript.go @@ -37,7 +37,7 @@ type GPTScript struct { OpenAIOptions DisplayOptions Debug bool `usage:"Enable debug logging"` - Quiet *bool `usage:"No output logging" short:"q"` + Quiet *bool `usage:"No output logging (set --quiet=false to force on even when there is no TTY)" short:"q"` Output string `usage:"Save output to a file, or - for stdout" short:"o"` Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"` SubTool string `usage:"Use tool of this name, not the first tool in file"` diff --git a/pkg/engine/cmd.go b/pkg/engine/cmd.go index 1a06712a..4cc956eb 100644 --- a/pkg/engine/cmd.go +++ b/pkg/engine/cmd.go @@ -59,6 +59,9 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) cmd.Stdin = strings.NewReader(input) cmd.Stderr = io.MultiWriter(all, os.Stderr) cmd.Stdout = io.MultiWriter(all, output) + if tool.WorkingDir != "" { + cmd.Dir = tool.WorkingDir + } if err := cmd.Run(); err != nil { _, _ = os.Stderr.Write(output.Bytes()) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 83be656d..b9ec8cb1 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -230,8 +230,7 @@ func (e *Engine) complete(ctx context.Context, state *State) (*Return, error) { ToolName: content.ToolCall.Function.Name, Input: content.ToolCall.Function.Arguments, } - } - if content.Text != "" { + } else { cp := content.Text ret.Result = &cp } diff --git a/pkg/engine/http.go b/pkg/engine/http.go index 78796e1c..c48838c5 100644 --- a/pkg/engine/http.go +++ b/pkg/engine/http.go @@ -7,6 +7,7 @@ import ( "io" "net/http" "net/url" + "os" "strings" "github.com/gptscript-ai/gptscript/pkg/types" @@ -15,7 +16,19 @@ import ( const DaemonURLSuffix = ".daemon.gpt.local" func (e *Engine) runHTTP(ctx context.Context, prg *types.Program, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { + envMap := map[string]string{} + for _, env := range e.Env { + v, ok := strings.CutPrefix(env, "GPTSCRIPT_VAR_") + if ok { + k, v, _ := strings.Cut(v, "=") + envMap[k] = v + } + } + toolURL := strings.Split(tool.Instructions, "\n")[0][2:] + toolURL = os.Expand(toolURL, func(s string) string { + return envMap[s] + }) parsed, err := url.Parse(toolURL) if err != nil { @@ -51,6 +64,10 @@ func (e *Engine) runHTTP(ctx context.Context, prg *types.Program, tool types.Too req.Header.Set("X-GPTScript-Tool-Name", tool.Parameters.Name) + for k, v := range envMap { + req.Header.Set("X-GPTScript-Var-"+k, v) + } + if err := json.Unmarshal([]byte(input), &map[string]any{}); err == nil { req.Header.Set("Content-Type", "application/json") } else { diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 27f9f132..22856290 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -200,6 +200,7 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN ) for i, tool := range tools { + tool.WorkingDir = base.Path tool.Source.File = base.File // Probably a better way to come up with an ID @@ -234,7 +235,13 @@ var ( invalidChars = regexp.MustCompile("[^a-zA-Z0-9_-]+") ) -func toolNormalizer(tool string) string { +func ToolNormalizer(tool string) string { + parts := strings.Split(tool, "/") + tool = parts[len(parts)-1] + if strings.HasSuffix(tool, ".gpt") { + tool = strings.TrimSuffix(tool, filepath.Ext(tool)) + } + if validToolName.MatchString(tool) { return tool } @@ -251,22 +258,17 @@ func toolNormalizer(tool string) string { } func pickToolName(toolName string, existing map[string]struct{}) string { - newName, suffix, ok := strings.Cut(toolName, "/") - if ok { - newName = suffix - } - newName = strings.TrimSuffix(newName, filepath.Ext(newName)) - if newName == "" { - newName = "external" + if toolName == "" { + toolName = "external" } for { - testName := toolNormalizer(newName) + testName := ToolNormalizer(toolName) if _, ok := existing[testName]; !ok { existing[testName] = struct{}{} return testName } - newName += "0" + toolName += "0" } } diff --git a/pkg/mvl/log.go b/pkg/mvl/log.go index ace857ec..a65aa7de 100644 --- a/pkg/mvl/log.go +++ b/pkg/mvl/log.go @@ -48,7 +48,10 @@ func Package() Logger { _, p, _, _ := runtime.Caller(1) _, suffix, _ := strings.Cut(p, "gptscript/") i := strings.LastIndex(suffix, "/") - return New(suffix[:i]) + if i > 0 { + return New(suffix[:i]) + } + return New(p) } func New(name string) Logger { diff --git a/pkg/runner/log.go b/pkg/runner/log.go new file mode 100644 index 00000000..72772a6c --- /dev/null +++ b/pkg/runner/log.go @@ -0,0 +1,5 @@ +package runner + +import "github.com/gptscript-ai/gptscript/pkg/mvl" + +var log = mvl.Package() diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 7c55ccba..fa2f9571 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -2,6 +2,7 @@ package runner import ( "context" + "os" "sync" "time" @@ -20,30 +21,41 @@ type Monitor interface { } type Options struct { + WorkingDir string MonitorFactory MonitorFactory `usage:"-"` } func complete(opts ...Options) (result Options) { for _, opt := range opts { + result.WorkingDir = types.FirstSet(opt.WorkingDir, result.WorkingDir) result.MonitorFactory = types.FirstSet(opt.MonitorFactory, result.MonitorFactory) } if result.MonitorFactory == nil { result.MonitorFactory = noopFactory{} } + if result.WorkingDir == "" { + var err error + result.WorkingDir, err = os.Getwd() + if err != nil { + log.Fatalf("failed to determine current working directory: %v", err) + } + } return } type Runner struct { - c engine.Model - factory MonitorFactory + c engine.Model + factory MonitorFactory + workingDir string } func New(client engine.Model, opts ...Options) (*Runner, error) { opt := complete(opts...) return &Runner{ - c: client, - factory: opt.MonitorFactory, + c: client, + factory: opt.MonitorFactory, + workingDir: opt.WorkingDir, }, nil } @@ -94,6 +106,10 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp Env: env, } + if r.workingDir != "" { + e.Env = append(e.Env, "GPTSCRIPT_VAR_WORKDIR="+r.workingDir) + } + monitor.Event(Event{ Time: time.Now(), CallContext: &callCtx, diff --git a/pkg/test/examples_test.go b/pkg/test/examples_test.go deleted file mode 100644 index bc0e3e85..00000000 --- a/pkg/test/examples_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package test - -import ( - "context" - "os" - "path/filepath" - "testing" - - "github.com/gptscript-ai/gptscript/pkg/loader" - "github.com/gptscript-ai/gptscript/pkg/openai" - "github.com/gptscript-ai/gptscript/pkg/runner" - "github.com/hexops/autogold/v2" - "github.com/stretchr/testify/require" -) - -const ( - examplePath = "../../examples" -) - -func TestExamples(t *testing.T) { - RequireOpenAPIKey(t) - - tests := []string{ - "fac.gpt", - "helloworld.gpt", - } - - client, err := openai.NewClient() - require.NoError(t, err) - - for _, entry := range tests { - t.Run(entry, func(t *testing.T) { - r, err := runner.New(client) - require.NoError(t, err) - - prg, err := loader.Program(context.Background(), filepath.Join(examplePath, entry), "") - require.NoError(t, err) - - output, err := r.Run(context.Background(), prg, os.Environ(), "") - require.NoError(t, err) - - autogold.ExpectFile(t, output) - }) - } -} - -func TestEcho(t *testing.T) { - RequireOpenAPIKey(t) - - client, err := openai.NewClient() - require.NoError(t, err) - - r, err := runner.New(client) - require.NoError(t, err) - - prg, err := loader.Program(context.Background(), filepath.Join(examplePath, "echo.gpt"), "") - require.NoError(t, err) - - output, err := r.Run(context.Background(), prg, os.Environ(), "this is a test") - require.NoError(t, err) - - autogold.ExpectFile(t, output) -} - -func RequireOpenAPIKey(t *testing.T) { - t.Helper() - if os.Getenv("OPENAI_API_KEY") == "" { - t.Skip() - } -} diff --git a/pkg/test/testdata/TestEcho.golden b/pkg/test/testdata/TestEcho.golden deleted file mode 100644 index 8ad1ddf9..00000000 --- a/pkg/test/testdata/TestEcho.golden +++ /dev/null @@ -1 +0,0 @@ -"this is a test" diff --git a/pkg/test/testdata/TestExamples/fac.gpt.golden b/pkg/test/testdata/TestExamples/fac.gpt.golden deleted file mode 100644 index 6617fc9b..00000000 --- a/pkg/test/testdata/TestExamples/fac.gpt.golden +++ /dev/null @@ -1 +0,0 @@ -"6" diff --git a/pkg/test/testdata/TestExamples/helloworld.gpt.golden b/pkg/test/testdata/TestExamples/helloworld.gpt.golden deleted file mode 100644 index fe857725..00000000 --- a/pkg/test/testdata/TestExamples/helloworld.gpt.golden +++ /dev/null @@ -1 +0,0 @@ -"Hello world" diff --git a/pkg/tests/runner_test.go b/pkg/tests/runner_test.go new file mode 100644 index 00000000..6c82eae3 --- /dev/null +++ b/pkg/tests/runner_test.go @@ -0,0 +1,26 @@ +package tests + +import ( + "testing" + + "github.com/gptscript-ai/gptscript/pkg/tests/tester" + "github.com/gptscript-ai/gptscript/pkg/types" + "github.com/stretchr/testify/assert" +) + +func TestCwd(t *testing.T) { + runner := tester.NewRunner(t) + + runner.RespondWith(tester.Result{ + Func: types.CompletionFunctionCall{ + Name: "subtool/test", + }, + }) + runner.RespondWith(tester.Result{ + Func: types.CompletionFunctionCall{ + Name: "local", + }, + }) + x := runner.RunDefault() + assert.Equal(t, "TEST RESULT CALL: 3", x) +} diff --git a/pkg/tests/testdata/TestCwd.golden b/pkg/tests/testdata/TestCwd.golden new file mode 100644 index 00000000..f564ec3f --- /dev/null +++ b/pkg/tests/testdata/TestCwd.golden @@ -0,0 +1,91 @@ +`{ + "Model": "gpt-4-turbo-preview", + "InternalSystemPrompt": null, + "Tools": [ + { + "function": { + "name": "test", + "parameters": null + } + }, + { + "function": { + "name": "local", + "parameters": null + } + } + ], + "Messages": [ + { + "role": "system", + "content": [ + { + "text": "noop" + } + ] + }, + { + "role": "assistant", + "content": [ + { + "toolCall": { + "index": 0, + "id": "call_1", + "function": { + "name": "test" + } + } + } + ] + }, + { + "role": "tool", + "content": [ + { + "text": "sub\nsub" + } + ], + "toolCall": { + "index": 0, + "id": "call_1", + "function": { + "name": "test" + } + } + }, + { + "role": "assistant", + "content": [ + { + "toolCall": { + "index": 1, + "id": "call_2", + "function": { + "name": "local" + } + } + } + ] + }, + { + "role": "tool", + "content": [ + { + "text": "/testdata/TestCwd\nthe data" + } + ], + "toolCall": { + "index": 1, + "id": "call_2", + "function": { + "name": "local" + } + } + } + ], + "MaxTokens": 0, + "Temperature": null, + "JSONResponse": false, + "Grammar": "", + "Cache": null +}` diff --git a/pkg/tests/testdata/TestCwd/call1.golden b/pkg/tests/testdata/TestCwd/call1.golden new file mode 100644 index 00000000..68e2851e --- /dev/null +++ b/pkg/tests/testdata/TestCwd/call1.golden @@ -0,0 +1,33 @@ +`{ + "Model": "gpt-4-turbo-preview", + "InternalSystemPrompt": null, + "Tools": [ + { + "function": { + "name": "test", + "parameters": null + } + }, + { + "function": { + "name": "local", + "parameters": null + } + } + ], + "Messages": [ + { + "role": "system", + "content": [ + { + "text": "noop" + } + ] + } + ], + "MaxTokens": 0, + "Temperature": null, + "JSONResponse": false, + "Grammar": "", + "Cache": null +}` diff --git a/pkg/tests/testdata/TestCwd/call2.golden b/pkg/tests/testdata/TestCwd/call2.golden new file mode 100644 index 00000000..6ab85bd2 --- /dev/null +++ b/pkg/tests/testdata/TestCwd/call2.golden @@ -0,0 +1,62 @@ +`{ + "Model": "gpt-4-turbo-preview", + "InternalSystemPrompt": null, + "Tools": [ + { + "function": { + "name": "test", + "parameters": null + } + }, + { + "function": { + "name": "local", + "parameters": null + } + } + ], + "Messages": [ + { + "role": "system", + "content": [ + { + "text": "noop" + } + ] + }, + { + "role": "assistant", + "content": [ + { + "toolCall": { + "index": 0, + "id": "call_1", + "function": { + "name": "test" + } + } + } + ] + }, + { + "role": "tool", + "content": [ + { + "text": "sub\nsub" + } + ], + "toolCall": { + "index": 0, + "id": "call_1", + "function": { + "name": "test" + } + } + } + ], + "MaxTokens": 0, + "Temperature": null, + "JSONResponse": false, + "Grammar": "", + "Cache": null +}` diff --git a/pkg/tests/testdata/TestCwd/call3.golden b/pkg/tests/testdata/TestCwd/call3.golden new file mode 100644 index 00000000..f564ec3f --- /dev/null +++ b/pkg/tests/testdata/TestCwd/call3.golden @@ -0,0 +1,91 @@ +`{ + "Model": "gpt-4-turbo-preview", + "InternalSystemPrompt": null, + "Tools": [ + { + "function": { + "name": "test", + "parameters": null + } + }, + { + "function": { + "name": "local", + "parameters": null + } + } + ], + "Messages": [ + { + "role": "system", + "content": [ + { + "text": "noop" + } + ] + }, + { + "role": "assistant", + "content": [ + { + "toolCall": { + "index": 0, + "id": "call_1", + "function": { + "name": "test" + } + } + } + ] + }, + { + "role": "tool", + "content": [ + { + "text": "sub\nsub" + } + ], + "toolCall": { + "index": 0, + "id": "call_1", + "function": { + "name": "test" + } + } + }, + { + "role": "assistant", + "content": [ + { + "toolCall": { + "index": 1, + "id": "call_2", + "function": { + "name": "local" + } + } + } + ] + }, + { + "role": "tool", + "content": [ + { + "text": "/testdata/TestCwd\nthe data" + } + ], + "toolCall": { + "index": 1, + "id": "call_2", + "function": { + "name": "local" + } + } + } + ], + "MaxTokens": 0, + "Temperature": null, + "JSONResponse": false, + "Grammar": "", + "Cache": null +}` diff --git a/pkg/tests/testdata/TestCwd/data.txt b/pkg/tests/testdata/TestCwd/data.txt new file mode 100644 index 00000000..17f0a400 --- /dev/null +++ b/pkg/tests/testdata/TestCwd/data.txt @@ -0,0 +1 @@ +the data \ No newline at end of file diff --git a/pkg/tests/testdata/TestCwd/subtool/sub.txt b/pkg/tests/testdata/TestCwd/subtool/sub.txt new file mode 100644 index 00000000..3de0f365 --- /dev/null +++ b/pkg/tests/testdata/TestCwd/subtool/sub.txt @@ -0,0 +1 @@ +sub \ No newline at end of file diff --git a/pkg/tests/testdata/TestCwd/subtool/test.gpt b/pkg/tests/testdata/TestCwd/subtool/test.gpt new file mode 100644 index 00000000..43bd9f40 --- /dev/null +++ b/pkg/tests/testdata/TestCwd/subtool/test.gpt @@ -0,0 +1,6 @@ +# +#!/bin/bash +set -e -x + +echo sub +cat sub.txt \ No newline at end of file diff --git a/pkg/tests/testdata/TestCwd/test.gpt b/pkg/tests/testdata/TestCwd/test.gpt new file mode 100644 index 00000000..2d3460bc --- /dev/null +++ b/pkg/tests/testdata/TestCwd/test.gpt @@ -0,0 +1,13 @@ +tools: ./subtool/test.gpt, local + +noop + +--- +name: local + +#!/bin/bash +set -e -x + +P=$(pwd) +echo ${P##${GPTSCRIPT_VAR_WORKDIR}} +cat data.txt \ No newline at end of file diff --git a/pkg/tests/tester/runner.go b/pkg/tests/tester/runner.go new file mode 100644 index 00000000..0d997543 --- /dev/null +++ b/pkg/tests/tester/runner.go @@ -0,0 +1,130 @@ +package tester + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/gptscript-ai/gptscript/pkg/loader" + "github.com/gptscript-ai/gptscript/pkg/runner" + "github.com/gptscript-ai/gptscript/pkg/types" + "github.com/hexops/autogold/v2" + "github.com/stretchr/testify/require" +) + +type Client struct { + t *testing.T + id int + result []Result +} + +type Result struct { + Text string + Func types.CompletionFunctionCall + Err error +} + +func (c *Client) Call(_ context.Context, messageRequest types.CompletionRequest, _ chan<- types.CompletionStatus) (*types.CompletionMessage, error) { + msgData, err := json.MarshalIndent(messageRequest, "", " ") + require.NoError(c.t, err) + + c.id++ + if c.id == 0 { + autogold.ExpectFile(c.t, string(msgData)) + } else { + c.t.Run(fmt.Sprintf("call%d", c.id), func(t *testing.T) { + autogold.ExpectFile(t, string(msgData)) + }) + } + if len(c.result) == 0 { + return &types.CompletionMessage{ + Role: types.CompletionMessageRoleTypeAssistant, + Content: types.Text(fmt.Sprintf("TEST RESULT CALL: %d", c.id)), + }, nil + } + + result := c.result[0] + c.result = c.result[1:] + + if result.Err != nil { + return nil, result.Err + } + + for i, tool := range messageRequest.Tools { + name := loader.ToolNormalizer(result.Func.Name) + if tool.Function.Name == name { + return &types.CompletionMessage{ + Role: types.CompletionMessageRoleTypeAssistant, + Content: []types.ContentPart{ + { + ToolCall: &types.CompletionToolCall{ + Index: &i, + ID: fmt.Sprintf("call_%d", c.id), + Function: types.CompletionFunctionCall{ + Name: tool.Function.Name, + Arguments: result.Func.Arguments, + }, + }, + }, + }, + }, nil + } + } + + if result.Func.Name != "" { + c.t.Fatalf("failed to find tool %s, normalized as %s", result.Func.Name, loader.ToolNormalizer(result.Func.Name)) + } + + return &types.CompletionMessage{ + Role: types.CompletionMessageRoleTypeAssistant, + Content: types.Text(result.Text), + }, nil +} + +type Runner struct { + *runner.Runner + + Client *Client +} + +func (r *Runner) RunDefault() string { + r.Client.t.Helper() + result, err := r.Run("", "") + require.NoError(r.Client.t, err) + return result +} + +func (r *Runner) Run(script, input string) (string, error) { + if script == "" { + script = "test.gpt" + } + prg, err := loader.Program(context.Background(), filepath.Join(".", "testdata", r.Client.t.Name(), script), "") + if err != nil { + return "", err + } + + return r.Runner.Run(context.Background(), prg, os.Environ(), input) +} + +func (r *Runner) RespondWith(result ...Result) { + r.Client.result = append(r.Client.result, result...) +} + +func NewRunner(t *testing.T) *Runner { + t.Helper() + + c := &Client{ + t: t, + } + + run, err := runner.New(c) + require.NoError(t, err) + + return &Runner{ + Runner: run, + Client: c, + } +} diff --git a/pkg/types/tool.go b/pkg/types/tool.go index c6d76713..5cf581a6 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -45,6 +45,7 @@ type Tool struct { LocalTools map[string]string `json:"localTools,omitempty"` BuiltinFunc BuiltinFunc `json:"-"` Source ToolSource `json:"source,omitempty"` + WorkingDir string `json:"workingDir,omitempty"` } func (t Tool) String() string { From 51826f560b4faf4e1156f0826dae0464258d2746 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 29 Feb 2024 18:04:03 -0700 Subject: [PATCH 137/774] Don't set the working dir of tools, require tools use GPTSCRIPT_TOOL_DIR --- pkg/engine/cmd.go | 14 ++++++------ pkg/engine/http.go | 12 +++-------- pkg/runner/log.go | 5 ----- pkg/runner/runner.go | 24 ++++----------------- pkg/tests/testdata/TestCwd/call3.golden | 2 +- pkg/tests/testdata/TestCwd/subtool/test.gpt | 4 +++- pkg/tests/testdata/TestCwd/test.gpt | 4 +++- 7 files changed, 20 insertions(+), 45 deletions(-) delete mode 100644 pkg/runner/log.go diff --git a/pkg/engine/cmd.go b/pkg/engine/cmd.go index 4cc956eb..a00d8856 100644 --- a/pkg/engine/cmd.go +++ b/pkg/engine/cmd.go @@ -40,7 +40,12 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) return tool.BuiltinFunc(ctx, e.Env, input) } - cmd, stop, err := e.newCommand(ctx, nil, tool.Instructions, input) + var extraEnv []string + if tool.WorkingDir != "" { + extraEnv = append(extraEnv, "GPTSCRIPT_TOOL_DIR="+tool.WorkingDir) + } + + cmd, stop, err := e.newCommand(ctx, extraEnv, tool.Instructions, input) if err != nil { return "", err } @@ -59,9 +64,6 @@ func (e *Engine) runCommand(ctx context.Context, tool types.Tool, input string) cmd.Stdin = strings.NewReader(input) cmd.Stderr = io.MultiWriter(all, os.Stderr) cmd.Stdout = io.MultiWriter(all, output) - if tool.WorkingDir != "" { - cmd.Dir = tool.WorkingDir - } if err := cmd.Run(); err != nil { _, _ = os.Stderr.Write(output.Bytes()) @@ -82,10 +84,6 @@ func (e *Engine) newCommand(ctx context.Context, extraEnv []string, instructions envMap := map[string]string{} for _, env := range env { key, value, _ := strings.Cut(env, "=") - key, ok := strings.CutPrefix(key, "GPTSCRIPT_VAR_") - if !ok { - continue - } envMap[key] = value } diff --git a/pkg/engine/http.go b/pkg/engine/http.go index c48838c5..0ff30cb7 100644 --- a/pkg/engine/http.go +++ b/pkg/engine/http.go @@ -17,12 +17,10 @@ const DaemonURLSuffix = ".daemon.gpt.local" func (e *Engine) runHTTP(ctx context.Context, prg *types.Program, tool types.Tool, input string) (cmdRet *Return, cmdErr error) { envMap := map[string]string{} + for _, env := range e.Env { - v, ok := strings.CutPrefix(env, "GPTSCRIPT_VAR_") - if ok { - k, v, _ := strings.Cut(v, "=") - envMap[k] = v - } + k, v, _ := strings.Cut(env, "=") + envMap[k] = v } toolURL := strings.Split(tool.Instructions, "\n")[0][2:] @@ -64,10 +62,6 @@ func (e *Engine) runHTTP(ctx context.Context, prg *types.Program, tool types.Too req.Header.Set("X-GPTScript-Tool-Name", tool.Parameters.Name) - for k, v := range envMap { - req.Header.Set("X-GPTScript-Var-"+k, v) - } - if err := json.Unmarshal([]byte(input), &map[string]any{}); err == nil { req.Header.Set("Content-Type", "application/json") } else { diff --git a/pkg/runner/log.go b/pkg/runner/log.go deleted file mode 100644 index 72772a6c..00000000 --- a/pkg/runner/log.go +++ /dev/null @@ -1,5 +0,0 @@ -package runner - -import "github.com/gptscript-ai/gptscript/pkg/mvl" - -var log = mvl.Package() diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index fa2f9571..7c55ccba 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -2,7 +2,6 @@ package runner import ( "context" - "os" "sync" "time" @@ -21,41 +20,30 @@ type Monitor interface { } type Options struct { - WorkingDir string MonitorFactory MonitorFactory `usage:"-"` } func complete(opts ...Options) (result Options) { for _, opt := range opts { - result.WorkingDir = types.FirstSet(opt.WorkingDir, result.WorkingDir) result.MonitorFactory = types.FirstSet(opt.MonitorFactory, result.MonitorFactory) } if result.MonitorFactory == nil { result.MonitorFactory = noopFactory{} } - if result.WorkingDir == "" { - var err error - result.WorkingDir, err = os.Getwd() - if err != nil { - log.Fatalf("failed to determine current working directory: %v", err) - } - } return } type Runner struct { - c engine.Model - factory MonitorFactory - workingDir string + c engine.Model + factory MonitorFactory } func New(client engine.Model, opts ...Options) (*Runner, error) { opt := complete(opts...) return &Runner{ - c: client, - factory: opt.MonitorFactory, - workingDir: opt.WorkingDir, + c: client, + factory: opt.MonitorFactory, }, nil } @@ -106,10 +94,6 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp Env: env, } - if r.workingDir != "" { - e.Env = append(e.Env, "GPTSCRIPT_VAR_WORKDIR="+r.workingDir) - } - monitor.Event(Event{ Time: time.Now(), CallContext: &callCtx, diff --git a/pkg/tests/testdata/TestCwd/call3.golden b/pkg/tests/testdata/TestCwd/call3.golden index f564ec3f..8116fbc0 100644 --- a/pkg/tests/testdata/TestCwd/call3.golden +++ b/pkg/tests/testdata/TestCwd/call3.golden @@ -71,7 +71,7 @@ "role": "tool", "content": [ { - "text": "/testdata/TestCwd\nthe data" + "text": "testdata/TestCwd\nthe data" } ], "toolCall": { diff --git a/pkg/tests/testdata/TestCwd/subtool/test.gpt b/pkg/tests/testdata/TestCwd/subtool/test.gpt index 43bd9f40..41314bbe 100644 --- a/pkg/tests/testdata/TestCwd/subtool/test.gpt +++ b/pkg/tests/testdata/TestCwd/subtool/test.gpt @@ -1,6 +1,8 @@ # -#!/bin/bash +#!/usr/bin/env X=${GPTSCRIPT_TOOL_DIR} /bin/bash set -e -x +[ ${X} = ${GPTSCRIPT_TOOL_DIR} ] +cd $X echo sub cat sub.txt \ No newline at end of file diff --git a/pkg/tests/testdata/TestCwd/test.gpt b/pkg/tests/testdata/TestCwd/test.gpt index 2d3460bc..5185635a 100644 --- a/pkg/tests/testdata/TestCwd/test.gpt +++ b/pkg/tests/testdata/TestCwd/test.gpt @@ -8,6 +8,8 @@ name: local #!/bin/bash set -e -x +[ "" = "${TOOL_DIR}" ] P=$(pwd) -echo ${P##${GPTSCRIPT_VAR_WORKDIR}} +echo ${GPTSCRIPT_TOOL_DIR##${P}} +cd $GPTSCRIPT_TOOL_DIR cat data.txt \ No newline at end of file From bc3bf84236fb9c00b45a02eb72d03e517f69eb72 Mon Sep 17 00:00:00 2001 From: Daishan Peng Date: Thu, 29 Feb 2024 18:28:37 -0700 Subject: [PATCH 138/774] Add browser tool usecase doc Signed-off-by: Daishan Peng --- docs/README-USECASES.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/README-USECASES.md b/docs/README-USECASES.md index ff848ae0..bced7ed2 100644 --- a/docs/README-USECASES.md +++ b/docs/README-USECASES.md @@ -42,7 +42,30 @@ Here is a GPTScript that produces a detailed travel itenirary based on inputs fr ### Web UI Automation -Here is a GPTScript that automates data gathering and analysis of web sites by interacting with a chrome web browser. [Link to example here] +GPTScript enables the automation of data collection and analysis from websites through seamless interaction with a Chrome web browser. Here's an example to illustrate how it works: + +1. Please install the browsing tool and configure it to operate continuously in the background as a service. + +```sh +git clone https://github.com/gptscript-ai/browser + +cd browser + +npm install + +npm run server +``` + +2. Let's explore a brief example on how to navigate through the Coachella Festival offerings and retrieve ticketing details + +```sh +# Go to the browser repo you just cloned +cd browser + +gpscript ./example/coachella-browse.gpt +``` + +For additional examples, please explore [here](https://github.com/gptscript-ai/browser?tab=readme-ov-file#examples). ### CLI Automation From a3cbbbad05143168b1b753e8f4cef5de9772a22f Mon Sep 17 00:00:00 2001 From: tylerslaton Date: Thu, 29 Feb 2024 11:16:10 -0500 Subject: [PATCH 139/774] docs: separate shell command from output in examples Signed-off-by: tylerslaton --- README.md | 10 ++++++---- docs/docs/01-overview.md | 4 ++-- docs/docs/100-tools/100-tools.md | 5 +++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 99a19a6f..73ab9a78 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,10 @@ Form and run a SQL query to find the artist with the most number of albums and o the result of that. When done remove the database file and the downloaded content. +```shell +$ gptscript ./example.gpt ``` ``` -$ gptscript ./example.gpt - OUTPUT: The artist with the most number of albums in the database is Iron Maiden, with a total @@ -89,7 +89,8 @@ $env:OPENAI = 'your-api-key' ```shell gptscript https://get.gptscript.ai/echo.gpt --input 'Hello, World!' - +``` +``` OUTPUT: Hello, World! @@ -134,7 +135,8 @@ When asked how I am doing, respond with "Thanks for asking "${question}", I'm do Put the above content in a file named `bob.gpt` and run the following command: ```shell $ gptscript bob.gpt - +``` +``` OUTPUT: Bob said, "Thanks for asking 'How are you doing?', I'm doing great fellow friendly AI tool!" diff --git a/docs/docs/01-overview.md b/docs/docs/01-overview.md index e5893170..b923790a 100644 --- a/docs/docs/01-overview.md +++ b/docs/docs/01-overview.md @@ -26,10 +26,10 @@ Form and run a SQL query to find the artist with the most number of albums and o the result of that. When done remove the database file and the downloaded content. +```shell +$ gptscript ./example.gpt ``` ``` -$ gptscript ./example.gpt - OUTPUT: The artist with the most number of albums in the database is Iron Maiden, with a total diff --git a/docs/docs/100-tools/100-tools.md b/docs/docs/100-tools/100-tools.md index e172cbff..111a0ace 100644 --- a/docs/docs/100-tools/100-tools.md +++ b/docs/docs/100-tools/100-tools.md @@ -23,9 +23,10 @@ When asked how I am doing, respond with "Thanks for asking "${question}", I'm do Put the above content in a file named `bob.gpt` and run the following command: -```sh +```shell $ gptscript bob.gpt - +``` +``` OUTPUT: Bob said, "Thanks for asking 'How are you doing?', I'm doing great fellow friendly AI tool!" From 99243ba97737b870fd71273ff65cbf974beb8497 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Fri, 1 Mar 2024 09:32:18 -0500 Subject: [PATCH 140/774] Update docs/docs/101-cookbook/vision.md Co-authored-by: Tyler Slaton <54378333+tylerslaton@users.noreply.github.com> Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- docs/docs/101-cookbook/vision.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/101-cookbook/vision.md b/docs/docs/101-cookbook/vision.md index 5b04d397..9d24a9ee 100644 --- a/docs/docs/101-cookbook/vision.md +++ b/docs/docs/101-cookbook/vision.md @@ -31,7 +31,7 @@ In this example, let's say that we want to create a `.gpt` script that uses visi ## Recap -In this example, we have created a GPTScript that leverages the `vision` tool to describe an image at a given URL. We gave it some flexibility by specifiying an argument `url` that the user can provide when running the script. We also specified gave the script a specific style to generate the description with. +In this example, we have created a GPTScript that leverages the `vision` tool to describe an image at a given URL. We gave it some flexibility by specifying an argument `url` that the user can provide when running the script. We also gave the script a specific style to generate the description with. Notable things to point out: From 227f0e22163f0153c69cdb1a34437df03a49b639 Mon Sep 17 00:00:00 2001 From: Donnie Adams Date: Tue, 27 Feb 2024 07:45:08 -0500 Subject: [PATCH 141/774] feat: add a few helper functions for using code outside of this package Signed-off-by: Donnie Adams --- pkg/mvl/log.go | 2 +- pkg/server/server.go | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/pkg/mvl/log.go b/pkg/mvl/log.go index a65aa7de..72f155cf 100644 --- a/pkg/mvl/log.go +++ b/pkg/mvl/log.go @@ -46,7 +46,7 @@ func SetError() { func Package() Logger { _, p, _, _ := runtime.Caller(1) - _, suffix, _ := strings.Cut(p, "gptscript/") + _, suffix, _ := strings.Cut(p, "gptscript") i := strings.LastIndex(suffix, "/") if i > 0 { return New(suffix[:i]) diff --git a/pkg/server/server.go b/pkg/server/server.go index 802164f0..e61b7dc7 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -45,9 +45,7 @@ func New(model engine.Model, opts ...Options) (*Server, error) { opt := complete(opts) r, err := runner.New(model, runner.Options{ - MonitorFactory: &SessionFactory{ - events: events, - }, + MonitorFactory: NewSessionFactory(events), }) if err != nil { return nil, err @@ -84,6 +82,14 @@ var ( type execKey struct{} +func ContextWithNewID(ctx context.Context) context.Context { + return context.WithValue(ctx, execKey{}, fmt.Sprint(atomic.AddInt64(&execID, 1))) +} + +func IDFromContext(ctx context.Context) string { + return ctx.Value(execKey{}).(string) +} + func (s *Server) list(rw http.ResponseWriter, req *http.Request) { rw.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(rw) @@ -276,6 +282,12 @@ type SessionFactory struct { events *broadcaster.Broadcaster[Event] } +func NewSessionFactory(events *broadcaster.Broadcaster[Event]) *SessionFactory { + return &SessionFactory{ + events: events, + } +} + func (s SessionFactory) Start(ctx context.Context, prg *types.Program, env []string, input string) (runner.Monitor, error) { id, _ := ctx.Value(execKey{}).(string) From bb5cbda17e742ce322137fd69d24acf5a2324f18 Mon Sep 17 00:00:00 2001 From: tylerslaton Date: Fri, 1 Mar 2024 14:35:52 -0500 Subject: [PATCH 142/774] fix: address typo issue with readme Signed-off-by: tylerslaton --- README.md | 1 + docs/docs/01-overview.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 73ab9a78..ec4631c5 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Form and run a SQL query to find the artist with the most number of albums and o the result of that. When done remove the database file and the downloaded content. +``` ```shell $ gptscript ./example.gpt ``` diff --git a/docs/docs/01-overview.md b/docs/docs/01-overview.md index b923790a..68f94afb 100644 --- a/docs/docs/01-overview.md +++ b/docs/docs/01-overview.md @@ -26,6 +26,7 @@ Form and run a SQL query to find the artist with the most number of albums and o the result of that. When done remove the database file and the downloaded content. +``` ```shell $ gptscript ./example.gpt ``` From 8c42da9db0297b92e73ca2f2615c513cf31907f6 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 1 Mar 2024 21:47:52 -0600 Subject: [PATCH 143/774] Add github metadata to internal data structures --- main.go | 3 + pkg/loader/github/github.go | 91 ++++++++++++++++++++++++++ pkg/loader/loader.go | 124 +++++++++++------------------------- pkg/loader/url.go | 88 +++++++++++++++++++++++++ pkg/loader/vcs/init.go | 6 ++ pkg/monitor/display.go | 2 +- pkg/server/server.go | 9 +-- pkg/system/prompt.go | 3 + pkg/types/tool.go | 6 +- 9 files changed, 238 insertions(+), 94 deletions(-) create mode 100644 pkg/loader/github/github.go create mode 100644 pkg/loader/url.go create mode 100644 pkg/loader/vcs/init.go diff --git a/main.go b/main.go index 3ac87972..597bf11a 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,9 @@ package main import ( "github.com/acorn-io/cmd" "github.com/gptscript-ai/gptscript/pkg/cli" + + // Load all VCS + _ "github.com/gptscript-ai/gptscript/pkg/loader/vcs" ) func main() { diff --git a/pkg/loader/github/github.go b/pkg/loader/github/github.go new file mode 100644 index 00000000..91f15ce0 --- /dev/null +++ b/pkg/loader/github/github.go @@ -0,0 +1,91 @@ +package github + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "path/filepath" + "strings" + + "github.com/gptscript-ai/gptscript/pkg/loader" + "github.com/gptscript-ai/gptscript/pkg/system" +) + +const ( + GithubPrefix = "github.com/" + githubRepoURL = "https://github.com/%s/%s.git" + githubDownloadURL = "https://raw.githubusercontent.com/%s/%s/%s/%s" + githubCommitURL = "https://api.github.com/repos/%s/%s/commits/%s" +) + +func init() { + loader.AddVSC(Load) +} + +func getCommit(account, repo, ref string) (string, error) { + url := fmt.Sprintf(githubCommitURL, account, repo, ref) + resp, err := http.Get(url) + if err != nil { + return "", err + } else if resp.StatusCode != http.StatusOK { + c, _ := io.ReadAll(resp.Body) + resp.Body.Close() + return "", fmt.Errorf("failed to GitHub commit of %s/%s at %s: %s %s", + account, repo, ref, resp.Status, c) + } + defer resp.Body.Close() + + var commit struct { + SHA string `json:"sha,omitempty"` + } + if err := json.NewDecoder(resp.Body).Decode(&commit); err != nil { + return "", fmt.Errorf("failed to decode GitHub commit of %s/%s at %s: %w", err) + } + + if commit.SHA == "" { + return "", fmt.Errorf("failed to find commit in response of %s, got empty string", url) + } + + return commit.SHA, nil +} + +func Load(urlName string) (string, *loader.Repo, bool, error) { + if !strings.HasPrefix(urlName, GithubPrefix) { + return "", nil, false, nil + } + + url, ref, _ := strings.Cut(urlName, "@") + if ref == "" { + ref = "HEAD" + } + + parts := strings.Split(url, "/") + // Must be at least 4 parts github.com/ACCOUNT/REPO/FILE + if len(parts) < 4 { + return "", nil, false, nil + } + + account, repo := parts[1], parts[2] + path := strings.Join(parts[3:], "/") + + if path == "" || path == "/" { + path = "tool.gpt" + } else if !strings.HasSuffix(path, system.Suffix) { + path += "/tool.gpt" + } + + ref, err := getCommit(account, repo, ref) + if err != nil { + return "", nil, false, err + } + + downloadURL := fmt.Sprintf(githubDownloadURL, account, repo, ref, path) + return downloadURL, &loader.Repo{ + VCS: "github", + Root: fmt.Sprintf(githubRepoURL, account, repo), + Path: filepath.Dir(path), + Name: filepath.Base(path), + Revision: ref, + }, true, nil +} diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 22856290..141b901b 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -11,8 +11,6 @@ import ( "fmt" "io" "io/fs" - "net/http" - url2 "net/url" "os" "path/filepath" "regexp" @@ -22,20 +20,37 @@ import ( "github.com/gptscript-ai/gptscript/pkg/builtin" "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/parser" + "github.com/gptscript-ai/gptscript/pkg/system" "github.com/gptscript-ai/gptscript/pkg/types" ) -const ( - GithubPrefix = "github.com/" - githubRawURL = "https://raw.githubusercontent.com/" -) - type source struct { + // Content The content of the source Content io.ReadCloser - Remote bool - Path string - Name string - File string + // Remote indicates that this file was loaded from a remote source (not local disk) + Remote bool + // Path is the path of this source used to find any relative references to this source + Path string + // Name is the filename of this source, it does not include the path in it + Name string + // Location is a string representation representing the source. It's not assume to + // be a valid URI or URL, used primarily for display. + Location string + // Repo The VCS repo where this tool was found, used to clone and provide the local tool code content + Repo *Repo +} + +type Repo struct { + // VCS The VCS type, such as "github" + VCS string + // The URL where the VCS repo can be found + Root string + // The path in the repo of this source. This should refer to a directory and not the actual file + Path string + // The filename of the source in the repo, relative to Path + Name string + // The revision of this source + Revision string } func (s *source) String() string { @@ -67,74 +82,11 @@ func loadLocal(base *source, name string) (*source, bool, error) { log.Debugf("opened %s", path) return &source{ - Content: content, - Remote: false, - Path: filepath.Dir(path), - Name: filepath.Base(path), - File: path, - }, true, nil -} - -func githubURL(urlName string) (string, bool) { - if !strings.HasPrefix(urlName, GithubPrefix) { - return "", false - } - - url, version, _ := strings.Cut(urlName, "@") - if version == "" { - version = "HEAD" - } - - parts := strings.Split(url, "/") - // Must be at least 4 parts github.com/ACCOUNT/REPO/FILE - if len(parts) < 4 { - return "", false - } - - url = githubRawURL + parts[1] + "/" + parts[2] + "/" + version + "/" + strings.Join(parts[3:], "/") - return url, true -} - -func loadURL(ctx context.Context, base *source, name string) (*source, bool, error) { - url := name - if base.Path != "" { - url = base.Path + "/" + name - } - if githubURL, ok := githubURL(url); ok { - url = githubURL - } - if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { - return nil, false, nil - } - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) - if err != nil { - return nil, false, err - } - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return nil, false, err - } else if resp.StatusCode != http.StatusOK { - return nil, false, fmt.Errorf("error loading %s: %s", url, resp.Status) - } - - log.Debugf("opened %s", url) - - parsed, err := url2.Parse(url) - if err != nil { - return nil, false, err - } - - pathURL := *parsed - pathURL.Path = filepath.Dir(parsed.Path) - - return &source{ - Content: resp.Body, - Remote: true, - Path: pathURL.String(), - Name: filepath.Base(parsed.Path), - File: url, + Content: content, + Remote: false, + Path: filepath.Dir(path), + Name: filepath.Base(path), + Location: path, }, true, nil } @@ -201,7 +153,7 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN for i, tool := range tools { tool.WorkingDir = base.Path - tool.Source.File = base.File + tool.Source.Location = base.Location // Probably a better way to come up with an ID tool.ID = tool.Source.String() @@ -211,7 +163,7 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN } if i != 0 && tool.Parameters.Name == "" { - return types.Tool{}, parser.NewErrLine(tool.Source.File, tool.Source.LineNo, fmt.Errorf("only the first tool in a file can have no name")) + return types.Tool{}, parser.NewErrLine(tool.Source.Location, tool.Source.LineNo, fmt.Errorf("only the first tool in a file can have no name")) } if targetToolName != "" && tool.Parameters.Name == targetToolName { @@ -219,8 +171,8 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN } if existing, ok := localTools[tool.Parameters.Name]; ok { - return types.Tool{}, parser.NewErrLine(tool.Source.File, tool.Source.LineNo, - fmt.Errorf("duplicate tool name [%s] in %s found at lines %d and %d", tool.Parameters.Name, tool.Source.File, + return types.Tool{}, parser.NewErrLine(tool.Source.Location, tool.Source.LineNo, + fmt.Errorf("duplicate tool name [%s] in %s found at lines %d and %d", tool.Parameters.Name, tool.Source.Location, tool.Source.LineNo, existing.Source.LineNo)) } @@ -238,7 +190,7 @@ var ( func ToolNormalizer(tool string) string { parts := strings.Split(tool, "/") tool = parts[len(parts)-1] - if strings.HasSuffix(tool, ".gpt") { + if strings.HasSuffix(tool, system.Suffix) { tool = strings.TrimSuffix(tool, filepath.Ext(tool)) } @@ -349,8 +301,8 @@ func ProgramFromSource(ctx context.Context, content, subToolName string) (types. ToolSet: types.ToolSet{}, } tool, err := readTool(ctx, &prg, &source{ - Content: io.NopCloser(strings.NewReader(content)), - File: "inline", + Content: io.NopCloser(strings.NewReader(content)), + Location: "inline", }, subToolName) if err != nil { return types.Program{}, err diff --git a/pkg/loader/url.go b/pkg/loader/url.go new file mode 100644 index 00000000..896d30ff --- /dev/null +++ b/pkg/loader/url.go @@ -0,0 +1,88 @@ +package loader + +import ( + "context" + "fmt" + "net/http" + url2 "net/url" + "path/filepath" + "strings" +) + +type VCSLookup func(string) (string, *Repo, bool, error) + +var vcsLookups []VCSLookup + +func AddVSC(lookup VCSLookup) { + vcsLookups = append(vcsLookups, lookup) +} + +func loadURL(ctx context.Context, base *source, name string) (*source, bool, error) { + var ( + repo *Repo + url = name + ) + + if base.Path != "" { + url = base.Path + "/" + name + } + + if base.Repo != nil { + newRepo := *base.Repo + newPath := filepath.Join(newRepo.Path, name) + newRepo.Path = filepath.Dir(newPath) + newRepo.Name = filepath.Base(newPath) + repo = &newRepo + } + + if repo == nil { + for _, vcs := range vcsLookups { + newURL, newRepo, ok, err := vcs(url) + if err != nil { + return nil, false, err + } else if ok { + repo = newRepo + url = newURL + break + } + } + } + + if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { + return nil, false, nil + } + + parsed, err := url2.Parse(url) + if err != nil { + return nil, false, err + } + + pathURL := *parsed + pathURL.Path = filepath.Dir(parsed.Path) + path := pathURL.String() + name = filepath.Base(parsed.Path) + url = path + "/" + name + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, false, err + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, false, err + } else if resp.StatusCode != http.StatusOK { + return nil, false, fmt.Errorf("error loading %s: %s", url, resp.Status) + } + + log.Debugf("opened %s", url) + + return &source{ + Content: resp.Body, + Remote: true, + Path: path, + Name: name, + Location: url, + Repo: repo, + }, true, nil +} diff --git a/pkg/loader/vcs/init.go b/pkg/loader/vcs/init.go new file mode 100644 index 00000000..4456b52d --- /dev/null +++ b/pkg/loader/vcs/init.go @@ -0,0 +1,6 @@ +package vcs + +import ( + // Load all VCS + _ "github.com/gptscript-ai/gptscript/pkg/loader/github" +) diff --git a/pkg/monitor/display.go b/pkg/monitor/display.go index cecebb72..c315633c 100644 --- a/pkg/monitor/display.go +++ b/pkg/monitor/display.go @@ -343,7 +343,7 @@ func (c callName) String() string { tool := c.prg.ToolSet[currentCall.ToolID] name := tool.Parameters.Name if name == "" { - name = tool.Source.File + name = tool.Source.Location } if currentCall.ID != "1" { name += "(" + c.prettyID + ")" diff --git a/pkg/server/server.go b/pkg/server/server.go index e61b7dc7..d24a8d06 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -20,6 +20,7 @@ import ( "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/loader" "github.com/gptscript-ai/gptscript/pkg/runner" + "github.com/gptscript-ai/gptscript/pkg/system" "github.com/gptscript-ai/gptscript/pkg/types" "github.com/gptscript-ai/gptscript/static" "github.com/olahol/melody" @@ -99,7 +100,7 @@ func (s *Server) list(rw http.ResponseWriter, req *http.Request) { if req.URL.Path == "/sys" { _ = enc.Encode(builtin.SysProgram()) return - } else if strings.HasSuffix(path, ".gpt") { + } else if strings.HasSuffix(path, system.Suffix) { prg, err := loader.Program(req.Context(), path, req.URL.Query().Get("tool")) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) @@ -121,7 +122,7 @@ func (s *Server) list(rw http.ResponseWriter, req *http.Request) { return nil } - if !d.IsDir() && strings.HasSuffix(d.Name(), ".gpt") { + if !d.IsDir() && strings.HasSuffix(d.Name(), system.Suffix) { result = append(result, path) } @@ -137,8 +138,8 @@ func (s *Server) list(rw http.ResponseWriter, req *http.Request) { func (s *Server) run(rw http.ResponseWriter, req *http.Request) { path := filepath.Join(".", req.URL.Path) - if !strings.HasSuffix(path, ".gpt") { - path += ".gpt" + if !strings.HasSuffix(path, system.Suffix) { + path += system.Suffix } prg, err := loader.Program(req.Context(), path, req.URL.Query().Get("tool")) diff --git a/pkg/system/prompt.go b/pkg/system/prompt.go index 4de97b85..4044092e 100644 --- a/pkg/system/prompt.go +++ b/pkg/system/prompt.go @@ -8,6 +8,9 @@ import ( "github.com/gptscript-ai/gptscript/pkg/types" ) +// Suffix is default suffix of gptscript files +const Suffix = ".gpt" + // InternalSystemPrompt is added to all threads. Changing this is very dangerous as it has a // terrible global effect and changes the behavior of all scripts. var InternalSystemPrompt = ` diff --git a/pkg/types/tool.go b/pkg/types/tool.go index 5cf581a6..3c4e6623 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -97,12 +97,12 @@ func (t Tool) String() string { } type ToolSource struct { - File string `json:"file,omitempty"` - LineNo int `json:"lineNo,omitempty"` + Location string `json:"location,omitempty"` + LineNo int `json:"lineNo,omitempty"` } func (t ToolSource) String() string { - return fmt.Sprintf("%s:%d", t.File, t.LineNo) + return fmt.Sprintf("%s:%d", t.Location, t.LineNo) } func (t Tool) IsCommand() bool { From b8a97bcd5fbead0c989e34e22eb3fb70d9f29772 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 1 Mar 2024 21:50:57 -0600 Subject: [PATCH 144/774] Print if it's a file or directory in stat call --- pkg/builtin/builtin.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index 62c526b5..bcdfce86 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -455,7 +455,11 @@ func SysStat(ctx context.Context, env []string, input string) (string, error) { return "", err } - return fmt.Sprintf("File %s mode: %s, size: %d bytes, modtime: %s", params.Filepath, stat.Mode().String(), stat.Size(), stat.ModTime().String()), nil + title := "File" + if stat.IsDir() { + title = "Directory" + } + return fmt.Sprintf("%s %s mode: %s, size: %d bytes, modtime: %s", title, params.Filepath, stat.Mode().String(), stat.Size(), stat.ModTime().String()), nil } func SysDownload(ctx context.Context, env []string, input string) (_ string, err error) { From 057ad681ab8e010226864a452372d7d1f280b9a7 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 1 Mar 2024 21:51:48 -0600 Subject: [PATCH 145/774] Print "No files found" in sys.find so LLM can handle empty case better --- pkg/builtin/builtin.go | 4 ++++ pkg/loader/github/github.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/builtin/builtin.go b/pkg/builtin/builtin.go index bcdfce86..027c3ed6 100644 --- a/pkg/builtin/builtin.go +++ b/pkg/builtin/builtin.go @@ -216,6 +216,10 @@ func SysFind(ctx context.Context, env []string, input string) (string, error) { if err != nil { return "", nil } + if len(result) == 0 { + return "No files found", nil + } + sort.Strings(result) return strings.Join(result, "\n"), nil } diff --git a/pkg/loader/github/github.go b/pkg/loader/github/github.go index 91f15ce0..9c52f819 100644 --- a/pkg/loader/github/github.go +++ b/pkg/loader/github/github.go @@ -40,7 +40,7 @@ func getCommit(account, repo, ref string) (string, error) { SHA string `json:"sha,omitempty"` } if err := json.NewDecoder(resp.Body).Decode(&commit); err != nil { - return "", fmt.Errorf("failed to decode GitHub commit of %s/%s at %s: %w", err) + return "", fmt.Errorf("failed to decode GitHub commit of %s/%s at %s: %w", account, repo, url, err) } if commit.SHA == "" { From 22b51716adecf4c2c78d0bea4dabd5937a8f29b2 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:28:19 -0500 Subject: [PATCH 146/774] chore: add releases to gitignore Add the releases directory to the .gitignore to prevent runtime/debug from detecting a modified source tree when built via goreleaser. Before this change, binaries built from tagged releases would return incorrect version info with a '-dirty' suffix. Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 73f4d464..c463dc84 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ **/package-lock.json **/__pycache__ /docs/yarn.lock +/releases +/checksums.txt From 8fcf6d2fd34215464087ac4c8f2e823b8db3092f Mon Sep 17 00:00:00 2001 From: Daishan Peng Date: Fri, 1 Mar 2024 11:00:57 -0700 Subject: [PATCH 147/774] Chore: Add ability to save state message from each gptscript call Signed-off-by: Daishan Peng --- go.mod | 3 +++ go.sum | 13 +++++++++++++ pkg/runner/runner.go | 29 +++++++++++++++++++++++++++++ scripts/upload-s3.gpt | 12 ++++++++++++ scripts/upload-s3.sh | 3 +++ 5 files changed, 60 insertions(+) create mode 100644 scripts/upload-s3.gpt create mode 100755 scripts/upload-s3.sh diff --git a/go.mod b/go.mod index 1d73035b..a187387d 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/stretchr/testify v1.8.4 golang.org/x/sync v0.6.0 golang.org/x/term v0.16.0 + google.golang.org/appengine v1.6.7 ) require ( @@ -26,6 +27,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.16.0 // indirect github.com/go-logr/logr v1.4.1 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect @@ -50,6 +52,7 @@ require ( golang.org/x/net v0.20.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/tools v0.17.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect mvdan.cc/gofumpt v0.6.0 // indirect diff --git a/go.sum b/go.sum index 4ad85942..d31fdc8f 100644 --- a/go.sum +++ b/go.sum @@ -26,7 +26,12 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -118,6 +123,7 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -152,6 +158,7 @@ golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -165,6 +172,12 @@ golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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/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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 7c55ccba..c4332322 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -2,12 +2,17 @@ package runner import ( "context" + "encoding/json" + "fmt" + "os" + "path/filepath" "sync" "time" "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/types" "golang.org/x/sync/errgroup" + "google.golang.org/appengine/log" ) type MonitorFactory interface { @@ -115,6 +120,9 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp Type: EventTypeCallFinish, Content: *result.Result, }) + if err := recordStateMessage(result.State); err != nil { + log.Warningf(callCtx.Ctx, "Failed to record state message: %v", err) + } return *result.Result, nil } @@ -218,3 +226,24 @@ func (r *Runner) subCalls(callCtx engine.Context, monitor Monitor, env []string, return } + +// recordStateMessage record the final state of the openai request and fetch messages and tools for analysis purpose +// The name follows `gptscript-state-${hostname}-${unixtimestamp}` +func recordStateMessage(state *engine.State) error { + if state == nil { + return nil + } + tmpdir := os.TempDir() + data, err := json.Marshal(state) + if err != nil { + return err + } + + hostname, err := os.Hostname() + if err != nil { + return err + } + + filename := filepath.Join(tmpdir, fmt.Sprintf("gptscript-state-%v-%v", hostname, time.Now().Unix())) + return os.WriteFile(filename, data, 0444) +} diff --git a/scripts/upload-s3.gpt b/scripts/upload-s3.gpt new file mode 100644 index 00000000..77a32f2f --- /dev/null +++ b/scripts/upload-s3.gpt @@ -0,0 +1,12 @@ +Tools: sys.exec, upload-s3 + +Find all files starts with `gptscript-state` in $TMPDIR, and upload the file to s3 bucket `gptscript-state`. Only find file from top-level folder. +Use filename to identify the file that is only uploaded within last week. + +--- +name: upload-s3 +description: upload all the file to s3 bucket +args: input: args to provide for aws s3 command + +aws s3 ${input} + diff --git a/scripts/upload-s3.sh b/scripts/upload-s3.sh new file mode 100755 index 00000000..eaa9a03b --- /dev/null +++ b/scripts/upload-s3.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +find $TMPDIR -maxdepth 1 -type f -name 'gptscript-state*' -mtime -7 | xargs -I{} aws s3 cp {} s3://gptscript-state/ From 067145393519f73d1a650b87b4eaedbff029de9e Mon Sep 17 00:00:00 2001 From: Hayden Barnes Date: Mon, 4 Mar 2024 16:30:13 -0500 Subject: [PATCH 148/774] Add Scoop install to README (#54) * Add Scoop install to README Signed-off-by: Hayden Barnes --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index ec4631c5..3a8a91e9 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,13 @@ brew install gptscript-ai/tap/gptscript curl https://get.gptscript.ai/install.sh | sh ``` +### Scoop (Windows) + +```shell +scoop bucket add extras # If 'extras' is not already enabled +scoop install gptscript +``` + #### WinGet (Windows) ```shell From 73bace161bf2ca05da567e93813a336326a092ed Mon Sep 17 00:00:00 2001 From: Daishan Peng Date: Mon, 4 Mar 2024 17:34:02 -0700 Subject: [PATCH 149/774] Fix: fix incorrect log package Signed-off-by: Daishan Peng --- go.mod | 3 --- go.sum | 13 ------------- pkg/runner/runner.go | 5 +++-- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index a187387d..1d73035b 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,6 @@ require ( github.com/stretchr/testify v1.8.4 golang.org/x/sync v0.6.0 golang.org/x/term v0.16.0 - google.golang.org/appengine v1.6.7 ) require ( @@ -27,7 +26,6 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.16.0 // indirect github.com/go-logr/logr v1.4.1 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect @@ -52,7 +50,6 @@ require ( golang.org/x/net v0.20.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/tools v0.17.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect mvdan.cc/gofumpt v0.6.0 // indirect diff --git a/go.sum b/go.sum index d31fdc8f..4ad85942 100644 --- a/go.sum +++ b/go.sum @@ -26,12 +26,7 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -123,7 +118,6 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -158,7 +152,6 @@ golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -172,12 +165,6 @@ golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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/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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index c4332322..10d536ef 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -11,8 +11,8 @@ import ( "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/types" + "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" - "google.golang.org/appengine/log" ) type MonitorFactory interface { @@ -121,7 +121,8 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp Content: *result.Result, }) if err := recordStateMessage(result.State); err != nil { - log.Warningf(callCtx.Ctx, "Failed to record state message: %v", err) + // Log a warning message if failed to record state message so that it doesn't affect the main process if state can't be recorded + logrus.Warningf("Failed to record state message: %v", err) } return *result.Result, nil } From 86f8f5c68f0828a20798757f6ddeaa0e54ec2d6a Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 1 Mar 2024 22:43:10 -0600 Subject: [PATCH 150/774] Add export parameter --- pkg/engine/engine.go | 102 ++++++++++++------ pkg/engine/toolname.go | 53 +++++++++ pkg/loader/loader.go | 108 +++++-------------- pkg/openai/client.go | 34 +++++- pkg/parser/parser.go | 4 +- pkg/runner/log.go | 5 + pkg/runner/runner.go | 10 +- pkg/tests/runner_test.go | 17 ++- pkg/tests/testdata/TestCwd/call1.golden | 2 + pkg/tests/testdata/TestCwd/call2.golden | 2 + pkg/tests/testdata/TestCwd/call3.golden | 2 + pkg/tests/testdata/TestExport/call1.golden | 84 +++++++++++++++ pkg/tests/testdata/TestExport/call2.golden | 11 ++ pkg/tests/testdata/TestExport/call3.golden | 114 ++++++++++++++++++++ pkg/tests/testdata/TestExport/parent.gpt | 8 ++ pkg/tests/testdata/TestExport/sub/child.gpt | 11 ++ pkg/tests/tester/runner.go | 5 +- pkg/types/completion.go | 1 + pkg/types/tool.go | 4 + 19 files changed, 449 insertions(+), 128 deletions(-) create mode 100644 pkg/engine/toolname.go create mode 100644 pkg/runner/log.go create mode 100644 pkg/tests/testdata/TestExport/call1.golden create mode 100644 pkg/tests/testdata/TestExport/call2.golden create mode 100644 pkg/tests/testdata/TestExport/call3.golden create mode 100644 pkg/tests/testdata/TestExport/parent.gpt create mode 100644 pkg/tests/testdata/TestExport/sub/child.gpt diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index b9ec8cb1..c8fc0e2c 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -45,21 +45,23 @@ type Return struct { } type Call struct { - ToolName string `json:"toolName,omitempty"` - Input string `json:"input,omitempty"` + ToolID string `json:"toolID,omitempty"` + Input string `json:"input,omitempty"` } type CallResult struct { - ID string `json:"id,omitempty"` + ToolID string `json:"toolID,omitempty"` + CallID string `json:"callID,omitempty"` Result string `json:"result,omitempty"` } type Context struct { - ID string - Ctx context.Context - Parent *Context - Program *types.Program - Tool types.Tool + ID string + Ctx context.Context + Parent *Context + Program *types.Program + Tool types.Tool + toolNames map[string]struct{} } func (c *Context) ParentID() string { @@ -97,10 +99,10 @@ func NewContext(ctx context.Context, prg *types.Program) Context { return callCtx } -func (c *Context) SubCall(ctx context.Context, toolName, callID string) (Context, error) { - tool, err := c.getTool(toolName) - if err != nil { - return Context{}, err +func (c *Context) SubCall(ctx context.Context, toolID, callID string) (Context, error) { + tool, ok := c.Program.ToolSet[toolID] + if !ok { + return Context{}, fmt.Errorf("failed to file tool for id [%s]", toolID) } return Context{ ID: callID, @@ -111,8 +113,8 @@ func (c *Context) SubCall(ctx context.Context, toolName, callID string) (Context }, nil } -func (c *Context) getTool(name string) (types.Tool, error) { - toolID, ok := c.Tool.ToolMapping[name] +func (c *Context) getTool(parent types.Tool, name string) (types.Tool, error) { + toolID, ok := parent.ToolMapping[name] if !ok { return types.Tool{}, &ErrToolNotFound{ ToolName: name, @@ -127,6 +129,45 @@ func (c *Context) getTool(name string) (types.Tool, error) { return tool, nil } +func (c *Context) appendTool(completion *types.CompletionRequest, parentTool types.Tool, subToolName string) error { + subTool, err := c.getTool(parentTool, subToolName) + if err != nil { + return err + } + + args := subTool.Parameters.Arguments + if args == nil && !subTool.IsCommand() { + args = &system.DefaultToolSchema + } + + for _, existingTool := range completion.Tools { + if existingTool.Function.ToolID == subTool.ID { + return nil + } + } + + if c.toolNames == nil { + c.toolNames = map[string]struct{}{} + } + + completion.Tools = append(completion.Tools, types.CompletionTool{ + Function: types.CompletionFunctionDefinition{ + ToolID: subTool.ID, + Name: PickToolName(subToolName, c.toolNames), + Description: subTool.Parameters.Description, + Parameters: args, + }, + }) + + for _, export := range subTool.Export { + if err := c.appendTool(completion, subTool, export); err != nil { + return err + } + } + + return nil +} + func (e *Engine) Start(ctx Context, input string) (*Return, error) { tool := ctx.Tool @@ -155,21 +196,9 @@ func (e *Engine) Start(ctx Context, input string) (*Return, error) { } for _, subToolName := range tool.Parameters.Tools { - subTool, err := ctx.getTool(subToolName) - if err != nil { + if err := ctx.appendTool(&completion, ctx.Tool, subToolName); err != nil { return nil, err } - args := subTool.Parameters.Arguments - if args == nil && !subTool.IsCommand() { - args = &system.DefaultToolSchema - } - completion.Tools = append(completion.Tools, types.CompletionTool{ - Function: types.CompletionFunctionDefinition{ - Name: subToolName, - Description: subTool.Parameters.Description, - Parameters: args, - }, - }) } if tool.Instructions != "" { @@ -225,10 +254,19 @@ func (e *Engine) complete(ctx context.Context, state *State) (*Return, error) { state.Pending = map[string]types.CompletionToolCall{} for _, content := range resp.Content { if content.ToolCall != nil { + var toolID string + for _, tool := range state.Completion.Tools { + if tool.Function.Name == content.ToolCall.Function.Name { + toolID = tool.Function.ToolID + } + } + if toolID == "" { + return nil, fmt.Errorf("failed to find tool id for tool %s in tool_call result", content.ToolCall.Function.Name) + } state.Pending[content.ToolCall.ID] = *content.ToolCall ret.Calls[content.ToolCall.ID] = Call{ - ToolName: content.ToolCall.Function.Name, - Input: content.ToolCall.Function.Arguments, + ToolID: toolID, + Input: content.ToolCall.Function.Arguments, } } else { cp := content.Text @@ -247,7 +285,7 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu } for _, result := range results { - state.Results[result.ID] = result + state.Results[result.CallID] = result } ret := Return{ @@ -262,8 +300,8 @@ func (e *Engine) Continue(ctx context.Context, state *State, results ...CallResu for id, pending := range state.Pending { if _, ok := state.Results[id]; !ok { ret.Calls[id] = Call{ - ToolName: pending.Function.Name, - Input: pending.Function.Arguments, + ToolID: state.Completion.Tools[*pending.Index].Function.ToolID, + Input: pending.Function.Arguments, } } } diff --git a/pkg/engine/toolname.go b/pkg/engine/toolname.go new file mode 100644 index 00000000..0887aad4 --- /dev/null +++ b/pkg/engine/toolname.go @@ -0,0 +1,53 @@ +package engine + +import ( + "crypto/md5" + "encoding/hex" + "path/filepath" + "regexp" + "strings" + + "github.com/gptscript-ai/gptscript/pkg/system" +) + +var ( + validToolName = regexp.MustCompile("^[a-zA-Z0-9_-]{1,64}$") + invalidChars = regexp.MustCompile("[^a-zA-Z0-9_-]+") +) + +func ToolNormalizer(tool string) string { + parts := strings.Split(tool, "/") + tool = parts[len(parts)-1] + if strings.HasSuffix(tool, system.Suffix) { + tool = strings.TrimSuffix(tool, filepath.Ext(tool)) + } + + if validToolName.MatchString(tool) { + return tool + } + + name := invalidChars.ReplaceAllString(tool, "-") + if len(name) > 55 { + name = name[:55] + } + + hash := md5.Sum([]byte(tool)) + hexed := hex.EncodeToString(hash[:]) + + return name + "-" + hexed[:8] +} + +func PickToolName(toolName string, existing map[string]struct{}) string { + if toolName == "" { + toolName = "external" + } + + for { + testName := ToolNormalizer(toolName) + if _, ok := existing[testName]; !ok { + existing[testName] = struct{}{} + return testName + } + toolName += "0" + } +} diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 141b901b..20edaca3 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -3,7 +3,6 @@ package loader import ( "bytes" "context" - "crypto/md5" "crypto/sha256" "encoding/hex" "encoding/json" @@ -13,14 +12,12 @@ import ( "io/fs" "os" "path/filepath" - "regexp" "strings" "github.com/gptscript-ai/gptscript/pkg/assemble" "github.com/gptscript-ai/gptscript/pkg/builtin" "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/parser" - "github.com/gptscript-ai/gptscript/pkg/system" "github.com/gptscript-ai/gptscript/pkg/types" ) @@ -182,48 +179,6 @@ func readTool(ctx context.Context, prg *types.Program, base *source, targetToolN return link(ctx, prg, base, mainTool, localTools) } -var ( - validToolName = regexp.MustCompile("^[a-zA-Z0-9_-]{1,64}$") - invalidChars = regexp.MustCompile("[^a-zA-Z0-9_-]+") -) - -func ToolNormalizer(tool string) string { - parts := strings.Split(tool, "/") - tool = parts[len(parts)-1] - if strings.HasSuffix(tool, system.Suffix) { - tool = strings.TrimSuffix(tool, filepath.Ext(tool)) - } - - if validToolName.MatchString(tool) { - return tool - } - - name := invalidChars.ReplaceAllString(tool, "-") - if len(name) > 55 { - name = name[:55] - } - - hash := md5.Sum([]byte(tool)) - hexed := hex.EncodeToString(hash[:]) - - return name + "-" + hexed[:8] -} - -func pickToolName(toolName string, existing map[string]struct{}) string { - if toolName == "" { - toolName = "external" - } - - for { - testName := ToolNormalizer(toolName) - if _, ok := existing[testName]; !ok { - existing[testName] = struct{}{} - return testName - } - toolName += "0" - } -} - func link(ctx context.Context, prg *types.Program, base *source, tool types.Tool, localTools types.ToolSet) (types.Tool, error) { if existing, ok := prg.ToolSet[tool.ID]; ok { return existing, nil @@ -240,50 +195,39 @@ func link(ctx context.Context, prg *types.Program, base *source, tool types.Tool // The below is done in two loops so that local names stay as the tool names // and don't get mangled by external references - for _, targetToolName := range tool.Parameters.Tools { + for _, targetToolName := range append(tool.Parameters.Tools, tool.Parameters.Export...) { localTool, ok := localTools[targetToolName] - if !ok { - continue - } + if ok { + var linkedTool types.Tool + if existing, ok := prg.ToolSet[localTool.ID]; ok { + linkedTool = existing + } else { + var err error + linkedTool, err = link(ctx, prg, base, localTool, localTools) + if err != nil { + return types.Tool{}, fmt.Errorf("failed linking %s at %s: %w", targetToolName, base, err) + } + } - var linkedTool types.Tool - if existing, ok := prg.ToolSet[localTool.ID]; ok { - linkedTool = existing + tool.ToolMapping[targetToolName] = linkedTool.ID + toolNames[targetToolName] = struct{}{} } else { - var err error - linkedTool, err = link(ctx, prg, base, localTool, localTools) - if err != nil { - return types.Tool{}, fmt.Errorf("failed linking %s at %s: %w", targetToolName, base, err) + subTool, toolName, ok := strings.Cut(targetToolName, " from ") + if ok { + toolName = strings.TrimSpace(toolName) + subTool = strings.TrimSpace(subTool) + } else { + toolName = targetToolName + subTool = "" } - } - - tool.ToolMapping[targetToolName] = linkedTool.ID - toolNames[targetToolName] = struct{}{} - } - - for i, targetToolName := range tool.Parameters.Tools { - _, ok := localTools[targetToolName] - if ok { - continue - } - subTool, toolName, ok := strings.Cut(targetToolName, " from ") - if ok { - toolName = strings.TrimSpace(toolName) - subTool = strings.TrimSpace(subTool) - } else { - toolName = targetToolName - subTool = "" - } + resolvedTool, err := resolve(ctx, prg, base, toolName, subTool) + if err != nil { + return types.Tool{}, fmt.Errorf("failed resolving %s at %s: %w", targetToolName, base, err) + } - resolvedTool, err := resolve(ctx, prg, base, toolName, subTool) - if err != nil { - return types.Tool{}, fmt.Errorf("failed resolving %s at %s: %w", targetToolName, base, err) + tool.ToolMapping[targetToolName] = resolvedTool.ID } - - newToolName := pickToolName(toolName, toolNames) - tool.ToolMapping[newToolName] = resolvedTool.ID - tool.Parameters.Tools[i] = newToolName } for _, localTool := range localTools { diff --git a/pkg/openai/client.go b/pkg/openai/client.go index 1590f29c..e6c246c3 100644 --- a/pkg/openai/client.go +++ b/pkg/openai/client.go @@ -9,6 +9,7 @@ import ( "io" "log/slog" "os" + "slices" "sort" "strings" "sync/atomic" @@ -188,14 +189,38 @@ func toToolCall(call types.CompletionToolCall) openai.ToolCall { } func toMessages(request types.CompletionRequest) (result []openai.ChatCompletionMessage, err error) { + var ( + systemPrompts []string + msgs []types.CompletionMessage + ) + if request.InternalSystemPrompt == nil || *request.InternalSystemPrompt { - result = append(result, openai.ChatCompletionMessage{ - Role: openai.ChatMessageRoleSystem, - Content: system.InternalSystemPrompt, + systemPrompts = append(systemPrompts, system.InternalSystemPrompt) + } + + for i, message := range request.Messages { + if message.Role == types.CompletionMessageRoleTypeSystem { + // Append if the next message is system or user, otherwise set as user message + if i == len(request.Messages)-1 || + (request.Messages[i].Role != types.CompletionMessageRoleTypeSystem && + request.Messages[i].Role != types.CompletionMessageRoleTypeUser) { + message.Role = types.CompletionMessageRoleTypeUser + } else { + systemPrompts = append(systemPrompts, message.Content[0].Text) + continue + } + } + msgs = append(msgs, message) + } + + if len(systemPrompts) > 0 { + msgs = slices.Insert(msgs, 0, types.CompletionMessage{ + Role: types.CompletionMessageRoleTypeSystem, + Content: types.Text(strings.Join(systemPrompts, "\n")), }) } - for _, message := range request.Messages { + for _, message := range msgs { chatMessage := openai.ChatCompletionMessage{ Role: string(message.Role), } @@ -230,6 +255,7 @@ func toMessages(request types.CompletionRequest) (result []openai.ChatCompletion result = append(result, chatMessage) } + return } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index a8274204..6466bece 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -90,6 +90,8 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { return false, err } tool.Parameters.InternalPrompt = &v + case "export": + tool.Parameters.Export = append(tool.Parameters.Export, csv(strings.ToLower(value))...) case "tools": tool.Parameters.Tools = append(tool.Parameters.Tools, csv(strings.ToLower(value))...) case "args": @@ -161,7 +163,7 @@ type context struct { func (c *context) finish(tools *[]types.Tool) { c.tool.Instructions = strings.TrimSpace(strings.Join(c.instructions, "")) - if c.tool.Instructions != "" || c.tool.Parameters.Name != "" { + if c.tool.Instructions != "" || c.tool.Parameters.Name != "" || len(c.tool.Export) > 0 || len(c.tool.Tools) > 0 { *tools = append(*tools, c.tool) } *c = context{} diff --git a/pkg/runner/log.go b/pkg/runner/log.go new file mode 100644 index 00000000..72772a6c --- /dev/null +++ b/pkg/runner/log.go @@ -0,0 +1,5 @@ +package runner + +import "github.com/gptscript-ai/gptscript/pkg/mvl" + +var log = mvl.Package() diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 10d536ef..2be8de02 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -11,7 +11,6 @@ import ( "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/types" - "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" ) @@ -121,8 +120,8 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp Content: *result.Result, }) if err := recordStateMessage(result.State); err != nil { - // Log a warning message if failed to record state message so that it doesn't affect the main process if state can't be recorded - logrus.Warningf("Failed to record state message: %v", err) + // Log a message if failed to record state message so that it doesn't affect the main process if state can't be recorded + log.Infof("Failed to record state message: %v", err) } return *result.Result, nil } @@ -200,7 +199,7 @@ func (r *Runner) subCalls(callCtx engine.Context, monitor Monitor, env []string, eg, subCtx := errgroup.WithContext(callCtx.Ctx) for id, call := range lastReturn.Calls { eg.Go(func() error { - callCtx, err := callCtx.SubCall(subCtx, call.ToolName, id) + callCtx, err := callCtx.SubCall(subCtx, call.ToolID, id) if err != nil { return err } @@ -213,7 +212,8 @@ func (r *Runner) subCalls(callCtx engine.Context, monitor Monitor, env []string, resultLock.Lock() defer resultLock.Unlock() callResults = append(callResults, engine.CallResult{ - ID: id, + ToolID: call.ToolID, + CallID: id, Result: result, }) diff --git a/pkg/tests/runner_test.go b/pkg/tests/runner_test.go index 6c82eae3..6e911977 100644 --- a/pkg/tests/runner_test.go +++ b/pkg/tests/runner_test.go @@ -3,9 +3,11 @@ package tests import ( "testing" + "github.com/gptscript-ai/gptscript/pkg/engine" "github.com/gptscript-ai/gptscript/pkg/tests/tester" "github.com/gptscript-ai/gptscript/pkg/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCwd(t *testing.T) { @@ -13,7 +15,7 @@ func TestCwd(t *testing.T) { runner.RespondWith(tester.Result{ Func: types.CompletionFunctionCall{ - Name: "subtool/test", + Name: engine.ToolNormalizer("./subtool/test.gpt"), }, }) runner.RespondWith(tester.Result{ @@ -24,3 +26,16 @@ func TestCwd(t *testing.T) { x := runner.RunDefault() assert.Equal(t, "TEST RESULT CALL: 3", x) } + +func TestExport(t *testing.T) { + runner := tester.NewRunner(t) + + runner.RespondWith(tester.Result{ + Func: types.CompletionFunctionCall{ + Name: "transient", + }, + }) + x, err := runner.Run("parent.gpt", "") + require.NoError(t, err) + assert.Equal(t, "TEST RESULT CALL: 3", x) +} diff --git a/pkg/tests/testdata/TestCwd/call1.golden b/pkg/tests/testdata/TestCwd/call1.golden index 68e2851e..d7fc990c 100644 --- a/pkg/tests/testdata/TestCwd/call1.golden +++ b/pkg/tests/testdata/TestCwd/call1.golden @@ -4,12 +4,14 @@ "Tools": [ { "function": { + "toolID": "testdata/TestCwd/subtool/test.gpt:1", "name": "test", "parameters": null } }, { "function": { + "toolID": "testdata/TestCwd/test.gpt:6", "name": "local", "parameters": null } diff --git a/pkg/tests/testdata/TestCwd/call2.golden b/pkg/tests/testdata/TestCwd/call2.golden index 6ab85bd2..b5832591 100644 --- a/pkg/tests/testdata/TestCwd/call2.golden +++ b/pkg/tests/testdata/TestCwd/call2.golden @@ -4,12 +4,14 @@ "Tools": [ { "function": { + "toolID": "testdata/TestCwd/subtool/test.gpt:1", "name": "test", "parameters": null } }, { "function": { + "toolID": "testdata/TestCwd/test.gpt:6", "name": "local", "parameters": null } diff --git a/pkg/tests/testdata/TestCwd/call3.golden b/pkg/tests/testdata/TestCwd/call3.golden index 8116fbc0..8d91f14b 100644 --- a/pkg/tests/testdata/TestCwd/call3.golden +++ b/pkg/tests/testdata/TestCwd/call3.golden @@ -4,12 +4,14 @@ "Tools": [ { "function": { + "toolID": "testdata/TestCwd/subtool/test.gpt:1", "name": "test", "parameters": null } }, { "function": { + "toolID": "testdata/TestCwd/test.gpt:6", "name": "local", "parameters": null } diff --git a/pkg/tests/testdata/TestExport/call1.golden b/pkg/tests/testdata/TestExport/call1.golden new file mode 100644 index 00000000..b1d0c9f0 --- /dev/null +++ b/pkg/tests/testdata/TestExport/call1.golden @@ -0,0 +1,84 @@ +`{ + "Model": "gpt-4-turbo-preview", + "InternalSystemPrompt": null, + "Tools": [ + { + "function": { + "toolID": "testdata/TestExport/parent.gpt:4", + "name": "frommain", + "parameters": { + "type": "object", + "properties": { + "defaultPromptParameter": { + "description": "Prompt to send to the tool or assistant. This may be instructions or question.", + "type": "string" + } + }, + "required": [ + "defaultPromptParameter" + ] + } + } + }, + { + "function": { + "toolID": "testdata/TestExport/parent.gpt:8", + "name": "parent-local", + "parameters": { + "type": "object", + "properties": { + "defaultPromptParameter": { + "description": "Prompt to send to the tool or assistant. This may be instructions or question.", + "type": "string" + } + }, + "required": [ + "defaultPromptParameter" + ] + } + } + }, + { + "function": { + "toolID": "testdata/TestExport/sub/child.gpt:4", + "name": "child", + "parameters": { + "type": "object", + "properties": { + "defaultPromptParameter": { + "description": "Prompt to send to the tool or assistant. This may be instructions or question.", + "type": "string" + } + }, + "required": [ + "defaultPromptParameter" + ] + } + } + }, + { + "function": { + "toolID": "testdata/TestExport/sub/child.gpt:8", + "name": "transient", + "parameters": { + "type": "object", + "properties": { + "defaultPromptParameter": { + "description": "Prompt to send to the tool or assistant. This may be instructions or question.", + "type": "string" + } + }, + "required": [ + "defaultPromptParameter" + ] + } + } + } + ], + "Messages": null, + "MaxTokens": 0, + "Temperature": null, + "JSONResponse": false, + "Grammar": "", + "Cache": null +}` diff --git a/pkg/tests/testdata/TestExport/call2.golden b/pkg/tests/testdata/TestExport/call2.golden new file mode 100644 index 00000000..babfc6da --- /dev/null +++ b/pkg/tests/testdata/TestExport/call2.golden @@ -0,0 +1,11 @@ +`{ + "Model": "gpt-4-turbo-preview", + "InternalSystemPrompt": null, + "Tools": null, + "Messages": null, + "MaxTokens": 0, + "Temperature": null, + "JSONResponse": false, + "Grammar": "", + "Cache": null +}` diff --git a/pkg/tests/testdata/TestExport/call3.golden b/pkg/tests/testdata/TestExport/call3.golden new file mode 100644 index 00000000..2ca34642 --- /dev/null +++ b/pkg/tests/testdata/TestExport/call3.golden @@ -0,0 +1,114 @@ +`{ + "Model": "gpt-4-turbo-preview", + "InternalSystemPrompt": null, + "Tools": [ + { + "function": { + "toolID": "testdata/TestExport/parent.gpt:4", + "name": "frommain", + "parameters": { + "type": "object", + "properties": { + "defaultPromptParameter": { + "description": "Prompt to send to the tool or assistant. This may be instructions or question.", + "type": "string" + } + }, + "required": [ + "defaultPromptParameter" + ] + } + } + }, + { + "function": { + "toolID": "testdata/TestExport/parent.gpt:8", + "name": "parent-local", + "parameters": { + "type": "object", + "properties": { + "defaultPromptParameter": { + "description": "Prompt to send to the tool or assistant. This may be instructions or question.", + "type": "string" + } + }, + "required": [ + "defaultPromptParameter" + ] + } + } + }, + { + "function": { + "toolID": "testdata/TestExport/sub/child.gpt:4", + "name": "child", + "parameters": { + "type": "object", + "properties": { + "defaultPromptParameter": { + "description": "Prompt to send to the tool or assistant. This may be instructions or question.", + "type": "string" + } + }, + "required": [ + "defaultPromptParameter" + ] + } + } + }, + { + "function": { + "toolID": "testdata/TestExport/sub/child.gpt:8", + "name": "transient", + "parameters": { + "type": "object", + "properties": { + "defaultPromptParameter": { + "description": "Prompt to send to the tool or assistant. This may be instructions or question.", + "type": "string" + } + }, + "required": [ + "defaultPromptParameter" + ] + } + } + } + ], + "Messages": [ + { + "role": "assistant", + "content": [ + { + "toolCall": { + "index": 3, + "id": "call_1", + "function": { + "name": "transient" + } + } + } + ] + }, + { + "role": "tool", + "content": [ + { + "text": "TEST RESULT CALL: 2" + } + ], + "toolCall": { + "index": 3, + "id": "call_1", + "function": { + "name": "transient" + } + } + } + ], + "MaxTokens": 0, + "Temperature": null, + "JSONResponse": false, + "Grammar": "", + "Cache": null +}` diff --git a/pkg/tests/testdata/TestExport/parent.gpt b/pkg/tests/testdata/TestExport/parent.gpt new file mode 100644 index 00000000..212b8cf2 --- /dev/null +++ b/pkg/tests/testdata/TestExport/parent.gpt @@ -0,0 +1,8 @@ +tools: frommain, sub/child.gpt + +--- +name: frommain +export: parent-local, fromchild from sub/child.gpt + +--- +name: parent-local diff --git a/pkg/tests/testdata/TestExport/sub/child.gpt b/pkg/tests/testdata/TestExport/sub/child.gpt new file mode 100644 index 00000000..2f591ace --- /dev/null +++ b/pkg/tests/testdata/TestExport/sub/child.gpt @@ -0,0 +1,11 @@ + + +--- +name: fromchild +export: transient + +--- +name: transient + +--- +name: miss diff --git a/pkg/tests/tester/runner.go b/pkg/tests/tester/runner.go index 0d997543..06f170d8 100644 --- a/pkg/tests/tester/runner.go +++ b/pkg/tests/tester/runner.go @@ -54,8 +54,7 @@ func (c *Client) Call(_ context.Context, messageRequest types.CompletionRequest, } for i, tool := range messageRequest.Tools { - name := loader.ToolNormalizer(result.Func.Name) - if tool.Function.Name == name { + if tool.Function.Name == result.Func.Name { return &types.CompletionMessage{ Role: types.CompletionMessageRoleTypeAssistant, Content: []types.ContentPart{ @@ -75,7 +74,7 @@ func (c *Client) Call(_ context.Context, messageRequest types.CompletionRequest, } if result.Func.Name != "" { - c.t.Fatalf("failed to find tool %s, normalized as %s", result.Func.Name, loader.ToolNormalizer(result.Func.Name)) + c.t.Fatalf("failed to find tool %s", result.Func.Name) } return &types.CompletionMessage{ diff --git a/pkg/types/completion.go b/pkg/types/completion.go index 7d7d927e..b78a1aa4 100644 --- a/pkg/types/completion.go +++ b/pkg/types/completion.go @@ -22,6 +22,7 @@ type CompletionTool struct { } type CompletionFunctionDefinition struct { + ToolID string `json:"toolID,omitempty"` Name string `json:"name"` Description string `json:"description,omitempty"` Domain string `json:"domain,omitempty"` diff --git a/pkg/types/tool.go b/pkg/types/tool.go index 3c4e6623..a0f1143a 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -34,6 +34,7 @@ type Parameters struct { InternalPrompt *bool `json:"internalPrompt"` Arguments *JSONSchema `json:"arguments,omitempty"` Tools []string `json:"tools,omitempty"` + Export []string `json:"export,omitempty"` } type Tool struct { @@ -59,6 +60,9 @@ func (t Tool) String() string { if len(t.Parameters.Tools) != 0 { _, _ = fmt.Fprintf(buf, "Tools: %s\n", strings.Join(t.Parameters.Tools, ", ")) } + if len(t.Parameters.Export) != 0 { + _, _ = fmt.Fprintf(buf, "Export: %s\n", strings.Join(t.Parameters.Export, ", ")) + } if t.Parameters.MaxTokens != 0 { _, _ = fmt.Fprintf(buf, "Max Tokens: %d\n", t.Parameters.MaxTokens) } From c1d4989ced010a9ee078159ac4929300cfd48c88 Mon Sep 17 00:00:00 2001 From: Tyler Slaton <54378333+tylerslaton@users.noreply.github.com> Date: Tue, 5 Mar 2024 10:18:16 -0500 Subject: [PATCH 151/774] docs: add story-book.gpt example (#99) * docs: add story-book example Signed-off-by: tylerslaton --- docs/README-USECASES.md | 5 +- examples/story-book/README.md | 34 +++++++ examples/story-book/index.html | 147 +++++++++++++++++++++++++++++ examples/story-book/story-book.gpt | 69 ++++++++++++++ 4 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 examples/story-book/README.md create mode 100644 examples/story-book/index.html create mode 100644 examples/story-book/story-book.gpt diff --git a/docs/README-USECASES.md b/docs/README-USECASES.md index bced7ed2..863d2682 100644 --- a/docs/README-USECASES.md +++ b/docs/README-USECASES.md @@ -102,9 +102,12 @@ Here is a GPTScript that summarizes the the code stored under the current direct ## Vision, Image, and Audio ### Vision + Here is an example of a web app that leverages GPTScript to recognize ingredients in a photo and suggest a recipe based on them: [recipe-generator](../examples/recipegenerator). -[More details to come] +### Image Generation + +Here is a GPTScript that takes a story prompt and generates an illustrated children's book: [story-book.gpt](../examples/story-book) ## Memory Management diff --git a/examples/story-book/README.md b/examples/story-book/README.md new file mode 100644 index 00000000..a30f4e68 --- /dev/null +++ b/examples/story-book/README.md @@ -0,0 +1,34 @@ +# Story Book + +Story Book is a GPTScript that can generate a story based on a prompt and the number of pages you want the story to be in. It is generated in HTML format and can then be viewed +by `index.html` which has some JS/CSS to make the story styling consistent and readable. + +## Usage Instructions + +1. **Install and bootstrap the `image-generation` tool.** + + This tool uses the `image-generation` tool, which is in a separate repository. To install and bootstrap the `image-generation` tool, starting at the root of `gptscript` run the following commands: + + > Note: We'll soon have package management that handles tools installation for you, but until then, you have to manually clone and boostrap tools. + + ```shell + cd .. # This assumes you're starting at the root of the gptscript project. We want image-generation to be a sibling of gptscript. + git clone https://github.com/gptscript-ai/image-generation + cd image-generation + make bootstrap + source .venv/bin/activate + cd - # returns you back to your original directory + ``` + +2. **Run the `story-book.gpt` script.** + + In the same terminal session where the virtual environment (venv) is now activated, navigate to the `story-book` example directory and run the `story-book.gpt` script: + + ```shell + cd examples/story-book + gptscript story-book.gpt --prompt "Goldilocks" --pages 3 + ``` + +3. **View the story.** + + Open `index.html` in your browser to view the generated story. diff --git a/examples/story-book/index.html b/examples/story-book/index.html new file mode 100644 index 00000000..e8bf7ebd --- /dev/null +++ b/examples/story-book/index.html @@ -0,0 +1,147 @@ + + + + Story Book + + + +

Story Book

+
+ +
+ + + + + + + \ No newline at end of file diff --git a/examples/story-book/story-book.gpt b/examples/story-book/story-book.gpt new file mode 100644 index 00000000..cc52cb77 --- /dev/null +++ b/examples/story-book/story-book.gpt @@ -0,0 +1,69 @@ +tools: story-writer, story-illustrator, mkdir, sys.write, sys.read, sys.download +description: Writes a children's book and generates illustrations for it. +args: story: The story to write and illustrate. Can be a prompt or a complete story. +args: pages: The number of pages to generate + +Do the following steps sequentially: + +1. Create the `pages` directory if it does not already exist. +2. If ${story} is a prompt and not a complete children's story, call story-writer + to write a story based on the prompt. +3. Take ${story} and break it up into ${pages} logical "pages" of text. +4. For each page: + - Call story-illustrator to illustrate it. Be sure to include any relevant characters to include when + asking it to illustrate the page. + - Download the illustration to a file at pages/.png. +5. For each page and its illustration write an html file with the text on top and image below it to pages/page.html. + Assume the illustration file is a sibling to the html file, Add this style tag to the HTML file: + ```html + + ``` +6. Edit the "pages" variable array in index.html to serve the pages you created. Do not + edit anything else. Do not edit the page select field. + +--- +name: story-writer +description: Writes a story for children +args: prompt: The prompt to use for the story + +Write a story with a tone for children based on ${prompt}. + +--- +name: story-illustrator +tools: ../../../image-generation/tool.gpt +description: Generates a illustration for a children's story +args: text: The text of the page to illustrate + +Think of a good prompt to generate an image to represent $text. Make sure to +include the name of any relevant characters in your prompt. Then use that prompt to +generate an illustration. Append any prompt that you have with ". In an pointilism cartoon +children's book style with no text in it". Only return the URL of the illustration. + +--- +name: mkdir +tools: sys.write +description: Creates a specified directory +args: dir: Path to the directory to be created + +#!bash + +mkdir ${dir} \ No newline at end of file From f039adce378b14d1dd350ea05c40340f8e181ec1 Mon Sep 17 00:00:00 2001 From: Bill Maxwell Date: Tue, 5 Mar 2024 08:26:11 -0700 Subject: [PATCH 152/774] add example nodejs and image generation example (#108) Signed-off-by: Bill Maxwell --- examples/nodejs-imagegen/README.md | 64 + examples/nodejs-imagegen/artists.json | 16 + examples/nodejs-imagegen/cli.py | 67 ++ examples/nodejs-imagegen/package-lock.json | 1224 ++++++++++++++++++++ examples/nodejs-imagegen/package.json | 20 + examples/nodejs-imagegen/public/index.html | 71 ++ examples/nodejs-imagegen/public/script.js | 130 +++ examples/nodejs-imagegen/requirements.txt | 3 + examples/nodejs-imagegen/server.js | 103 ++ examples/nodejs-imagegen/tool.gpt | 8 + 10 files changed, 1706 insertions(+) create mode 100644 examples/nodejs-imagegen/README.md create mode 100644 examples/nodejs-imagegen/artists.json create mode 100644 examples/nodejs-imagegen/cli.py create mode 100644 examples/nodejs-imagegen/package-lock.json create mode 100644 examples/nodejs-imagegen/package.json create mode 100644 examples/nodejs-imagegen/public/index.html create mode 100644 examples/nodejs-imagegen/public/script.js create mode 100644 examples/nodejs-imagegen/requirements.txt create mode 100644 examples/nodejs-imagegen/server.js create mode 100644 examples/nodejs-imagegen/tool.gpt diff --git a/examples/nodejs-imagegen/README.md b/examples/nodejs-imagegen/README.md new file mode 100644 index 00000000..3f2084a5 --- /dev/null +++ b/examples/nodejs-imagegen/README.md @@ -0,0 +1,64 @@ +# AI Logo Design (Nodejs image generation example) + +## Overview + +This nodejs app uses the gptscript node module and the image generation tool (leverages DALL-E) to create a simple AI logo design site. The app uses an existing three AI generated artists, or can create an additional set of three artists, to render a logo based on the description provided by the user. The resulting logo images are then presented to the user. + +## Features + +- Three built in AI artists. +- Ability to generate three additional AI artists. +- Provide a description of the logo to be generated. +- View three rendered logo options. + +## Installation + +1. Clone the repository. + +```bash +git clone https://github.com/gptscript-ai/gptscript.git +``` + +1. Navigate to the 'examples/nodejs-imagegen' directory and install dependencies. + +Python: + +*note: You can use a virtual environment to install the python dependencies, just make sure it is activated before running the server.* + +```bash +pip install -r requirements.txt +``` + +this will install the python dependencies for the image generation tool. + +Node: + +```bash +npm install +``` + +This is for the application itself. + +1. Setup OPENAI_API_KEY environment variable. + +```bash +export OPENAI_API_KEY=your-api-key +``` + +1. Run the application. + +```bash +npm run dev +``` + +## Usage + +Once the application is started, open in your browser. You will be presented with a form to enter a description of the logo you would like to generate. After submitting the form, you will be presented with three logo options. + +The backend models take a bit of time to render the images, so it might seem like the application is hanging. This is normal, and the images will be presented once they are ready. + +## Diving in + +The application is a simple nodejs app that uses the gptscript node module to interact with the image generation tool. The gptscript module is just running the CLI under the hood, and will pick up the standard configuration environment variables, the most important of which is the OPENAI_API_KEY. + +Sometimes the OpenAI LLM model will return an error, which can be seen in the terminal running the server app. Sometimes, the model will return a response that doesn't quite match the expected output format and throw an error. diff --git a/examples/nodejs-imagegen/artists.json b/examples/nodejs-imagegen/artists.json new file mode 100644 index 00000000..625362f6 --- /dev/null +++ b/examples/nodejs-imagegen/artists.json @@ -0,0 +1,16 @@ +{ + "artists": [ + { + "name": "Elena Vasquez", + "description": "Elena Vasquez, hailing from the vibrant streets of Buenos Aires, Argentina, is a graphic artist whose work is deeply influenced by the rich cultural heritage and bustling urban life of her homeland. Her art is a vivid tapestry of colors, blending traditional South American motifs with modern digital techniques. Elena's muse is the dynamic interplay of tradition and innovation, which she believes mirrors the evolving identity of Latin America. Her pieces often feature bold, geometric patterns interwoven with imagery from folklore and street art, creating a unique visual language that speaks to the heart of contemporary Latin American society." + }, + { + "name": "Taro Yamamoto", + "description": "Taro Yamamoto, a Tokyo-based graphic artist, draws inspiration from the minimalist aesthetics and profound philosophical concepts of traditional Japanese art. His work is characterized by its simplicity, elegance, and deep contemplation of nature and human existence. Taro's muse is the Zen concept of 'ma' (間) - the dynamic space between objects, which he interprets as the essence of life itself. By incorporating this philosophy into his digital creations, Taro seeks to evoke a sense of tranquility and introspection, inviting viewers to explore the invisible connections that bind the universe together." + }, + { + "name": "Ava Johnson", + "description": "Ava Johnson, from the bustling city of New York, is a graphic artist whose work is a reflection of the urban chaos and diversity that surrounds her. Her muse is the city itself - its towering skyscrapers, crowded streets, and the mosaic of cultures that define its identity. Ava's art is a dialogue between the concrete jungle and the human spirit, exploring themes of isolation, connection, and resilience. Through a mix of photography, digital manipulation, and traditional drawing, she captures the raw energy and complexity of urban life, creating pieces that are as multifaceted and dynamic as the city that inspires her." + } + ] +} \ No newline at end of file diff --git a/examples/nodejs-imagegen/cli.py b/examples/nodejs-imagegen/cli.py new file mode 100644 index 00000000..9f0fd7b3 --- /dev/null +++ b/examples/nodejs-imagegen/cli.py @@ -0,0 +1,67 @@ +import os +import sys +import argparse +import openai + +# Set up defaults and get API key from environment variable +defaults = { + "api_key": os.getenv('OPENAI_API_KEY'), + "model": "dall-e-3", + "size": "1024x1024", + "quality": "standard", + "number": "1", +} + +# Function to validate and parse arguments +def validate_and_parse_args(parser): + args = parser.parse_args() + + for key, value in vars(args).items(): + if not value: + args.__dict__[key] = parser.get_default(key) + + if not args.api_key: + parser.error('The --api-key argument is required if OPENAI_API_KEY environment variable is not set.') + if not args.prompt: + parser.error('The --prompt argument is required.') + if not args.number.isdigit(): + parser.error('The --number argument must be a number.') + args.number = int(args.number) + + return args + +def main(): + # Parse the command line arguments + parser = argparse.ArgumentParser(description="CLI for image generation prompt using OpenAI's DALL-E model.") + parser.add_argument('-k', '--api-key', type=str, default=defaults["api_key"], + help='OpenAI API key. Can also be set with OPENAI_API_KEY environment variable.') + parser.add_argument('-p', '--prompt', type=str, required=True, help='Prompt for image generation.') + parser.add_argument('-m', '--model', type=str, default=defaults["model"], + help=f'Model to use for image generation. Default is "{defaults["model"]}".') + parser.add_argument('-s', '--size', type=str, default=defaults["size"], + help=f'Size of the image to generate, format WxH (e.g. {defaults["size"]}). Default is {defaults["size"]}.') + parser.add_argument('-q', '--quality', type=str, default=defaults["quality"], + help=f'Quality of the generated image. Allowed values are "standard" or "hd". Default is "{defaults["quality"]}"') + parser.add_argument('-n', '--number', type=str, default=defaults["number"], + help='Number of images to generate. Default is 1.') + args = validate_and_parse_args(parser) + + # Initialize OpenAI client + client = openai.OpenAI(api_key=args.api_key) + + # Make request to the OpenAI API + try: + response = client.images.generate( + model=args.model, + prompt=args.prompt, + size=args.size, + quality=args.quality, + n=args.number + ) + print([image.url for image in response.data]) + except openai.OpenAIError as e: + print(f"Received an error code while generating images: {e}", file=sys.stderr) + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/examples/nodejs-imagegen/package-lock.json b/examples/nodejs-imagegen/package-lock.json new file mode 100644 index 00000000..11e91975 --- /dev/null +++ b/examples/nodejs-imagegen/package-lock.json @@ -0,0 +1,1224 @@ +{ + "name": "examples", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "examples", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@gptscript-ai/gptscript": "^0.1.2", + "express": "^4.18.3", + "express-ws": "^5.0.2", + "nodemon": "^3.1.0", + "ws": "^8.16.0" + } + }, + "node_modules/@gptscript-ai/gptscript": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@gptscript-ai/gptscript/-/gptscript-0.1.2.tgz", + "integrity": "sha512-SI1iifrcy+pl9vjMtq0Ez9sA639ftbmz+ehRjLS9tDTFlm/uhCXlDP1mzcq15O6Kwm9knHeJd9skcz7dxdNw+Q==", + "hasInstallScript": true, + "dependencies": { + "adm-zip": "^0.5.10", + "node-downloader-helper": "^2.1.9", + "tar": "^6.2.0" + }, + "bin": { + "gptscript": "bin/gptscript" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/adm-zip": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", + "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-ws": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz", + "integrity": "sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==", + "dependencies": { + "ws": "^7.4.6" + }, + "engines": { + "node": ">=4.5.0" + }, + "peerDependencies": { + "express": "^4.0.0 || ^5.0.0-alpha.1" + } + }, + "node_modules/express-ws/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-downloader-helper": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/node-downloader-helper/-/node-downloader-helper-2.1.9.tgz", + "integrity": "sha512-FSvAol2Z8UP191sZtsUZwHIN0eGoGue3uEXGdWIH5228e9KH1YHXT7fN8Oa33UGf+FbqGTQg3sJfrRGzmVCaJA==", + "bin": { + "ndh": "bin/ndh" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/nodemon": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", + "integrity": "sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/examples/nodejs-imagegen/package.json b/examples/nodejs-imagegen/package.json new file mode 100644 index 00000000..9479a557 --- /dev/null +++ b/examples/nodejs-imagegen/package.json @@ -0,0 +1,20 @@ +{ + "name": "examples", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "nodemon server.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@gptscript-ai/gptscript": "^0.1.2", + "express": "^4.18.3", + "express-ws": "^5.0.2", + "nodemon": "^3.1.0", + "ws": "^8.16.0" + } +} \ No newline at end of file diff --git a/examples/nodejs-imagegen/public/index.html b/examples/nodejs-imagegen/public/index.html new file mode 100644 index 00000000..fb9bf611 --- /dev/null +++ b/examples/nodejs-imagegen/public/index.html @@ -0,0 +1,71 @@ + + + + + + + Logo Generator + + + + + + + +

AI Logo Generator

+ +
+

Describe the logo you want designed for your company and we will generate it for you.

+

Our AI will generate a logo based on your description.

+
+ + +
+ + + + + + +
+ + +
+ + +
+ +
+ + + + + \ No newline at end of file diff --git a/examples/nodejs-imagegen/public/script.js b/examples/nodejs-imagegen/public/script.js new file mode 100644 index 00000000..45aa2c8e --- /dev/null +++ b/examples/nodejs-imagegen/public/script.js @@ -0,0 +1,130 @@ +document.addEventListener('DOMContentLoaded', function () { + // Function to fetch and display artists + function fetchArtists() { + fetch('/artists') + .then(response => response.json()) + .then(data => { + const artistsSection = document.getElementById('artistsSection'); + artistsSection.innerHTML = ""; // reset + + data.artists.forEach(artist => { + const artistCard = ` +
+
+
${artist.name}
+

${artist.description}

+
+
+ `; + artistsSection.insertAdjacentHTML('beforeend', artistCard); + }); + }) + .catch(error => { + console.error('Error:', error); + }); + } + + // Function to reattach event listeners + function attachEventListeners() { + // Event listener for fetching new artists + const newArtistsLink = document.getElementById('newArtistsLink'); + + newArtistsLink.addEventListener('click', function (event) { + event.preventDefault(); + + // Clear previous submissions + resetSubmissions(); + + // Fetch and display new artists + fetch('/new-artists', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + }) + .then(response => response.json()) + .then(data => { + fetchArtists(); + }) + .catch(error => { + console.error('Error:', error); + }); + }); + + // Event listener for submitting logo description + const submitBtn = document.getElementById('submitBtn'); + + submitBtn.addEventListener('click', function () { + resetSubmissions(); + // Show spinner and waiting message for each response area + const spinner = document.querySelector('.spinner-border'); + spinner.classList.remove('hidden'); + + // Send POST request to backend for logo generation + fetch('/generate-logo', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + description: document.getElementById('logoDescription').value + }) + }) + .then(response => response.json()) + .then(data => { + const artistResponse = document.getElementById('artistResponse'); + // Hide spinner and display response message for each response area + document.querySelectorAll('.spinner-border').forEach(spinner => { + spinner.classList.add('hidden'); + }); + spinner.classList.add('hidden'); + artistResponse.innerHTML = ""; + + // Display generated logos for each artist + data.submissions.forEach(submission => { + // Create HTML elements + const artistCard = document.createElement('div'); + artistCard.classList.add('max-w-xs', 'rounded', 'overflow-hidden', 'shadow-lg', 'bg-white', 'm-4'); + + const innerDiv = document.createElement('div'); + innerDiv.classList.add('px-6', 'py-4'); + + const artistName = document.createElement('div'); + artistName.classList.add('font-bold', 'text-xl', 'mb-2'); + artistName.textContent = submission.name; + + const image = document.createElement('img'); + image.setAttribute('src', submission.url); + image.setAttribute('alt', `${submission.name} Logo`); + image.classList.add('w-full', 'h-auto'); + + // Append elements to each other + innerDiv.appendChild(artistName); + innerDiv.appendChild(image); + artistCard.appendChild(innerDiv); + + // Append the generated HTML to the container + artistResponse.appendChild(artistCard); + }); + }) + .catch(error => { + console.error('Error:', error); + }); + + }); + } + + function resetSubmissions() { + // Clear previous submissions + document.getElementById('artistResponse').innerHTML = ` + `; + const spinner = document.querySelector('.spinner-border'); + spinner.classList.add('hidden'); + } + + // Initial setup + fetchArtists(); // Fetch and display artists + attachEventListeners(); // Attach event listeners +}); diff --git a/examples/nodejs-imagegen/requirements.txt b/examples/nodejs-imagegen/requirements.txt new file mode 100644 index 00000000..15738306 --- /dev/null +++ b/examples/nodejs-imagegen/requirements.txt @@ -0,0 +1,3 @@ +# requirements.txt +openai +argparse diff --git a/examples/nodejs-imagegen/server.js b/examples/nodejs-imagegen/server.js new file mode 100644 index 00000000..19c1e157 --- /dev/null +++ b/examples/nodejs-imagegen/server.js @@ -0,0 +1,103 @@ +const path = require('path'); +const express = require('express'); +const bodyParser = require('body-parser'); +const gptscript = require('@gptscript-ai/gptscript'); +const app = express(); +const PORT = 3000; + +// Middleware +app.use(bodyParser.json()); +app.use(express.static(path.join(__dirname, 'public'))); + + +// JSON data +const artistsData = require('./artists.json'); + +let newArtistsData = new Map(); + +function getArtistsData() { + if (newArtistsData.size === 0) { + return artistsData; + } else { + return newArtistsData; + } +} + +// Route to serve index.html +app.get('/', (req, res) => { + res.sendFile(__dirname + '/public/index.html'); +}); + +// Route to handle logo generation request +app.post('/generate-logo', async (req, res) => { + const description = req.body.description; + const artists = getArtistsData(); + const prompt = ` + tools: ./tool.gpt + For each of the three amazing and capable artists described here + ${JSON.stringify(artists)} + make sure to include the artistName field in the response. + + Have each one generate a logo that meets these requirements and represents their pov: + ${description} + + The response format should be json and MUST NOT have other content or formatting. + the name should be the name of the artist for the submission + + { + submissions: [{ + name: "artistName", + url: "imageURL" + }] + } +`; + try { + const output = await gptscript.exec(prompt); + const cleanedResp = output.trim().replace(/^```json.*/, '').replace(/```/g, ''); + res.json(JSON.parse(cleanedResp)); + } catch (error) { + console.error(error); + res.json({ error: error.message }) + } +}); + +// Route to request new artists +app.post('/new-artists', async (req, res) => { + const prompt = ` + tools: sys.write + +Create three short graphic artist descriptions and their muses. +These should be descriptive and explain their point of view. +Also come up with a made up name, they each should be from different +backgrounds and approach art differently. + +the response format should be json and MUST NOT have other content or formatting. + +{ + artists: [{ + name: "name" + description: "description" + }] +} +`; + try { + const output = await gptscript.exec(prompt); + const cleanedResp = output.trim().replace(/^```json.*/, '').replace(/```/g, ''); + newArtistsData = JSON.parse(cleanedResp); + res.json(newArtistsData); + } catch (error) { + console.error(error); + res.json({ error: error.message }) + } +}); + +// Route to serve artists data +app.get('/artists', (req, res) => { + const artistsData = getArtistsData(); + res.json(artistsData); +}); + +// Start server +app.listen(PORT, '0.0.0.0', () => { + console.log(`Server is running on http://0.0.0.0:${PORT}`); +}); diff --git a/examples/nodejs-imagegen/tool.gpt b/examples/nodejs-imagegen/tool.gpt new file mode 100644 index 00000000..fd5bddc8 --- /dev/null +++ b/examples/nodejs-imagegen/tool.gpt @@ -0,0 +1,8 @@ +description: I am a tool that can generate images based on arguments that are sent to me. I return a list of URLs to the generated images. +args: prompt: (required) The text prompt based on which the GPT model will generate a response +args: model: (optional) The model to use for image generation. Defaults to "dall-e-3". +args: size: (optional) The size of the image to generate, format WxH (e.g. 1024x1024). Defaults to 1024x1024. +args: quality: (optional) The quality of the generated image. Allowed values are "standard" or "hd". Default is "standard". +args: number: (optional) The number of images to generate. Defaults to 1. + +#!/usr/bin/env python3 ./cli.py --prompt="${prompt}" --model="${model}" --size="${size}" --quality="${quality}" --number="${number}" \ No newline at end of file From 9b50fe1ae0bdb5d4ef84a9a1d11a410e1bf4086b Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Tue, 5 Mar 2024 10:29:01 -0500 Subject: [PATCH 153/774] enhance: add document summarizer example (#107) * enhance: add document summarizer example Signed-off-by: Grant Linville --- docs/README-USECASES.md | 2 +- examples/hamlet-summarizer/.gitignore | 1 + examples/hamlet-summarizer/Hamlet.pdf | Bin 0 -> 523383 bytes examples/hamlet-summarizer/README.md | 40 ++++++++++++++++++ .../hamlet-summarizer/hamlet-summarizer.gpt | 35 +++++++++++++++ examples/hamlet-summarizer/main.py | 24 +++++++++++ examples/hamlet-summarizer/requirements.txt | 3 ++ 7 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 examples/hamlet-summarizer/.gitignore create mode 100644 examples/hamlet-summarizer/Hamlet.pdf create mode 100644 examples/hamlet-summarizer/README.md create mode 100644 examples/hamlet-summarizer/hamlet-summarizer.gpt create mode 100644 examples/hamlet-summarizer/main.py create mode 100644 examples/hamlet-summarizer/requirements.txt diff --git a/docs/README-USECASES.md b/docs/README-USECASES.md index 863d2682..f22655ab 100644 --- a/docs/README-USECASES.md +++ b/docs/README-USECASES.md @@ -83,7 +83,7 @@ Depending on the context window supported by the LLM, you can either send a larg ### Summarization -Here is a GPTScript that sends a large document in batches to the LLM and produces a summary of the entire document. [Link to example here] +Here is a GPTScript that sends a large document in batches to the LLM and produces a summary of the entire document. [hamlet-summarizer](../examples/hamlet-summarizer) Here is a GPTScript that reads the content of a large SQL database and produces a summary of the entire database. [Link to example here] diff --git a/examples/hamlet-summarizer/.gitignore b/examples/hamlet-summarizer/.gitignore new file mode 100644 index 00000000..f7275bbb --- /dev/null +++ b/examples/hamlet-summarizer/.gitignore @@ -0,0 +1 @@ +venv/ diff --git a/examples/hamlet-summarizer/Hamlet.pdf b/examples/hamlet-summarizer/Hamlet.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e61506346998b0a6d44bd6f6a5700e7c708c192a GIT binary patch literal 523383 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 z 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