]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add file with list of all counters we collect
authorMichael Matloob <matloob@golang.org>
Thu, 15 Feb 2024 21:07:40 +0000 (16:07 -0500)
committerMichael Matloob <matloob@golang.org>
Mon, 4 Mar 2024 17:57:25 +0000 (17:57 +0000)
Maintain a list of counters we collect and test that it hasn't
changed. If it has, fail a test and have the user update the list. The
update process will print a reminder to update the list of collected
counters.

Also run go mod vendor to pull in
golang.org/x/telemetry/counter/countertest.

For #58894

Change-Id: I661a9c3d67cb33f42a5519f4639af7aa05c3821d
Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest
Reviewed-on: https://go-review.googlesource.com/c/go/+/564555
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
44 files changed:
src/cmd/go/counters_test.go [new file with mode: 0644]
src/cmd/go/go_test.go
src/cmd/go/main.go
src/cmd/go/script_test.go
src/cmd/go/telemetry.go [new file with mode: 0644]
src/cmd/go/telemetry_bootstrap.go [new file with mode: 0644]
src/cmd/go/testdata/counters.txt [new file with mode: 0644]
src/cmd/vendor/golang.org/x/sync/errgroup/errgroup.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/sync/errgroup/go120.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/sync/errgroup/pre_go120.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/.dockerignore [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/.eslintrc.json [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/.gitattributes [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/.gitignore [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/.prettierrc.json [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/.stylelintrc.json [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/CONTRIBUTING.md [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/README.md [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest_go118.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest_go121.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/doc.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/config/config.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/configstore/download.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/crashmonitor/crash_go123.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/crashmonitor/monitor.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/upload/Doc.txt [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/upload/date.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/upload/findwork.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/upload/reports.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/upload/run.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/internal/upload/upload.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/mode.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/npm [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/npx [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/package-lock.json [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/package.json [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/start.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/start_posix.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/start_windows.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/tsconfig.json [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/types_alias.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/telemetry/upload/upload.go [new file with mode: 0644]
src/cmd/vendor/modules.txt

diff --git a/src/cmd/go/counters_test.go b/src/cmd/go/counters_test.go
new file mode 100644 (file)
index 0000000..0413597
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main_test
+
+import (
+       "cmd/go/internal/base"
+       "flag"
+       "internal/diff"
+       "os"
+       "slices"
+       "strings"
+       "testing"
+)
+
+var update = flag.Bool("update", false, "if true update testdata/counternames.txt")
+
+func TestCounterNamesUpToDate(t *testing.T) {
+       if !*update {
+               t.Parallel()
+       }
+
+       var counters []string
+       // -C is a special case because it's handled by handleChdirFlag rather than
+       // standard flag processing with FlagSets.
+       // cmd/go/subcommand:unknown is also a special case: it's used when the subcommand
+       // doesn't match any of the known commands.
+       counters = append(counters, "cmd/go/flag:C", "cmd/go/subcommand:unknown")
+       counters = append(counters, flagscounters("cmd/go/flag:", *flag.CommandLine)...)
+
+       for _, cmd := range base.Go.Commands {
+               counters = append(counters, cmdcounters(nil, cmd)...)
+       }
+       cstr := []byte(strings.Join(counters, "\n") + "\n")
+
+       const counterNamesFile = "testdata/counters.txt"
+       old, err := os.ReadFile(counterNamesFile)
+       if err != nil {
+               t.Fatalf("error reading %s: %v", counterNamesFile, err)
+       }
+       diff := diff.Diff(counterNamesFile, old, "generated counter names", cstr)
+       if diff == nil {
+               t.Logf("%s is up to date.", counterNamesFile)
+               return
+       }
+
+       if *update {
+               if err := os.WriteFile(counterNamesFile, cstr, 0666); err != nil {
+                       t.Fatal(err)
+               }
+               t.Logf("wrote %d bytes to %s", len(cstr), counterNamesFile)
+               t.Logf("don't forget to file a proposal to update the list of collected counters")
+       } else {
+               t.Logf("\n%s", diff)
+               t.Errorf("%s is stale. To update, run 'go generate cmd/go'.", counterNamesFile)
+       }
+}
+
+func flagscounters(prefix string, flagSet flag.FlagSet) []string {
+       var counters []string
+       flagSet.VisitAll(func(f *flag.Flag) {
+               counters = append(counters, prefix+f.Name)
+       })
+       return counters
+}
+
+func cmdcounters(previous []string, cmd *base.Command) []string {
+       const subcommandPrefix = "cmd/go/subcommand:"
+       const flagPrefix = "cmd/go/flag:"
+       var counters []string
+       previousComponent := strings.Join(previous, "-")
+       if len(previousComponent) > 0 {
+               previousComponent += "-"
+       }
+       if cmd.Runnable() {
+               counters = append(counters, subcommandPrefix+previousComponent+cmd.Name())
+       }
+       counters = append(counters, flagscounters(flagPrefix+previousComponent+cmd.Name()+"-", cmd.Flag)...)
+       if len(previous) != 0 {
+               counters = append(counters, subcommandPrefix+previousComponent+"help-"+cmd.Name())
+       }
+       counters = append(counters, subcommandPrefix+"help-"+previousComponent+cmd.Name())
+
+       for _, subcmd := range cmd.Commands {
+               counters = append(counters, cmdcounters(append(slices.Clone(previous), cmd.Name()), subcmd)...)
+       }
+       return counters
+}
index 4f38ec3defabccd8cb8569bf56860b8faa791736..34a3cf15c963cc6653b3b1e0ae6ae9e674477a54 100644 (file)
@@ -44,6 +44,8 @@ import (
        "cmd/internal/sys"
 
        cmdgo "cmd/go"
+
+       "golang.org/x/telemetry/counter/countertest"
 )
 
 func init() {
@@ -153,6 +155,15 @@ func TestMain(m *testing.M) {
                        web.EnableTestHooks(interceptors)
                }
 
+               cmdgo.TelemetryStart = func() {
+                       // TODO(matloob): we'll ideally want to call telemetry.Start here
+                       // but it calls counter.Open, which we don't want to do because
+                       // we want to call countertest.Open.
+                       if telemetryDir := os.Getenv("TESTGO_TELEMETRY_DIR"); telemetryDir != "" {
+                               countertest.Open(telemetryDir)
+                       }
+               }
+
                cmdgo.Main()
                os.Exit(0)
        }
index 0f6305f89c7d3e82b34393c72b44b586139fb480..c1433b47ad238253335aa1de1ec09ef1f0d84d59 100644 (file)
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 //go:generate go test cmd/go -v -run=^TestDocsUpToDate$ -fixdocs
+//go:generate go test cmd/go -v -run=^TestCounterNamesUpToDate$ -update
 
 package main
 
@@ -91,7 +92,7 @@ var _ = go11tag
 
 func main() {
        log.SetFlags(0)
-       counter.Open() // Open the telemetry counter file so counters can be written to it.
+       TelemetryStart() // Open the telemetry counter file so counters can be written to it.
        handleChdirFlag()
        toolchain.Select()
 
@@ -153,7 +154,6 @@ func main() {
 
        cmd, used := lookupCmd(args)
        cfg.CmdName = strings.Join(args[:used], " ")
-       counter.Inc("cmd/go/subcommand:" + strings.ReplaceAll(cfg.CmdName, " ", "-"))
        if len(cmd.Commands) > 0 {
                if used >= len(args) {
                        help.PrintUsage(os.Stderr, cmd)
@@ -162,6 +162,7 @@ func main() {
                }
                if args[used] == "help" {
                        // Accept 'go mod help' and 'go mod help foo' for 'go help mod' and 'go help mod foo'.
+                       counter.Inc("cmd/go/subcommand:" + strings.ReplaceAll(cfg.CmdName, " ", "-") + "-" + strings.Join(args[used:], "-"))
                        help.Help(os.Stdout, append(slices.Clip(args[:used]), args[used+1:]...))
                        base.Exit()
                }
@@ -173,10 +174,12 @@ func main() {
                if cmdName == "" {
                        cmdName = args[0]
                }
+               counter.Inc("cmd/go/subcommand:unknown")
                fmt.Fprintf(os.Stderr, "go %s: unknown command\nRun 'go help%s' for usage.\n", cmdName, helpArg)
                base.SetExitStatus(2)
                base.Exit()
        }
+       counter.Inc("cmd/go/subcommand:" + strings.ReplaceAll(cfg.CmdName, " ", "-"))
        invoke(cmd, args[used-1:])
        base.Exit()
 }
@@ -241,7 +244,7 @@ func invoke(cmd *base.Command, args []string) {
        } else {
                base.SetFromGOFLAGS(&cmd.Flag)
                cmd.Flag.Parse(args[1:])
-               counter.CountFlags("cmd/go/flag:"+cmd.Name()+"-", cmd.Flag)
+               counter.CountFlags("cmd/go/flag:"+strings.ReplaceAll(cfg.CmdName, " ", "-")+"-", cmd.Flag)
                args = cmd.Flag.Args()
        }
 
@@ -326,7 +329,7 @@ func handleChdirFlag() {
                _, dir, _ = strings.Cut(a, "=")
                os.Args = slices.Delete(os.Args, used, used+1)
        }
-       counter.Inc("cmd/go:flag-C")
+       counter.Inc("cmd/go/flag:C")
 
        if err := os.Chdir(dir); err != nil {
                base.Fatalf("go: %v", err)
index f50e85f575f197ade2591ae67654225d1339e2c0..6efa9217de098b3403155c84e35e60f2261e3d30 100644 (file)
@@ -13,6 +13,7 @@ import (
        "bufio"
        "bytes"
        "context"
+       _ "embed"
        "flag"
        "internal/testenv"
        "internal/txtar"
@@ -21,6 +22,7 @@ import (
        "path/filepath"
        "runtime"
        "strings"
+       "sync"
        "testing"
        "time"
 
@@ -29,6 +31,8 @@ import (
        "cmd/go/internal/script"
        "cmd/go/internal/script/scripttest"
        "cmd/go/internal/vcweb/vcstest"
+
+       "golang.org/x/telemetry/counter/countertest"
 )
 
 var testSum = flag.String("testsum", "", `may be tidy, listm, or listall. If set, TestScript generates a go.sum file at the beginning of each test and updates test files if they pass.`)
@@ -124,7 +128,7 @@ func TestScript(t *testing.T) {
                        if err != nil {
                                t.Fatal(err)
                        }
-                       initScriptDirs(t, s)
+                       telemetryDir := initScriptDirs(t, s)
                        if err := s.ExtractFiles(a); err != nil {
                                t.Fatal(err)
                        }
@@ -154,6 +158,7 @@ func TestScript(t *testing.T) {
                        // will work better seeing the full path relative to cmd/go
                        // (where the "go test" command is usually run).
                        scripttest.Run(t, engine, s, file, bytes.NewReader(a.Comment))
+                       checkCounters(t, telemetryDir)
                })
        }
 }
@@ -177,7 +182,7 @@ func tbFromContext(ctx context.Context) (testing.TB, bool) {
 
 // initScriptState creates the initial directory structure in s for unpacking a
 // cmd/go script.
-func initScriptDirs(t testing.TB, s *script.State) {
+func initScriptDirs(t testing.TB, s *script.State) (telemetryDir string) {
        must := func(err error) {
                if err != nil {
                        t.Helper()
@@ -188,6 +193,10 @@ func initScriptDirs(t testing.TB, s *script.State) {
        work := s.Getwd()
        must(s.Setenv("WORK", work))
 
+       telemetryDir = filepath.Join(work, "telemetry")
+       must(os.MkdirAll(telemetryDir, 0777))
+       must(s.Setenv("TESTGO_TELEMETRY_DIR", filepath.Join(work, "telemetry")))
+
        must(os.MkdirAll(filepath.Join(work, "tmp"), 0777))
        must(s.Setenv(tempEnvName(), filepath.Join(work, "tmp")))
 
@@ -196,6 +205,7 @@ func initScriptDirs(t testing.TB, s *script.State) {
        gopathSrc := filepath.Join(gopath, "src")
        must(os.MkdirAll(gopathSrc, 0777))
        must(s.Chdir(gopathSrc))
+       return telemetryDir
 }
 
 func scriptEnv(srv *vcstest.Server, srvCertFile string) ([]string, error) {
@@ -357,3 +367,53 @@ func updateSum(t testing.TB, e *script.Engine, s *script.State, archive *txtar.A
        }
        return rewrite
 }
+
+func readCounters(t *testing.T, telemetryDir string) map[string]uint64 {
+       localDir := filepath.Join(telemetryDir, "local")
+       dirents, err := os.ReadDir(localDir)
+       if err != nil {
+               if os.IsNotExist(err) {
+                       return nil // The Go command didn't ever run so the local dir wasn't created
+               }
+               t.Fatalf("reading telemetry local dir: %v", err)
+       }
+       totals := map[string]uint64{}
+       for _, dirent := range dirents {
+               if dirent.IsDir() || !strings.HasSuffix(dirent.Name(), ".count") {
+                       // not a counter file
+                       continue
+               }
+               counters, _, err := countertest.ReadFile(filepath.Join(localDir, dirent.Name()))
+               if err != nil {
+                       t.Fatalf("reading counter file: %v", err)
+               }
+               for k, v := range counters {
+                       totals[k] += v
+               }
+       }
+
+       return totals
+}
+
+//go:embed testdata/counters.txt
+var countersTxt string
+
+var (
+       allowedCountersOnce sync.Once
+       allowedCounters     = map[string]bool{} // Set of allowed counters.
+)
+
+func checkCounters(t *testing.T, telemetryDir string) {
+       allowedCountersOnce.Do(func() {
+               for _, counter := range strings.Fields(countersTxt) {
+                       allowedCounters[counter] = true
+               }
+       })
+       counters := readCounters(t, telemetryDir)
+       for name := range counters {
+               if !allowedCounters[name] {
+                       t.Fatalf("incremented counter %q is not in testdata/counters.txt. "+
+                               "Please update counters_test.go to produce an entry for it.", name)
+               }
+       }
+}
diff --git a/src/cmd/go/telemetry.go b/src/cmd/go/telemetry.go
new file mode 100644 (file)
index 0000000..ac7a6a9
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !cmd_go_bootstrap
+
+package main
+
+import "golang.org/x/telemetry"
+
+var TelemetryStart = func() {
+       telemetry.Start(telemetry.Config{Upload: true})
+}
diff --git a/src/cmd/go/telemetry_bootstrap.go b/src/cmd/go/telemetry_bootstrap.go
new file mode 100644 (file)
index 0000000..8bacf21
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build cmd_go_bootstrap
+
+package main
+
+var TelemetryStart = func() {}
diff --git a/src/cmd/go/testdata/counters.txt b/src/cmd/go/testdata/counters.txt
new file mode 100644 (file)
index 0000000..5e1a565
--- /dev/null
@@ -0,0 +1,661 @@
+cmd/go/flag:C
+cmd/go/subcommand:unknown
+cmd/go/flag:fixdocs
+cmd/go/flag:fixreadme
+cmd/go/flag:flaky
+cmd/go/flag:proxy
+cmd/go/flag:test.bench
+cmd/go/flag:test.benchmem
+cmd/go/flag:test.benchtime
+cmd/go/flag:test.blockprofile
+cmd/go/flag:test.blockprofilerate
+cmd/go/flag:test.count
+cmd/go/flag:test.coverprofile
+cmd/go/flag:test.cpu
+cmd/go/flag:test.cpuprofile
+cmd/go/flag:test.failfast
+cmd/go/flag:test.fullpath
+cmd/go/flag:test.fuzz
+cmd/go/flag:test.fuzzcachedir
+cmd/go/flag:test.fuzzminimizetime
+cmd/go/flag:test.fuzztime
+cmd/go/flag:test.fuzzworker
+cmd/go/flag:test.gocoverdir
+cmd/go/flag:test.list
+cmd/go/flag:test.memprofile
+cmd/go/flag:test.memprofilerate
+cmd/go/flag:test.mutexprofile
+cmd/go/flag:test.mutexprofilefraction
+cmd/go/flag:test.outputdir
+cmd/go/flag:test.paniconexit0
+cmd/go/flag:test.parallel
+cmd/go/flag:test.run
+cmd/go/flag:test.short
+cmd/go/flag:test.shuffle
+cmd/go/flag:test.skip
+cmd/go/flag:test.testlogfile
+cmd/go/flag:test.timeout
+cmd/go/flag:test.trace
+cmd/go/flag:test.v
+cmd/go/flag:testsum
+cmd/go/flag:testwork
+cmd/go/flag:update
+cmd/go/subcommand:bug
+cmd/go/flag:bug-C
+cmd/go/flag:bug-v
+cmd/go/subcommand:help-bug
+cmd/go/subcommand:build
+cmd/go/flag:build-C
+cmd/go/flag:build-a
+cmd/go/flag:build-asan
+cmd/go/flag:build-asmflags
+cmd/go/flag:build-buildmode
+cmd/go/flag:build-buildvcs
+cmd/go/flag:build-compiler
+cmd/go/flag:build-cover
+cmd/go/flag:build-covermode
+cmd/go/flag:build-coverpkg
+cmd/go/flag:build-debug-actiongraph
+cmd/go/flag:build-debug-runtime-trace
+cmd/go/flag:build-debug-trace
+cmd/go/flag:build-gccgoflags
+cmd/go/flag:build-gcflags
+cmd/go/flag:build-installsuffix
+cmd/go/flag:build-ldflags
+cmd/go/flag:build-linkshared
+cmd/go/flag:build-mod
+cmd/go/flag:build-modcacherw
+cmd/go/flag:build-modfile
+cmd/go/flag:build-msan
+cmd/go/flag:build-n
+cmd/go/flag:build-o
+cmd/go/flag:build-overlay
+cmd/go/flag:build-p
+cmd/go/flag:build-pgo
+cmd/go/flag:build-pkgdir
+cmd/go/flag:build-race
+cmd/go/flag:build-tags
+cmd/go/flag:build-toolexec
+cmd/go/flag:build-trimpath
+cmd/go/flag:build-v
+cmd/go/flag:build-work
+cmd/go/flag:build-x
+cmd/go/subcommand:help-build
+cmd/go/subcommand:clean
+cmd/go/flag:clean-C
+cmd/go/flag:clean-a
+cmd/go/flag:clean-asan
+cmd/go/flag:clean-asmflags
+cmd/go/flag:clean-buildmode
+cmd/go/flag:clean-buildvcs
+cmd/go/flag:clean-cache
+cmd/go/flag:clean-compiler
+cmd/go/flag:clean-debug-actiongraph
+cmd/go/flag:clean-debug-runtime-trace
+cmd/go/flag:clean-debug-trace
+cmd/go/flag:clean-fuzzcache
+cmd/go/flag:clean-gccgoflags
+cmd/go/flag:clean-gcflags
+cmd/go/flag:clean-i
+cmd/go/flag:clean-installsuffix
+cmd/go/flag:clean-ldflags
+cmd/go/flag:clean-linkshared
+cmd/go/flag:clean-mod
+cmd/go/flag:clean-modcache
+cmd/go/flag:clean-modcacherw
+cmd/go/flag:clean-modfile
+cmd/go/flag:clean-msan
+cmd/go/flag:clean-n
+cmd/go/flag:clean-overlay
+cmd/go/flag:clean-p
+cmd/go/flag:clean-pgo
+cmd/go/flag:clean-pkgdir
+cmd/go/flag:clean-r
+cmd/go/flag:clean-race
+cmd/go/flag:clean-tags
+cmd/go/flag:clean-testcache
+cmd/go/flag:clean-toolexec
+cmd/go/flag:clean-trimpath
+cmd/go/flag:clean-v
+cmd/go/flag:clean-work
+cmd/go/flag:clean-x
+cmd/go/subcommand:help-clean
+cmd/go/subcommand:doc
+cmd/go/subcommand:help-doc
+cmd/go/subcommand:env
+cmd/go/flag:env-C
+cmd/go/flag:env-json
+cmd/go/flag:env-n
+cmd/go/flag:env-u
+cmd/go/flag:env-w
+cmd/go/flag:env-x
+cmd/go/subcommand:help-env
+cmd/go/subcommand:fix
+cmd/go/flag:fix-C
+cmd/go/flag:fix-a
+cmd/go/flag:fix-asan
+cmd/go/flag:fix-asmflags
+cmd/go/flag:fix-buildmode
+cmd/go/flag:fix-buildvcs
+cmd/go/flag:fix-compiler
+cmd/go/flag:fix-debug-actiongraph
+cmd/go/flag:fix-debug-runtime-trace
+cmd/go/flag:fix-debug-trace
+cmd/go/flag:fix-fix
+cmd/go/flag:fix-gccgoflags
+cmd/go/flag:fix-gcflags
+cmd/go/flag:fix-installsuffix
+cmd/go/flag:fix-ldflags
+cmd/go/flag:fix-linkshared
+cmd/go/flag:fix-mod
+cmd/go/flag:fix-modcacherw
+cmd/go/flag:fix-modfile
+cmd/go/flag:fix-msan
+cmd/go/flag:fix-n
+cmd/go/flag:fix-overlay
+cmd/go/flag:fix-p
+cmd/go/flag:fix-pgo
+cmd/go/flag:fix-pkgdir
+cmd/go/flag:fix-race
+cmd/go/flag:fix-tags
+cmd/go/flag:fix-toolexec
+cmd/go/flag:fix-trimpath
+cmd/go/flag:fix-v
+cmd/go/flag:fix-work
+cmd/go/flag:fix-x
+cmd/go/subcommand:help-fix
+cmd/go/subcommand:fmt
+cmd/go/flag:fmt-C
+cmd/go/flag:fmt-mod
+cmd/go/flag:fmt-modcacherw
+cmd/go/flag:fmt-modfile
+cmd/go/flag:fmt-n
+cmd/go/flag:fmt-overlay
+cmd/go/flag:fmt-x
+cmd/go/subcommand:help-fmt
+cmd/go/subcommand:generate
+cmd/go/flag:generate-C
+cmd/go/flag:generate-a
+cmd/go/flag:generate-asan
+cmd/go/flag:generate-asmflags
+cmd/go/flag:generate-buildmode
+cmd/go/flag:generate-buildvcs
+cmd/go/flag:generate-compiler
+cmd/go/flag:generate-debug-actiongraph
+cmd/go/flag:generate-debug-runtime-trace
+cmd/go/flag:generate-debug-trace
+cmd/go/flag:generate-gccgoflags
+cmd/go/flag:generate-gcflags
+cmd/go/flag:generate-installsuffix
+cmd/go/flag:generate-ldflags
+cmd/go/flag:generate-linkshared
+cmd/go/flag:generate-mod
+cmd/go/flag:generate-modcacherw
+cmd/go/flag:generate-modfile
+cmd/go/flag:generate-msan
+cmd/go/flag:generate-n
+cmd/go/flag:generate-overlay
+cmd/go/flag:generate-p
+cmd/go/flag:generate-pgo
+cmd/go/flag:generate-pkgdir
+cmd/go/flag:generate-race
+cmd/go/flag:generate-run
+cmd/go/flag:generate-skip
+cmd/go/flag:generate-tags
+cmd/go/flag:generate-toolexec
+cmd/go/flag:generate-trimpath
+cmd/go/flag:generate-v
+cmd/go/flag:generate-work
+cmd/go/flag:generate-x
+cmd/go/subcommand:help-generate
+cmd/go/subcommand:get
+cmd/go/flag:get-C
+cmd/go/flag:get-a
+cmd/go/flag:get-asan
+cmd/go/flag:get-asmflags
+cmd/go/flag:get-buildmode
+cmd/go/flag:get-buildvcs
+cmd/go/flag:get-compiler
+cmd/go/flag:get-d
+cmd/go/flag:get-debug-actiongraph
+cmd/go/flag:get-debug-runtime-trace
+cmd/go/flag:get-debug-trace
+cmd/go/flag:get-f
+cmd/go/flag:get-fix
+cmd/go/flag:get-gccgoflags
+cmd/go/flag:get-gcflags
+cmd/go/flag:get-insecure
+cmd/go/flag:get-installsuffix
+cmd/go/flag:get-ldflags
+cmd/go/flag:get-linkshared
+cmd/go/flag:get-m
+cmd/go/flag:get-modcacherw
+cmd/go/flag:get-modfile
+cmd/go/flag:get-msan
+cmd/go/flag:get-n
+cmd/go/flag:get-overlay
+cmd/go/flag:get-p
+cmd/go/flag:get-pgo
+cmd/go/flag:get-pkgdir
+cmd/go/flag:get-race
+cmd/go/flag:get-t
+cmd/go/flag:get-tags
+cmd/go/flag:get-toolexec
+cmd/go/flag:get-trimpath
+cmd/go/flag:get-u
+cmd/go/flag:get-v
+cmd/go/flag:get-work
+cmd/go/flag:get-x
+cmd/go/subcommand:help-get
+cmd/go/subcommand:install
+cmd/go/flag:install-C
+cmd/go/flag:install-a
+cmd/go/flag:install-asan
+cmd/go/flag:install-asmflags
+cmd/go/flag:install-buildmode
+cmd/go/flag:install-buildvcs
+cmd/go/flag:install-compiler
+cmd/go/flag:install-cover
+cmd/go/flag:install-covermode
+cmd/go/flag:install-coverpkg
+cmd/go/flag:install-debug-actiongraph
+cmd/go/flag:install-debug-runtime-trace
+cmd/go/flag:install-debug-trace
+cmd/go/flag:install-gccgoflags
+cmd/go/flag:install-gcflags
+cmd/go/flag:install-installsuffix
+cmd/go/flag:install-ldflags
+cmd/go/flag:install-linkshared
+cmd/go/flag:install-mod
+cmd/go/flag:install-modcacherw
+cmd/go/flag:install-modfile
+cmd/go/flag:install-msan
+cmd/go/flag:install-n
+cmd/go/flag:install-overlay
+cmd/go/flag:install-p
+cmd/go/flag:install-pgo
+cmd/go/flag:install-pkgdir
+cmd/go/flag:install-race
+cmd/go/flag:install-tags
+cmd/go/flag:install-toolexec
+cmd/go/flag:install-trimpath
+cmd/go/flag:install-v
+cmd/go/flag:install-work
+cmd/go/flag:install-x
+cmd/go/subcommand:help-install
+cmd/go/subcommand:list
+cmd/go/flag:list-C
+cmd/go/flag:list-a
+cmd/go/flag:list-asan
+cmd/go/flag:list-asmflags
+cmd/go/flag:list-buildmode
+cmd/go/flag:list-buildvcs
+cmd/go/flag:list-compiled
+cmd/go/flag:list-compiler
+cmd/go/flag:list-cover
+cmd/go/flag:list-covermode
+cmd/go/flag:list-coverpkg
+cmd/go/flag:list-debug-actiongraph
+cmd/go/flag:list-debug-runtime-trace
+cmd/go/flag:list-debug-trace
+cmd/go/flag:list-deps
+cmd/go/flag:list-e
+cmd/go/flag:list-export
+cmd/go/flag:list-f
+cmd/go/flag:list-find
+cmd/go/flag:list-gccgoflags
+cmd/go/flag:list-gcflags
+cmd/go/flag:list-installsuffix
+cmd/go/flag:list-json
+cmd/go/flag:list-ldflags
+cmd/go/flag:list-linkshared
+cmd/go/flag:list-m
+cmd/go/flag:list-mod
+cmd/go/flag:list-modcacherw
+cmd/go/flag:list-modfile
+cmd/go/flag:list-msan
+cmd/go/flag:list-n
+cmd/go/flag:list-overlay
+cmd/go/flag:list-p
+cmd/go/flag:list-pgo
+cmd/go/flag:list-pkgdir
+cmd/go/flag:list-race
+cmd/go/flag:list-retracted
+cmd/go/flag:list-reuse
+cmd/go/flag:list-tags
+cmd/go/flag:list-test
+cmd/go/flag:list-toolexec
+cmd/go/flag:list-trimpath
+cmd/go/flag:list-u
+cmd/go/flag:list-v
+cmd/go/flag:list-versions
+cmd/go/flag:list-work
+cmd/go/flag:list-x
+cmd/go/subcommand:help-list
+cmd/go/subcommand:help-mod
+cmd/go/subcommand:mod-download
+cmd/go/flag:mod-download-C
+cmd/go/flag:mod-download-json
+cmd/go/flag:mod-download-modcacherw
+cmd/go/flag:mod-download-modfile
+cmd/go/flag:mod-download-overlay
+cmd/go/flag:mod-download-reuse
+cmd/go/flag:mod-download-x
+cmd/go/subcommand:mod-help-download
+cmd/go/subcommand:help-mod-download
+cmd/go/subcommand:mod-edit
+cmd/go/flag:mod-edit-C
+cmd/go/flag:mod-edit-dropexclude
+cmd/go/flag:mod-edit-dropreplace
+cmd/go/flag:mod-edit-droprequire
+cmd/go/flag:mod-edit-dropretract
+cmd/go/flag:mod-edit-exclude
+cmd/go/flag:mod-edit-fmt
+cmd/go/flag:mod-edit-go
+cmd/go/flag:mod-edit-json
+cmd/go/flag:mod-edit-modcacherw
+cmd/go/flag:mod-edit-modfile
+cmd/go/flag:mod-edit-module
+cmd/go/flag:mod-edit-n
+cmd/go/flag:mod-edit-overlay
+cmd/go/flag:mod-edit-print
+cmd/go/flag:mod-edit-replace
+cmd/go/flag:mod-edit-require
+cmd/go/flag:mod-edit-retract
+cmd/go/flag:mod-edit-toolchain
+cmd/go/flag:mod-edit-x
+cmd/go/subcommand:mod-help-edit
+cmd/go/subcommand:help-mod-edit
+cmd/go/subcommand:mod-graph
+cmd/go/flag:mod-graph-C
+cmd/go/flag:mod-graph-go
+cmd/go/flag:mod-graph-modcacherw
+cmd/go/flag:mod-graph-modfile
+cmd/go/flag:mod-graph-overlay
+cmd/go/flag:mod-graph-x
+cmd/go/subcommand:mod-help-graph
+cmd/go/subcommand:help-mod-graph
+cmd/go/subcommand:mod-init
+cmd/go/flag:mod-init-C
+cmd/go/flag:mod-init-modcacherw
+cmd/go/flag:mod-init-modfile
+cmd/go/flag:mod-init-overlay
+cmd/go/subcommand:mod-help-init
+cmd/go/subcommand:help-mod-init
+cmd/go/subcommand:mod-tidy
+cmd/go/flag:mod-tidy-C
+cmd/go/flag:mod-tidy-compat
+cmd/go/flag:mod-tidy-e
+cmd/go/flag:mod-tidy-go
+cmd/go/flag:mod-tidy-modcacherw
+cmd/go/flag:mod-tidy-modfile
+cmd/go/flag:mod-tidy-overlay
+cmd/go/flag:mod-tidy-v
+cmd/go/flag:mod-tidy-x
+cmd/go/subcommand:mod-help-tidy
+cmd/go/subcommand:help-mod-tidy
+cmd/go/subcommand:mod-vendor
+cmd/go/flag:mod-vendor-C
+cmd/go/flag:mod-vendor-e
+cmd/go/flag:mod-vendor-modcacherw
+cmd/go/flag:mod-vendor-modfile
+cmd/go/flag:mod-vendor-o
+cmd/go/flag:mod-vendor-overlay
+cmd/go/flag:mod-vendor-v
+cmd/go/subcommand:mod-help-vendor
+cmd/go/subcommand:help-mod-vendor
+cmd/go/subcommand:mod-verify
+cmd/go/flag:mod-verify-C
+cmd/go/flag:mod-verify-modcacherw
+cmd/go/flag:mod-verify-modfile
+cmd/go/flag:mod-verify-overlay
+cmd/go/subcommand:mod-help-verify
+cmd/go/subcommand:help-mod-verify
+cmd/go/subcommand:mod-why
+cmd/go/flag:mod-why-C
+cmd/go/flag:mod-why-m
+cmd/go/flag:mod-why-modcacherw
+cmd/go/flag:mod-why-modfile
+cmd/go/flag:mod-why-overlay
+cmd/go/flag:mod-why-vendor
+cmd/go/subcommand:mod-help-why
+cmd/go/subcommand:help-mod-why
+cmd/go/subcommand:help-work
+cmd/go/subcommand:work-edit
+cmd/go/flag:work-edit-C
+cmd/go/flag:work-edit-dropreplace
+cmd/go/flag:work-edit-dropuse
+cmd/go/flag:work-edit-fmt
+cmd/go/flag:work-edit-go
+cmd/go/flag:work-edit-json
+cmd/go/flag:work-edit-print
+cmd/go/flag:work-edit-replace
+cmd/go/flag:work-edit-toolchain
+cmd/go/flag:work-edit-use
+cmd/go/subcommand:work-help-edit
+cmd/go/subcommand:help-work-edit
+cmd/go/subcommand:work-init
+cmd/go/flag:work-init-C
+cmd/go/flag:work-init-modcacherw
+cmd/go/flag:work-init-modfile
+cmd/go/flag:work-init-overlay
+cmd/go/subcommand:work-help-init
+cmd/go/subcommand:help-work-init
+cmd/go/subcommand:work-sync
+cmd/go/flag:work-sync-C
+cmd/go/flag:work-sync-modcacherw
+cmd/go/flag:work-sync-modfile
+cmd/go/flag:work-sync-overlay
+cmd/go/subcommand:work-help-sync
+cmd/go/subcommand:help-work-sync
+cmd/go/subcommand:work-use
+cmd/go/flag:work-use-C
+cmd/go/flag:work-use-modcacherw
+cmd/go/flag:work-use-modfile
+cmd/go/flag:work-use-overlay
+cmd/go/flag:work-use-r
+cmd/go/subcommand:work-help-use
+cmd/go/subcommand:help-work-use
+cmd/go/subcommand:work-vendor
+cmd/go/flag:work-vendor-C
+cmd/go/flag:work-vendor-e
+cmd/go/flag:work-vendor-modcacherw
+cmd/go/flag:work-vendor-modfile
+cmd/go/flag:work-vendor-o
+cmd/go/flag:work-vendor-overlay
+cmd/go/flag:work-vendor-v
+cmd/go/subcommand:work-help-vendor
+cmd/go/subcommand:help-work-vendor
+cmd/go/subcommand:run
+cmd/go/flag:run-C
+cmd/go/flag:run-a
+cmd/go/flag:run-asan
+cmd/go/flag:run-asmflags
+cmd/go/flag:run-buildmode
+cmd/go/flag:run-buildvcs
+cmd/go/flag:run-compiler
+cmd/go/flag:run-cover
+cmd/go/flag:run-covermode
+cmd/go/flag:run-coverpkg
+cmd/go/flag:run-debug-actiongraph
+cmd/go/flag:run-debug-runtime-trace
+cmd/go/flag:run-debug-trace
+cmd/go/flag:run-exec
+cmd/go/flag:run-gccgoflags
+cmd/go/flag:run-gcflags
+cmd/go/flag:run-installsuffix
+cmd/go/flag:run-ldflags
+cmd/go/flag:run-linkshared
+cmd/go/flag:run-mod
+cmd/go/flag:run-modcacherw
+cmd/go/flag:run-modfile
+cmd/go/flag:run-msan
+cmd/go/flag:run-n
+cmd/go/flag:run-overlay
+cmd/go/flag:run-p
+cmd/go/flag:run-pgo
+cmd/go/flag:run-pkgdir
+cmd/go/flag:run-race
+cmd/go/flag:run-tags
+cmd/go/flag:run-toolexec
+cmd/go/flag:run-trimpath
+cmd/go/flag:run-v
+cmd/go/flag:run-work
+cmd/go/flag:run-x
+cmd/go/subcommand:help-run
+cmd/go/subcommand:test
+cmd/go/flag:test-C
+cmd/go/flag:test-a
+cmd/go/flag:test-asan
+cmd/go/flag:test-asmflags
+cmd/go/flag:test-bench
+cmd/go/flag:test-benchmem
+cmd/go/flag:test-benchtime
+cmd/go/flag:test-blockprofile
+cmd/go/flag:test-blockprofilerate
+cmd/go/flag:test-buildmode
+cmd/go/flag:test-buildvcs
+cmd/go/flag:test-c
+cmd/go/flag:test-compiler
+cmd/go/flag:test-count
+cmd/go/flag:test-cover
+cmd/go/flag:test-covermode
+cmd/go/flag:test-coverpkg
+cmd/go/flag:test-coverprofile
+cmd/go/flag:test-cpu
+cmd/go/flag:test-cpuprofile
+cmd/go/flag:test-debug-actiongraph
+cmd/go/flag:test-debug-runtime-trace
+cmd/go/flag:test-debug-trace
+cmd/go/flag:test-exec
+cmd/go/flag:test-failfast
+cmd/go/flag:test-fullpath
+cmd/go/flag:test-fuzz
+cmd/go/flag:test-fuzzminimizetime
+cmd/go/flag:test-fuzztime
+cmd/go/flag:test-gccgoflags
+cmd/go/flag:test-gcflags
+cmd/go/flag:test-installsuffix
+cmd/go/flag:test-json
+cmd/go/flag:test-ldflags
+cmd/go/flag:test-linkshared
+cmd/go/flag:test-list
+cmd/go/flag:test-memprofile
+cmd/go/flag:test-memprofilerate
+cmd/go/flag:test-mod
+cmd/go/flag:test-modcacherw
+cmd/go/flag:test-modfile
+cmd/go/flag:test-msan
+cmd/go/flag:test-mutexprofile
+cmd/go/flag:test-mutexprofilefraction
+cmd/go/flag:test-n
+cmd/go/flag:test-o
+cmd/go/flag:test-outputdir
+cmd/go/flag:test-overlay
+cmd/go/flag:test-p
+cmd/go/flag:test-parallel
+cmd/go/flag:test-pgo
+cmd/go/flag:test-pkgdir
+cmd/go/flag:test-race
+cmd/go/flag:test-run
+cmd/go/flag:test-short
+cmd/go/flag:test-shuffle
+cmd/go/flag:test-skip
+cmd/go/flag:test-tags
+cmd/go/flag:test-test.bench
+cmd/go/flag:test-test.benchmem
+cmd/go/flag:test-test.benchtime
+cmd/go/flag:test-test.blockprofile
+cmd/go/flag:test-test.blockprofilerate
+cmd/go/flag:test-test.count
+cmd/go/flag:test-test.coverprofile
+cmd/go/flag:test-test.cpu
+cmd/go/flag:test-test.cpuprofile
+cmd/go/flag:test-test.failfast
+cmd/go/flag:test-test.fullpath
+cmd/go/flag:test-test.fuzz
+cmd/go/flag:test-test.fuzzminimizetime
+cmd/go/flag:test-test.fuzztime
+cmd/go/flag:test-test.list
+cmd/go/flag:test-test.memprofile
+cmd/go/flag:test-test.memprofilerate
+cmd/go/flag:test-test.mutexprofile
+cmd/go/flag:test-test.mutexprofilefraction
+cmd/go/flag:test-test.outputdir
+cmd/go/flag:test-test.parallel
+cmd/go/flag:test-test.run
+cmd/go/flag:test-test.short
+cmd/go/flag:test-test.shuffle
+cmd/go/flag:test-test.skip
+cmd/go/flag:test-test.timeout
+cmd/go/flag:test-test.trace
+cmd/go/flag:test-test.v
+cmd/go/flag:test-timeout
+cmd/go/flag:test-toolexec
+cmd/go/flag:test-trace
+cmd/go/flag:test-trimpath
+cmd/go/flag:test-v
+cmd/go/flag:test-vet
+cmd/go/flag:test-work
+cmd/go/flag:test-x
+cmd/go/subcommand:help-test
+cmd/go/subcommand:tool
+cmd/go/flag:tool-C
+cmd/go/flag:tool-n
+cmd/go/subcommand:help-tool
+cmd/go/subcommand:version
+cmd/go/flag:version-C
+cmd/go/flag:version-m
+cmd/go/flag:version-v
+cmd/go/subcommand:help-version
+cmd/go/subcommand:vet
+cmd/go/flag:vet-C
+cmd/go/flag:vet-a
+cmd/go/flag:vet-asan
+cmd/go/flag:vet-asmflags
+cmd/go/flag:vet-buildmode
+cmd/go/flag:vet-buildvcs
+cmd/go/flag:vet-compiler
+cmd/go/flag:vet-debug-actiongraph
+cmd/go/flag:vet-debug-runtime-trace
+cmd/go/flag:vet-debug-trace
+cmd/go/flag:vet-gccgoflags
+cmd/go/flag:vet-gcflags
+cmd/go/flag:vet-installsuffix
+cmd/go/flag:vet-ldflags
+cmd/go/flag:vet-linkshared
+cmd/go/flag:vet-mod
+cmd/go/flag:vet-modcacherw
+cmd/go/flag:vet-modfile
+cmd/go/flag:vet-msan
+cmd/go/flag:vet-n
+cmd/go/flag:vet-overlay
+cmd/go/flag:vet-p
+cmd/go/flag:vet-pgo
+cmd/go/flag:vet-pkgdir
+cmd/go/flag:vet-race
+cmd/go/flag:vet-tags
+cmd/go/flag:vet-toolexec
+cmd/go/flag:vet-trimpath
+cmd/go/flag:vet-v
+cmd/go/flag:vet-vettool
+cmd/go/flag:vet-work
+cmd/go/flag:vet-x
+cmd/go/subcommand:help-vet
+cmd/go/subcommand:help-buildconstraint
+cmd/go/subcommand:help-buildmode
+cmd/go/subcommand:help-c
+cmd/go/subcommand:help-cache
+cmd/go/subcommand:help-environment
+cmd/go/subcommand:help-filetype
+cmd/go/subcommand:help-go.mod
+cmd/go/subcommand:help-gopath
+cmd/go/subcommand:help-goproxy
+cmd/go/subcommand:help-importpath
+cmd/go/subcommand:help-modules
+cmd/go/subcommand:help-module-auth
+cmd/go/subcommand:help-packages
+cmd/go/subcommand:help-private
+cmd/go/subcommand:help-testflag
+cmd/go/subcommand:help-testfunc
+cmd/go/subcommand:help-vcs
diff --git a/src/cmd/vendor/golang.org/x/sync/errgroup/errgroup.go b/src/cmd/vendor/golang.org/x/sync/errgroup/errgroup.go
new file mode 100644 (file)
index 0000000..948a3ee
--- /dev/null
@@ -0,0 +1,135 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package errgroup provides synchronization, error propagation, and Context
+// cancelation for groups of goroutines working on subtasks of a common task.
+//
+// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks
+// returning errors.
+package errgroup
+
+import (
+       "context"
+       "fmt"
+       "sync"
+)
+
+type token struct{}
+
+// A Group is a collection of goroutines working on subtasks that are part of
+// the same overall task.
+//
+// A zero Group is valid, has no limit on the number of active goroutines,
+// and does not cancel on error.
+type Group struct {
+       cancel func(error)
+
+       wg sync.WaitGroup
+
+       sem chan token
+
+       errOnce sync.Once
+       err     error
+}
+
+func (g *Group) done() {
+       if g.sem != nil {
+               <-g.sem
+       }
+       g.wg.Done()
+}
+
+// WithContext returns a new Group and an associated Context derived from ctx.
+//
+// The derived Context is canceled the first time a function passed to Go
+// returns a non-nil error or the first time Wait returns, whichever occurs
+// first.
+func WithContext(ctx context.Context) (*Group, context.Context) {
+       ctx, cancel := withCancelCause(ctx)
+       return &Group{cancel: cancel}, ctx
+}
+
+// Wait blocks until all function calls from the Go method have returned, then
+// returns the first non-nil error (if any) from them.
+func (g *Group) Wait() error {
+       g.wg.Wait()
+       if g.cancel != nil {
+               g.cancel(g.err)
+       }
+       return g.err
+}
+
+// Go calls the given function in a new goroutine.
+// It blocks until the new goroutine can be added without the number of
+// active goroutines in the group exceeding the configured limit.
+//
+// The first call to return a non-nil error cancels the group's context, if the
+// group was created by calling WithContext. The error will be returned by Wait.
+func (g *Group) Go(f func() error) {
+       if g.sem != nil {
+               g.sem <- token{}
+       }
+
+       g.wg.Add(1)
+       go func() {
+               defer g.done()
+
+               if err := f(); err != nil {
+                       g.errOnce.Do(func() {
+                               g.err = err
+                               if g.cancel != nil {
+                                       g.cancel(g.err)
+                               }
+                       })
+               }
+       }()
+}
+
+// TryGo calls the given function in a new goroutine only if the number of
+// active goroutines in the group is currently below the configured limit.
+//
+// The return value reports whether the goroutine was started.
+func (g *Group) TryGo(f func() error) bool {
+       if g.sem != nil {
+               select {
+               case g.sem <- token{}:
+                       // Note: this allows barging iff channels in general allow barging.
+               default:
+                       return false
+               }
+       }
+
+       g.wg.Add(1)
+       go func() {
+               defer g.done()
+
+               if err := f(); err != nil {
+                       g.errOnce.Do(func() {
+                               g.err = err
+                               if g.cancel != nil {
+                                       g.cancel(g.err)
+                               }
+                       })
+               }
+       }()
+       return true
+}
+
+// SetLimit limits the number of active goroutines in this group to at most n.
+// A negative value indicates no limit.
+//
+// Any subsequent call to the Go method will block until it can add an active
+// goroutine without exceeding the configured limit.
+//
+// The limit must not be modified while any goroutines in the group are active.
+func (g *Group) SetLimit(n int) {
+       if n < 0 {
+               g.sem = nil
+               return
+       }
+       if len(g.sem) != 0 {
+               panic(fmt.Errorf("errgroup: modify limit while %v goroutines in the group are still active", len(g.sem)))
+       }
+       g.sem = make(chan token, n)
+}
diff --git a/src/cmd/vendor/golang.org/x/sync/errgroup/go120.go b/src/cmd/vendor/golang.org/x/sync/errgroup/go120.go
new file mode 100644 (file)
index 0000000..f93c740
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.20
+
+package errgroup
+
+import "context"
+
+func withCancelCause(parent context.Context) (context.Context, func(error)) {
+       return context.WithCancelCause(parent)
+}
diff --git a/src/cmd/vendor/golang.org/x/sync/errgroup/pre_go120.go b/src/cmd/vendor/golang.org/x/sync/errgroup/pre_go120.go
new file mode 100644 (file)
index 0000000..88ce334
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.20
+
+package errgroup
+
+import "context"
+
+func withCancelCause(parent context.Context) (context.Context, func(error)) {
+       ctx, cancel := context.WithCancel(parent)
+       return ctx, func(error) { cancel() }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/.dockerignore b/src/cmd/vendor/golang.org/x/telemetry/.dockerignore
new file mode 100644 (file)
index 0000000..416ae44
--- /dev/null
@@ -0,0 +1,17 @@
+.git
+.localstorage
+node_modules
+devtools
+.eslint*
+.gitignore
+.prettier*
+.stylelint*
+CONTRIBUTING.md
+LICENSE
+npm
+npx
+package-lock.json
+package.json
+PATENTS
+README.md
+tsconfig.json
\ No newline at end of file
diff --git a/src/cmd/vendor/golang.org/x/telemetry/.eslintrc.json b/src/cmd/vendor/golang.org/x/telemetry/.eslintrc.json
new file mode 100644 (file)
index 0000000..ba5e242
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "extends": [
+    "eslint:recommended",
+    "plugin:@typescript-eslint/recommended",
+    "prettier"
+  ],
+  "parser": "@typescript-eslint/parser",
+  "plugins": ["@typescript-eslint"],
+  "root": true,
+  "ignorePatterns": ["*.min.js"]
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/.gitattributes b/src/cmd/vendor/golang.org/x/telemetry/.gitattributes
new file mode 100644 (file)
index 0000000..f529a11
--- /dev/null
@@ -0,0 +1,14 @@
+# Treat all files in the repo as binary, with no git magic updating
+# line endings. This produces predictable results in different environments.
+#
+# Windows users contributing to Go will need to use a modern version
+# of git and editors capable of LF line endings.
+#
+# Windows .bat files are known to have multiple bugs when run with LF
+# endings. So if they are checked in with CRLF endings, there should
+# be a test like the one in test/winbatch.go in the go repository.
+# (See golang.org/issue/37791.)
+#
+# See golang.org/issue/9281.
+
+* -text
diff --git a/src/cmd/vendor/golang.org/x/telemetry/.gitignore b/src/cmd/vendor/golang.org/x/telemetry/.gitignore
new file mode 100644 (file)
index 0000000..46770c4
--- /dev/null
@@ -0,0 +1,2 @@
+node_modules
+.localstorage
\ No newline at end of file
diff --git a/src/cmd/vendor/golang.org/x/telemetry/.prettierrc.json b/src/cmd/vendor/golang.org/x/telemetry/.prettierrc.json
new file mode 100644 (file)
index 0000000..91c0b94
--- /dev/null
@@ -0,0 +1 @@
+{"proseWrap": "always"}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/.stylelintrc.json b/src/cmd/vendor/golang.org/x/telemetry/.stylelintrc.json
new file mode 100644 (file)
index 0000000..adccf47
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "extends": ["stylelint-config-standard"],
+  "rules": {
+    "declaration-property-value-allowed-list": {
+      "/color/": ["/^var\\(--/", "transparent"]
+    },
+    "unit-disallowed-list": ["px"],
+    "selector-class-pattern": "^[a-zA-Z\\-]+$"
+  },
+  "ignoreFiles": ["**/*.min.css"]
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/CONTRIBUTING.md b/src/cmd/vendor/golang.org/x/telemetry/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..e913373
--- /dev/null
@@ -0,0 +1,30 @@
+# Contributing to Go
+
+Go is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+## Filing issues
+
+When [filing an issue](https://golang.org/issue/new), make sure to answer these
+five questions:
+
+1.  What version of Go are you using (`go version`)?
+2.  What operating system and processor architecture are you using?
+3.  What did you do?
+4.  What did you expect to see?
+5.  What did you see instead?
+
+General questions should go to the
+[golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead
+of the issue tracker. The gophers there will answer or ask you to file an issue
+if you've tripped over a bug.
+
+## Contributing code
+
+Please read the
+[Contribution Guidelines](https://golang.org/doc/contribute.html) before sending
+patches.
+
+Unless otherwise noted, the Go source files are distributed under the BSD-style
+license found in the LICENSE file.
diff --git a/src/cmd/vendor/golang.org/x/telemetry/README.md b/src/cmd/vendor/golang.org/x/telemetry/README.md
new file mode 100644 (file)
index 0000000..a914a16
--- /dev/null
@@ -0,0 +1,60 @@
+# Go Telemetry
+
+This repository holds the Go Telemetry server code and libraries, used for
+hosting [telemetry.go.dev](https://telemetry.go.dev) and instrumenting Go
+toolchain programs with opt-in telemetry.
+
+**Warning**: this repository is intended for use only in tools maintained by
+the Go team, including tools in the Go distribution and auxiliary tools like
+[gopls](https://pkg.go.dev/golang.org/x/tools/gopls) or
+[govulncheck](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck). There are
+no compatibility guarantees for any of the packages here: public APIs will
+change in breaking ways as the telemetry integration is refined.
+
+## Notable Packages
+
+- The [x/telemetry/counter](https://pkg.go.dev/golang.org/x/telemetry/counter)
+  package provides a library for instrumenting programs with counters and stack
+  reports.
+- The [x/telemetry/upload](https://pkg.go.dev/golang.org/x/telemetry/upload)
+  package provides a hook for Go toolchain programs to upload telemetry data,
+  if the user has opted in to telemetry uploading.
+- The [x/telemetry/cmd/gotelemetry](https://pkg.go.dev/pkg/golang.org/x/telemetry/cmd/gotelemetry)
+  command is used for managing telemetry data and configuration.
+- The [x/telemetry/config](https://pkg.go.dev/pkg/golang.org/x/telemetry/config)
+  package defines the subset of telemetry data that has been approved for
+  uploading by the telemetry proposal process.
+- The [x/telemetry/godev](https://pkg.go.dev/pkg/golang.org/x/telemetry/godev) directory defines
+  the services running at [telemetry.go.dev](https://telemetry.go.dev).
+
+## Contributing
+
+This repository uses Gerrit for code changes. To learn how to submit changes to
+this repository, see https://golang.org/doc/contribute.html.
+
+The main issue tracker for the time repository is located at
+https://github.com/golang/go/issues. Prefix your issue with "x/telemetry:" in
+the subject line, so it is easy to find.
+
+### Linting & Formatting
+
+This repository uses [eslint](https://eslint.org/) to format TS files,
+[stylelint](https://stylelint.io/) to format CSS files, and
+[prettier](https://prettier.io/) to format TS, CSS, Markdown, and YAML files.
+
+See the style guides:
+
+- [TypeScript](https://google.github.io/styleguide/tsguide.html)
+- [CSS](https://go.dev/wiki/CSSStyleGuide)
+
+It is encouraged that all TS and CSS code be run through formatters before
+submitting a change. However, it is not a strict requirement enforced by CI.
+
+### Installing npm Dependencies:
+
+1. Install [docker](https://docs.docker.com/get-docker/)
+2. Run `./npm install`
+
+### Run ESLint, Stylelint, & Prettier
+
+    ./npm run all
diff --git a/src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest.go b/src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest.go
new file mode 100644 (file)
index 0000000..b9bec1f
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.19
+
+// countertest provides testing utilities for counters.
+// This package cannot be used except for testing.
+package countertest
+
+import (
+       "path/filepath"
+       "sync"
+
+       "golang.org/x/telemetry/counter"
+       ic "golang.org/x/telemetry/internal/counter"
+       "golang.org/x/telemetry/internal/telemetry"
+)
+
+var (
+       openedMu sync.Mutex
+       opened   bool
+)
+
+func isOpen() bool {
+       openedMu.Lock()
+       defer openedMu.Unlock()
+       return opened
+}
+
+// Open enables telemetry data writing to disk.
+// This is supposed to be called once during the program execution
+// (i.e. typically in TestMain), and must not be used with
+// golang.org/x/telemetry/counter.Open.
+func Open(telemetryDir string) {
+       openedMu.Lock()
+       defer openedMu.Unlock()
+       if opened {
+               panic("Open was called more than once")
+       }
+       telemetry.ModeFile = telemetry.ModeFilePath(filepath.Join(telemetryDir, "mode"))
+       telemetry.LocalDir = filepath.Join(telemetryDir, "local")
+       telemetry.UploadDir = filepath.Join(telemetryDir, "upload")
+
+       counter.Open()
+       opened = true
+}
+
+// ReadCounter reads the given counter.
+func ReadCounter(c *counter.Counter) (count uint64, _ error) {
+       return ic.Read(c)
+}
+
+// ReadStackCounter reads the given StackCounter.
+func ReadStackCounter(c *counter.StackCounter) (stackCounts map[string]uint64, _ error) {
+       return ic.ReadStack(c)
+}
+
+// ReadFile reads the counters and stack counters from the given file.
+func ReadFile(name string) (counters, stackCounters map[string]uint64, _ error) {
+       return ic.ReadFile(name)
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest_go118.go b/src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest_go118.go
new file mode 100644 (file)
index 0000000..d9eaecc
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.19
+
+package countertest
+
+import "golang.org/x/telemetry/counter"
+
+func Open(telemetryDir string) {}
+
+func ReadCounter(c *counter.Counter) (count uint64, _ error) {
+       return 0, nil
+}
+
+func ReadStackCounter(c *counter.StackCounter) (stackCounts map[string]uint64, _ error) {
+       return nil, nil
+}
+
+func ReadFile(name string) (map[string]uint64, map[string]uint64, error) { return nil, nil, nil }
diff --git a/src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest_go121.go b/src/cmd/vendor/golang.org/x/telemetry/counter/countertest/countertest_go121.go
new file mode 100644 (file)
index 0000000..8d117e0
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.21
+
+package countertest
+
+import "testing"
+
+func init() {
+       // Extra safety check for go1.21+.
+       if !testing.Testing() {
+               panic("use of this package is disallowed in non-testing code")
+       }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/doc.go b/src/cmd/vendor/golang.org/x/telemetry/doc.go
new file mode 100644 (file)
index 0000000..073f40d
--- /dev/null
@@ -0,0 +1 @@
+package telemetry
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/config/config.go b/src/cmd/vendor/golang.org/x/telemetry/internal/config/config.go
new file mode 100644 (file)
index 0000000..7d73dcd
--- /dev/null
@@ -0,0 +1,140 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// package config provides methods for loading and querying a
+// telemetry upload config file.
+package config
+
+import (
+       "encoding/json"
+       "os"
+       "strings"
+
+       "golang.org/x/telemetry/internal/telemetry"
+)
+
+// Config is a wrapper around telemetry.UploadConfig that provides some
+// convenience methods for checking the contents of a report.
+type Config struct {
+       *telemetry.UploadConfig
+       program         map[string]bool
+       goos            map[string]bool
+       goarch          map[string]bool
+       goversion       map[string]bool
+       pgversion       map[pgkey]bool
+       pgcounter       map[pgkey]bool
+       pgcounterprefix map[pgkey]bool
+       pgstack         map[pgkey]bool
+       rate            map[pgkey]float64
+}
+
+type pgkey struct {
+       program, key string
+}
+
+func ReadConfig(file string) (*Config, error) {
+       data, err := os.ReadFile(file)
+       if err != nil {
+               return nil, err
+       }
+       var cfg telemetry.UploadConfig
+       if err := json.Unmarshal(data, &cfg); err != nil {
+               return nil, err
+       }
+       return NewConfig(&cfg), nil
+}
+
+func NewConfig(cfg *telemetry.UploadConfig) *Config {
+       ucfg := Config{UploadConfig: cfg}
+       ucfg.goos = set(ucfg.GOOS)
+       ucfg.goarch = set(ucfg.GOARCH)
+       ucfg.goversion = set(ucfg.GoVersion)
+       ucfg.program = make(map[string]bool, len(ucfg.Programs))
+       ucfg.pgversion = make(map[pgkey]bool, len(ucfg.Programs))
+       ucfg.pgcounter = make(map[pgkey]bool, len(ucfg.Programs))
+       ucfg.pgcounterprefix = make(map[pgkey]bool, len(ucfg.Programs))
+       ucfg.pgstack = make(map[pgkey]bool, len(ucfg.Programs))
+       ucfg.rate = make(map[pgkey]float64)
+       for _, p := range ucfg.Programs {
+               ucfg.program[p.Name] = true
+               for _, v := range p.Versions {
+                       ucfg.pgversion[pgkey{p.Name, v}] = true
+               }
+               for _, c := range p.Counters {
+                       for _, e := range Expand(c.Name) {
+                               ucfg.pgcounter[pgkey{p.Name, e}] = true
+                               ucfg.rate[pgkey{p.Name, e}] = c.Rate
+                       }
+                       prefix, _, found := strings.Cut(c.Name, ":")
+                       if found {
+                               ucfg.pgcounterprefix[pgkey{p.Name, prefix}] = true
+                       }
+               }
+               for _, s := range p.Stacks {
+                       ucfg.pgstack[pgkey{p.Name, s.Name}] = true
+                       ucfg.rate[pgkey{p.Name, s.Name}] = s.Rate
+               }
+       }
+       return &ucfg
+}
+
+func (r *Config) HasProgram(s string) bool {
+       return r.program[s]
+}
+
+func (r *Config) HasGOOS(s string) bool {
+       return r.goos[s]
+}
+
+func (r *Config) HasGOARCH(s string) bool {
+       return r.goarch[s]
+}
+
+func (r *Config) HasGoVersion(s string) bool {
+       return r.goversion[s]
+}
+
+func (r *Config) HasVersion(program, version string) bool {
+       return r.pgversion[pgkey{program, version}]
+}
+
+func (r *Config) HasCounter(program, counter string) bool {
+       return r.pgcounter[pgkey{program, counter}]
+}
+
+func (r *Config) HasCounterPrefix(program, prefix string) bool {
+       return r.pgcounterprefix[pgkey{program, prefix}]
+}
+
+func (r *Config) HasStack(program, stack string) bool {
+       return r.pgstack[pgkey{program, stack}]
+}
+
+func (r *Config) Rate(program, name string) float64 {
+       return r.rate[pgkey{program, name}]
+}
+
+func set(slice []string) map[string]bool {
+       s := make(map[string]bool, len(slice))
+       for _, v := range slice {
+               s[v] = true
+       }
+       return s
+}
+
+// Expand takes a counter defined with buckets and expands it into distinct
+// strings for each bucket
+func Expand(counter string) []string {
+       prefix, rest, hasBuckets := strings.Cut(counter, "{")
+       var counters []string
+       if hasBuckets {
+               buckets := strings.Split(strings.TrimSuffix(rest, "}"), ",")
+               for _, b := range buckets {
+                       counters = append(counters, prefix+b)
+               }
+       } else {
+               counters = append(counters, prefix)
+       }
+       return counters
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/configstore/download.go b/src/cmd/vendor/golang.org/x/telemetry/internal/configstore/download.go
new file mode 100644 (file)
index 0000000..1382243
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package configstore abstracts interaction with the telemetry config server.
+// Telemetry config (golang.org/x/telemetry/config) is distributed as a go
+// module containing go.mod and config.json. Programs that upload collected
+// counters download the latest config using `go mod download`. This provides
+// verification of downloaded configuration and cacheability.
+package configstore
+
+import (
+       "bytes"
+       "encoding/json"
+       "fmt"
+       "os"
+       "os/exec"
+       "path/filepath"
+
+       "golang.org/x/telemetry/internal/telemetry"
+)
+
+const (
+       configModulePath = "golang.org/x/telemetry/config"
+       configFileName   = "config.json"
+)
+
+// DownloadOption is an option for Download.
+type DownloadOption struct {
+       // Env holds the environment variables used when downloading the configuration.
+       // If nil, the process's environment variables are used.
+       Env []string
+}
+
+// Download fetches the requested telemetry UploadConfig using "go mod download".
+//
+// The second result is the canonical version of the requested configuration.
+func Download(version string, opts *DownloadOption) (telemetry.UploadConfig, string, error) {
+       if version == "" {
+               version = "latest"
+       }
+       if opts == nil {
+               opts = &DownloadOption{}
+       }
+       modVer := configModulePath + "@" + version
+       var stdout, stderr bytes.Buffer
+       cmd := exec.Command("go", "mod", "download", "-json", modVer)
+       cmd.Env = opts.Env
+       cmd.Stdout = &stdout
+       cmd.Stderr = &stderr
+       if err := cmd.Run(); err != nil {
+               var info struct {
+                       Error string
+               }
+               if err := json.Unmarshal(stdout.Bytes(), &info); err == nil && info.Error != "" {
+                       return telemetry.UploadConfig{}, "", fmt.Errorf("failed to download config module: %v", info.Error)
+               }
+               return telemetry.UploadConfig{}, "", fmt.Errorf("failed to download config module: %w\n%s", err, &stderr)
+       }
+
+       var info struct {
+               Dir     string
+               Version string
+               Error   string
+       }
+       if err := json.Unmarshal(stdout.Bytes(), &info); err != nil || info.Dir == "" {
+               return telemetry.UploadConfig{}, "", fmt.Errorf("failed to download config module (invalid JSON): %w", err)
+       }
+       data, err := os.ReadFile(filepath.Join(info.Dir, configFileName))
+       if err != nil {
+               return telemetry.UploadConfig{}, "", fmt.Errorf("invalid config module: %w", err)
+       }
+       var cfg telemetry.UploadConfig
+       if err := json.Unmarshal(data, &cfg); err != nil {
+               return telemetry.UploadConfig{}, "", fmt.Errorf("invalid config: %w", err)
+       }
+       return cfg, info.Version, nil
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/crashmonitor/crash_go123.go b/src/cmd/vendor/golang.org/x/telemetry/internal/crashmonitor/crash_go123.go
new file mode 100644 (file)
index 0000000..2e0c1b3
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.23
+// +build go1.23
+
+package crashmonitor
+
+import "runtime/debug"
+
+func init() {
+       setCrashOutput = debug.SetCrashOutput
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/crashmonitor/monitor.go b/src/cmd/vendor/golang.org/x/telemetry/internal/crashmonitor/monitor.go
new file mode 100644 (file)
index 0000000..f475f7e
--- /dev/null
@@ -0,0 +1,256 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package crashmonitor
+
+// This file defines a monitor that reports arbitrary Go runtime
+// crashes to telemetry.
+
+import (
+       "bytes"
+       "fmt"
+       "io"
+       "log"
+       "os"
+       "reflect"
+       "runtime/debug"
+       "strconv"
+       "strings"
+
+       "golang.org/x/telemetry/internal/counter"
+)
+
+// Supported reports whether the runtime supports [runtime.SetCrashOutput].
+//
+// TODO(adonovan): eliminate once go1.23+ is assured.
+func Supported() bool { return setCrashOutput != nil }
+
+var setCrashOutput func(*os.File) error // = runtime.SetCrashOutput on go1.23+
+
+// Parent sets up the parent side of the crashmonitor. It requires
+// exclusive use of a writable pipe connected to the child process's stdin.
+func Parent(pipe *os.File) {
+       writeSentinel(pipe)
+       // Ensure that we get pc=0x%x values in the traceback.
+       debug.SetTraceback("system")
+       setCrashOutput(pipe)
+}
+
+// Child runs the part of the crashmonitor that runs in the child process.
+// It expects its stdin to be connected via a pipe to the parent which has
+// run Parent.
+func Child() {
+       // Wait for parent process's dying gasp.
+       // If the parent dies for any reason this read will return.
+       data, err := io.ReadAll(os.Stdin)
+       if err != nil {
+               log.Fatalf("failed to read from input pipe: %v", err)
+       }
+
+       // If the only line is the sentinel, it wasn't a crash.
+       if bytes.Count(data, []byte("\n")) < 2 {
+               childExitHook()
+               os.Exit(0) // parent exited without crash report
+       }
+
+       log.Printf("parent reported crash:\n%s", data)
+
+       // Parse the stack out of the crash report
+       // and record a telemetry count for it.
+       name, err := telemetryCounterName(data)
+       if err != nil {
+               // Keep count of how often this happens
+               // so that we can investigate if necessary.
+               incrementCounter("crash/malformed")
+
+               // Something went wrong.
+               // Save the crash securely in the file system.
+               f, err := os.CreateTemp(os.TempDir(), "*.crash")
+               if err != nil {
+                       log.Fatal(err)
+               }
+               if _, err := f.Write(data); err != nil {
+                       log.Fatal(err)
+               }
+               if err := f.Close(); err != nil {
+                       log.Fatal(err)
+               }
+               log.Printf("failed to report crash to telemetry: %v", err)
+               log.Fatalf("crash report saved at %s", f.Name())
+       }
+
+       incrementCounter(name)
+
+       childExitHook()
+       log.Fatalf("telemetry crash recorded")
+}
+
+// (stubbed by test)
+var (
+       incrementCounter = func(name string) { counter.New(name).Inc() }
+       childExitHook    = func() {}
+)
+
+// The sentinel function returns its address. The difference between
+// this value as observed by calls in two different processes of the
+// same executable tells us the relative offset of their text segments.
+//
+// It would be nice if SetCrashOutput took care of this as it's fiddly
+// and likely to confuse every user at first.
+func sentinel() uint64 {
+       return uint64(reflect.ValueOf(sentinel).Pointer())
+}
+
+func writeSentinel(out io.Writer) {
+       fmt.Fprintf(out, "sentinel %x\n", sentinel())
+}
+
+// telemetryCounterName parses a crash report produced by the Go
+// runtime, extracts the stack of the first runnable goroutine,
+// converts each line into telemetry form ("symbol:relative-line"),
+// and returns this as the name of a counter.
+func telemetryCounterName(crash []byte) (string, error) {
+       pcs, err := parseStackPCs(string(crash))
+       if err != nil {
+               return "", err
+       }
+
+       // Limit the number of frames we request.
+       pcs = pcs[:min(len(pcs), 16)]
+
+       if len(pcs) == 0 {
+               // This can occur if all goroutines are idle, as when
+               // caught in a deadlock, or killed by an async signal
+               // while blocked.
+               //
+               // TODO(adonovan): consider how to report such
+               // situations. Reporting a goroutine in [sleep] or
+               // [select] state could be quite confusing without
+               // further information about the nature of the crash,
+               // as the problem is not local to the code location.
+               //
+               // For now, we keep count of this situation so that we
+               // can access whether it needs a more involved solution.
+               return "crash/no-running-goroutine", nil
+       }
+
+       // This string appears at the start of all
+       // crashmonitor-generated counter names.
+       //
+       // It is tempting to expose this as a parameter of Start, but
+       // it is not without risk. What value should most programs
+       // provide? There's no point giving the name of the executable
+       // as this is already recorded by telemetry. What if the
+       // application runs in multiple modes? Then it might be useful
+       // to record the mode. The problem is that an application with
+       // multiple modes probably doesn't know its mode by line 1 of
+       // main.main: it might require flag or argument parsing, or
+       // even validation of an environment variable, and we really
+       // want to steer users aware from any logic before Start. The
+       // flags and arguments will be wrong in the child process, and
+       // every extra conditional branch creates a risk that the
+       // recursively executed child program will behave not like the
+       // monitor but like the application. If the child process
+       // exits before calling Start, then the parent application
+       // will not have a monitor, and its crash reports will be
+       // discarded (written in to a pipe that is never read).
+       //
+       // So for now, we use this constant string.
+       const prefix = "crash/crash"
+       return counter.EncodeStack(pcs, prefix), nil
+}
+
+// parseStackPCs parses the parent process's program counters for the
+// first running goroutine out of a GOTRACEBACK=system traceback,
+// adjusting them so that they are valid for the child process's text
+// segment.
+//
+// This function returns only program counter values, ensuring that
+// there is no possibility of strings from the crash report (which may
+// contain PII) leaking into the telemetry system.
+func parseStackPCs(crash string) ([]uintptr, error) {
+       // getPC parses the PC out of a line of the form:
+       //     \tFILE:LINE +0xRELPC sp=... fp=... pc=...
+       getPC := func(line string) (uint64, error) {
+               _, pcstr, ok := strings.Cut(line, " pc=") // e.g. pc=0x%x
+               if !ok {
+                       return 0, fmt.Errorf("no pc= for stack frame: %s", line)
+               }
+               return strconv.ParseUint(pcstr, 0, 64) // 0 => allow 0x prefix
+       }
+
+       var (
+               pcs            []uintptr
+               parentSentinel uint64
+               childSentinel  = sentinel()
+               on             = false // are we in the first running goroutine?
+               lines          = strings.Split(crash, "\n")
+       )
+       for i := 0; i < len(lines); i++ {
+               line := lines[i]
+
+               // Read sentinel value.
+               if parentSentinel == 0 && strings.HasPrefix(line, "sentinel ") {
+                       _, err := fmt.Sscanf(line, "sentinel %x", &parentSentinel)
+                       if err != nil {
+                               return nil, fmt.Errorf("can't read sentinel line")
+                       }
+                       continue
+               }
+
+               // Search for "goroutine GID [STATUS]"
+               if !on {
+                       if strings.HasPrefix(line, "goroutine ") &&
+                               strings.Contains(line, " [running]:") {
+                               on = true
+
+                               if parentSentinel == 0 {
+                                       return nil, fmt.Errorf("no sentinel value in crash report")
+                               }
+                       }
+                       continue
+               }
+
+               // A blank line marks end of a goroutine stack.
+               if line == "" {
+                       break
+               }
+
+               // Skip the final "created by SYMBOL in goroutine GID" part.
+               if strings.HasPrefix(line, "created by ") {
+                       break
+               }
+
+               // Expect a pair of lines:
+               //   SYMBOL(ARGS)
+               //   \tFILE:LINE +0xRELPC sp=0x%x fp=0x%x pc=0x%x
+               // Note: SYMBOL may contain parens "pkg.(*T).method"
+               // The RELPC is sometimes missing.
+
+               // Skip the symbol(args) line.
+               i++
+               if i == len(lines) {
+                       break
+               }
+               line = lines[i]
+
+               // Parse the PC, and correct for the parent and child's
+               // different mappings of the text section.
+               pc, err := getPC(line)
+               if err != nil {
+                       // Inlined frame, perhaps; skip it.
+                       continue
+               }
+               pcs = append(pcs, uintptr(pc-parentSentinel+childSentinel))
+       }
+       return pcs, nil
+}
+
+func min(x, y int) int {
+       if x < y {
+               return x
+       } else {
+               return y
+       }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/upload/Doc.txt b/src/cmd/vendor/golang.org/x/telemetry/internal/upload/Doc.txt
new file mode 100644 (file)
index 0000000..45601e6
--- /dev/null
@@ -0,0 +1,45 @@
+The upload process converts count files into reports, and
+uploads reports. There will be only one report, named YYYY-MM-DD.json,
+for a given day.
+
+First phase. Look at the localdir (os.UserConfigdir()/go/telemetry/local)
+and find all .count and .json files. Find the count files that are no
+longer active by looking at their metadata.
+
+Second phase. Group the inactive count files by their expiry date, and
+for each date generate the local report and the upload report. (The upload
+report only contains the counters in the upload configuration.) The upload
+report is saved in the local directory with a name like YYYY-MM-DD.json, if
+there is no file already existing with that name.
+If the local report is different, it is saved in the local directory
+with a name like local.YYYY-MM-DD.json. The new upload report is
+added to the list of .json files from the first phase. At this point
+the count files are no longer needed and can be deleted.
+
+Third phase. Look at the .json files in the list from the first phase.
+If the name starts with local, skip it. If there is a file with the
+identical name in the upload directory, remove the one in the local directory.
+Otherwise try to upload the one in the local directory,
+If the upload succeeds, move the file to the uploaded directory.
+
+
+There are various error conditions.
+1. Several processes could look at localdir and see work to do.
+1A. They could see different sets of expired count files for some day.
+    This could happen if another process is removing count files. In this
+    case there is already a YYYY-MM-DD.json file either in localdir
+    or updatedir, so the process seeing fewer count files will not generate
+    a report.
+1B. They could see the same count files, and no report in either directory.
+    They will both generate (in memory) reports and check to see if there
+    is a YYYY-MM-DD.json file in either directory. They could both then
+    write two files with the same name, but different X values, but
+    otherwise the same contents. The X values are very close to the front
+    of the file. Assuming reasonable file system semantics one version of
+    the file will be written. To minimize this, just before writing reports
+    the code checks again to see if they exist.
+1C. Once there is an existing well-formed file YYYY-MM-DD.json in localdir
+    eventually the upload will succeed, and the file will be moved to updatedir.
+    It is possible that other processes will not see the file in updatedir and
+    upload it again and also move it to uploaddir. This is harmless as all
+    the uploaded files are identical.
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/upload/date.go b/src/cmd/vendor/golang.org/x/telemetry/internal/upload/date.go
new file mode 100644 (file)
index 0000000..5a831f0
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package upload
+
+import (
+       "fmt"
+       "os"
+       "sync"
+       "time"
+
+       "golang.org/x/telemetry/internal/counter"
+)
+
+// time and date handling
+
+var distantPast = 21 * 24 * time.Hour
+
+// reports that are too old (21 days) are not uploaded
+func tooOld(date string, uploadStartTime time.Time) bool {
+       t, err := time.Parse("2006-01-02", date)
+       if err != nil {
+               logger.Printf("tooOld: %v", err)
+               return false
+       }
+       age := uploadStartTime.Sub(t)
+       return age > distantPast
+}
+
+// a time in the far future for the expiry time with errors
+var farFuture = time.UnixMilli(1 << 62)
+
+// counterDateSpan parses the counter file named fname and returns the (begin, end) span
+// recorded in its metadata.
+// On any error, it returns (0, farFuture), so that invalid files don't look
+// like they can be used.
+//
+// TODO(rfindley): just return an error to make this explicit.
+func (u *Uploader) counterDateSpan(fname string) (begin, end time.Time) {
+       parsed, err := u.parse(fname)
+       if err != nil {
+               logger.Printf("expiry Parse: %v for %s", err, fname)
+               return time.Time{}, farFuture
+       }
+       begin, err = time.Parse(time.RFC3339, parsed.Meta["TimeBegin"])
+       if err != nil {
+               logger.Printf("time.Parse(%s[TimeBegin]) failed: %v", fname, err)
+               return time.Time{}, farFuture
+       }
+       end, err = time.Parse(time.RFC3339, parsed.Meta["TimeEnd"])
+       if err != nil {
+               logger.Printf("time.Parse(%s[TimeEnd]) failed: %v", fname, err)
+               return time.Time{}, farFuture
+       }
+       return begin, end
+}
+
+// stillOpen returns true if the counter file might still be active
+func (u *Uploader) stillOpen(fname string) bool {
+       _, expiry := u.counterDateSpan(fname)
+       return expiry.After(u.StartTime)
+}
+
+// avoid parsing count files multiple times
+type parsedCache struct {
+       mu sync.Mutex
+       m  map[string]*counter.File
+}
+
+func (u *Uploader) parse(fname string) (*counter.File, error) {
+       u.cache.mu.Lock()
+       defer u.cache.mu.Unlock()
+       if u.cache.m == nil {
+               u.cache.m = make(map[string]*counter.File)
+       }
+       if f, ok := u.cache.m[fname]; ok {
+               return f, nil
+       }
+       buf, err := os.ReadFile(fname)
+       if err != nil {
+               return nil, fmt.Errorf("parse ReadFile: %v for %s", err, fname)
+       }
+       f, err := counter.Parse(fname, buf)
+       if err != nil {
+
+               return nil, fmt.Errorf("parse Parse: %v for %s", err, fname)
+       }
+       u.cache.m[fname] = f
+       return f, nil
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/upload/findwork.go b/src/cmd/vendor/golang.org/x/telemetry/internal/upload/findwork.go
new file mode 100644 (file)
index 0000000..286d6be
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package upload
+
+import (
+       "os"
+       "path/filepath"
+       "strings"
+)
+
+// files to handle
+type work struct {
+       // absolute file names
+       countfiles []string // count files to process
+       readyfiles []string // old reports to upload
+       // relative names
+       uploaded map[string]bool // reports that have been uploaded
+}
+
+// find all the files that look like counter files or reports
+// that need to be uploaded. (There may be unexpected leftover files
+// and uploading is supposed to be idempotent.)
+func (u *Uploader) findWork() work {
+       localdir, uploaddir := u.LocalDir, u.UploadDir
+       var ans work
+       fis, err := os.ReadDir(localdir)
+       if err != nil {
+               logger.Printf("could not read %s, progress impossible (%v)", localdir, err)
+               return ans
+       }
+
+       mode, asof := u.ModeFilePath.Mode()
+       logger.Printf("mode %s, asof %s", mode, asof)
+
+       // count files end in .v1.count
+       // reports end in .json. If they are not to be uploaded they
+       // start with local.
+       for _, fi := range fis {
+               if strings.HasSuffix(fi.Name(), ".v1.count") {
+                       fname := filepath.Join(localdir, fi.Name())
+                       if u.stillOpen(fname) {
+                               logger.Printf("still active: %s", fname)
+                               continue
+                       }
+                       ans.countfiles = append(ans.countfiles, fname)
+               } else if strings.HasPrefix(fi.Name(), "local.") {
+                       // skip
+               } else if strings.HasSuffix(fi.Name(), ".json") && mode == "on" {
+                       // Collect reports that are ready for upload.
+                       reportDate := uploadReportDate(fi.Name())
+                       if !asof.IsZero() && !reportDate.IsZero() {
+                               // If both the mode asof date and the report date are present, do the
+                               // right thing...
+                               //
+                               // (see https://github.com/golang/go/issues/63142#issuecomment-1734025130)
+                               if asof.Before(reportDate) {
+                                       // Note: since this report was created after telemetry was enabled,
+                                       // we can only assume that the process that created it checked that
+                                       // the counter data contained therein was all from after the asof
+                                       // date.
+                                       //
+                                       // TODO(rfindley): store the begin date in reports, so that we can
+                                       // verify this assumption.
+                                       logger.Printf("uploadable %s", fi.Name())
+                                       ans.readyfiles = append(ans.readyfiles, filepath.Join(localdir, fi.Name()))
+                               }
+                       } else {
+                               // ...otherwise fall back on the old behavior of uploading all
+                               // unuploaded files.
+                               //
+                               // TODO(rfindley): invert this logic following more testing. We
+                               // should only upload if we know both the asof date and the report
+                               // date, and they are acceptable.
+                               logger.Printf("uploadable anyway %s", fi.Name())
+                               ans.readyfiles = append(ans.readyfiles, filepath.Join(localdir, fi.Name()))
+                       }
+               }
+       }
+
+       fis, err = os.ReadDir(uploaddir)
+       if err != nil {
+               os.MkdirAll(uploaddir, 0777)
+               return ans
+       }
+       // There should be only one of these per day; maybe sometime
+       // we'll want to clean the directory.
+       ans.uploaded = make(map[string]bool)
+       for _, fi := range fis {
+               if strings.HasSuffix(fi.Name(), ".json") {
+                       ans.uploaded[fi.Name()] = true
+               }
+       }
+       return ans
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/upload/reports.go b/src/cmd/vendor/golang.org/x/telemetry/internal/upload/reports.go
new file mode 100644 (file)
index 0000000..e8a65bc
--- /dev/null
@@ -0,0 +1,311 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package upload
+
+import (
+       "crypto/rand"
+       "encoding/binary"
+       "encoding/json"
+       "fmt"
+       "math"
+       "os"
+       "path/filepath"
+       "strings"
+       "time"
+
+       "golang.org/x/telemetry/internal/config"
+       "golang.org/x/telemetry/internal/configstore"
+       "golang.org/x/telemetry/internal/counter"
+       "golang.org/x/telemetry/internal/telemetry"
+)
+
+// reports generates reports from inactive count files
+func (u *Uploader) reports(todo *work) ([]string, error) {
+       if mode, _ := u.ModeFilePath.Mode(); mode == "off" {
+               return nil, nil // no reports
+       }
+       thisInstant := u.StartTime
+       today := thisInstant.Format("2006-01-02")
+       lastWeek := latestReport(todo.uploaded)
+       if lastWeek >= today { //should never happen
+               lastWeek = ""
+       }
+       logger.Printf("lastWeek %q, today %s", lastWeek, today)
+       countFiles := make(map[string][]string) // expiry date string->filenames
+       earliest := make(map[string]time.Time)  // earliest begin time for any counter
+       for _, f := range todo.countfiles {
+               begin, end := u.counterDateSpan(f)
+
+               if end.Before(thisInstant) {
+                       expiry := end.Format(dateFormat)
+                       countFiles[expiry] = append(countFiles[expiry], f)
+                       if earliest[expiry].IsZero() || earliest[expiry].After(begin) {
+                               earliest[expiry] = begin
+                       }
+               }
+       }
+       for expiry, files := range countFiles {
+               if notNeeded(expiry, *todo) {
+                       logger.Printf("files for %s not needed, deleting %v", expiry, files)
+                       // The report already exists.
+                       // There's another check in createReport.
+                       deleteFiles(files)
+                       continue
+               }
+               fname, err := u.createReport(earliest[expiry], expiry, files, lastWeek)
+               if err != nil {
+                       return nil, err
+               }
+               if fname != "" {
+                       todo.readyfiles = append(todo.readyfiles, fname)
+               }
+       }
+       return todo.readyfiles, nil
+}
+
+// latestReport returns the YYYY-MM-DD of the last report uploaded
+// or the empty string if there are no reports.
+func latestReport(uploaded map[string]bool) string {
+       var latest string
+       for name := range uploaded {
+               if strings.HasSuffix(name, ".json") {
+                       if name > latest {
+                               latest = name
+                       }
+               }
+       }
+       if latest == "" {
+               return ""
+       }
+       // strip off the .json
+       return latest[:len(latest)-len(".json")]
+}
+
+// notNeeded returns true if the report for date has already been created
+func notNeeded(date string, todo work) bool {
+       if todo.uploaded != nil && todo.uploaded[date+".json"] {
+               return true
+       }
+       // maybe the report is already in todo.readyfiles
+       for _, f := range todo.readyfiles {
+               if strings.Contains(f, date) {
+                       return true
+               }
+       }
+       return false
+}
+
+func deleteFiles(files []string) {
+       for _, f := range files {
+               if err := os.Remove(f); err != nil {
+                       // this could be a race condition.
+                       // conversely, on Windows, err may be nil and
+                       // the file not deleted if anyone has it open.
+                       logger.Printf("%v failed to remove %s", err, f)
+               }
+       }
+}
+
+// createReport for all the count files for the same date.
+// returns the absolute path name of the file containing the report
+func (u *Uploader) createReport(start time.Time, expiryDate string, files []string, lastWeek string) (string, error) {
+       if u.Config == nil {
+               a, v, err := configstore.Download("latest", nil)
+               if err != nil {
+                       logger.Print(err) // or something (e.g., panic(err))
+               }
+               u.Config = &a
+               u.ConfigVersion = v
+       }
+       uploadOK := true
+       mode, asof := u.ModeFilePath.Mode()
+       if u.Config == nil || mode != "on" {
+               logger.Printf("no upload config or mode %q is not 'on'", mode)
+               uploadOK = false // no config, nothing to upload
+       }
+       if tooOld(expiryDate, u.StartTime) {
+               logger.Printf("expiryDate %s is too old", expiryDate)
+               uploadOK = false
+       }
+       // If the mode is recorded with an asof date, don't upload if the report
+       // includes any data on or before the asof date.
+       if !asof.IsZero() && !asof.Before(start) {
+               logger.Printf("asof %s is not before start %s", asof, start)
+               uploadOK = false
+       }
+       // should we check that all the x.Meta are consistent for GOOS, GOARCH, etc?
+       report := &telemetry.Report{
+               Config:   u.ConfigVersion,
+               X:        computeRandom(), // json encodes all the bits
+               Week:     expiryDate,
+               LastWeek: lastWeek,
+       }
+       if report.X > u.Config.SampleRate && u.Config.SampleRate > 0 {
+               logger.Printf("X:%f > SampleRate:%f, not uploadable", report.X, u.Config.SampleRate)
+               uploadOK = false
+       }
+       var succeeded bool
+       for _, f := range files {
+               x, err := u.parse(string(f))
+               if err != nil {
+                       logger.Printf("unparseable (%v) %s", err, f)
+                       continue
+               }
+               prog := findProgReport(x.Meta, report)
+               for k, v := range x.Count {
+                       if counter.IsStackCounter(k) {
+                               // stack
+                               prog.Stacks[k] += int64(v)
+                       } else {
+                               // counter
+                               prog.Counters[k] += int64(v)
+                       }
+                       succeeded = true
+               }
+       }
+       if !succeeded {
+               return "", fmt.Errorf("all %d count files were unparseable", len(files))
+       }
+       // 1. generate the local report
+       localContents, err := json.MarshalIndent(report, "", " ")
+       if err != nil {
+               return "", fmt.Errorf("failed to marshal report (%v)", err)
+       }
+       // check that the report can be read back
+       // TODO(pjw): remove for production?
+       var x telemetry.Report
+       if err := json.Unmarshal(localContents, &x); err != nil {
+               return "", fmt.Errorf("failed to unmarshal local report (%v)", err)
+       }
+
+       var uploadContents []byte
+       if uploadOK {
+               // 2. create the uploadable version
+               cfg := config.NewConfig(u.Config)
+               upload := &telemetry.Report{
+                       Week:     report.Week,
+                       LastWeek: report.LastWeek,
+                       X:        report.X,
+                       Config:   report.Config,
+               }
+               for _, p := range report.Programs {
+                       // does the uploadConfig want this program?
+                       // if so, copy over the Stacks and Counters
+                       // that the uploadConfig mentions.
+                       if !cfg.HasGoVersion(p.GoVersion) || !cfg.HasProgram(p.Program) || !cfg.HasVersion(p.Program, p.Version) {
+                               continue
+                       }
+                       x := &telemetry.ProgramReport{
+                               Program:   p.Program,
+                               Version:   p.Version,
+                               GOOS:      p.GOOS,
+                               GOARCH:    p.GOARCH,
+                               GoVersion: p.GoVersion,
+                               Counters:  make(map[string]int64),
+                               Stacks:    make(map[string]int64),
+                       }
+                       upload.Programs = append(upload.Programs, x)
+                       for k, v := range p.Counters {
+                               if cfg.HasCounter(p.Program, k) && report.X <= cfg.Rate(p.Program, k) {
+                                       x.Counters[k] = v
+                               }
+                       }
+                       // and the same for Stacks
+                       // this can be made more efficient, when it matters
+                       for k, v := range p.Stacks {
+                               before, _, _ := strings.Cut(k, "\n")
+                               if cfg.HasStack(p.Program, before) && report.X <= cfg.Rate(p.Program, before) {
+                                       x.Stacks[k] = v
+                               }
+                       }
+               }
+
+               uploadContents, err = json.MarshalIndent(upload, "", " ")
+               if err != nil {
+                       return "", fmt.Errorf("failed to marshal upload report (%v)", err)
+               }
+       }
+       localFileName := filepath.Join(u.LocalDir, "local."+expiryDate+".json")
+       uploadFileName := filepath.Join(u.LocalDir, expiryDate+".json")
+
+       /* Prepare to write files */
+       // if either file exists, someone has been here ahead of us
+       // (there is still a race, but this check shortens the open window)
+       if _, err := os.Stat(localFileName); err == nil {
+               deleteFiles(files)
+               return "", fmt.Errorf("local report %s already exists", localFileName)
+       }
+       if _, err := os.Stat(uploadFileName); err == nil {
+               deleteFiles(files)
+               return "", fmt.Errorf("report %s already exists", uploadFileName)
+       }
+       // write the uploadable file
+       var errUpload, errLocal error
+       if uploadOK {
+               errUpload = os.WriteFile(uploadFileName, uploadContents, 0644)
+       }
+       // write the local file
+       errLocal = os.WriteFile(localFileName, localContents, 0644)
+       /*  Wrote the files */
+
+       // even though these errors won't occur, what should happen
+       // if errUpload == nil and it is ok to upload, and errLocal != nil?
+       if errLocal != nil {
+               return "", fmt.Errorf("failed to write local file %s (%v)", localFileName, errLocal)
+       }
+       if errUpload != nil {
+               return "", fmt.Errorf("failed to write upload file %s (%v)", uploadFileName, errUpload)
+       }
+       logger.Printf("created %q, deleting %v", uploadFileName, files)
+       deleteFiles(files)
+       if uploadOK {
+               return uploadFileName, nil
+       }
+       return "", nil
+}
+
+// return an existing ProgremReport, or create anew
+func findProgReport(meta map[string]string, report *telemetry.Report) *telemetry.ProgramReport {
+       for _, prog := range report.Programs {
+               if prog.Program == meta["Program"] && prog.Version == meta["Version"] &&
+                       prog.GoVersion == meta["GoVersion"] && prog.GOOS == meta["GOOS"] &&
+                       prog.GOARCH == meta["GOARCH"] {
+                       return prog
+               }
+       }
+       prog := telemetry.ProgramReport{
+               Program:   meta["Program"],
+               Version:   meta["Version"],
+               GoVersion: meta["GoVersion"],
+               GOOS:      meta["GOOS"],
+               GOARCH:    meta["GOARCH"],
+               Counters:  make(map[string]int64),
+               Stacks:    make(map[string]int64),
+       }
+       report.Programs = append(report.Programs, &prog)
+       return &prog
+}
+
+// turn 8 random bytes into a float64 in [0,1]
+func computeRandom() float64 {
+       for {
+               b := make([]byte, 8)
+               _, err := rand.Read(b)
+               if err != nil {
+                       logger.Fatalf("rand.Read: %v", err)
+               }
+               // and turn it into a float64
+               x := math.Float64frombits(binary.LittleEndian.Uint64(b))
+               if math.IsNaN(x) || math.IsInf(x, 0) {
+                       continue
+               }
+               x = math.Abs(x)
+               if x < 0x1p-1000 { // avoid underflow patterns
+                       continue
+               }
+               frac, _ := math.Frexp(x) // 52 bits of randomness
+               return frac*2 - 1
+       }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/upload/run.go b/src/cmd/vendor/golang.org/x/telemetry/internal/upload/run.go
new file mode 100644 (file)
index 0000000..f21d973
--- /dev/null
@@ -0,0 +1,135 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package upload
+
+import (
+       "fmt"
+       "io"
+       "log"
+       "os"
+       "path"
+       "path/filepath"
+       "runtime/debug"
+       "strings"
+       "time"
+
+       "golang.org/x/telemetry/internal/telemetry"
+)
+
+var logger *log.Logger
+
+func init() {
+       logger = log.New(io.Discard, "", 0)
+}
+
+// keep track of what SetLogOutput has seen
+var seenlogwriters []io.Writer
+
+// SetLogOutput sets the default logger's output destination.
+func SetLogOutput(logging io.Writer) {
+       if logging == nil {
+               return
+       }
+       logger.SetOutput(logging) // the common case
+       seenlogwriters = append(seenlogwriters, logging)
+       if len(seenlogwriters) > 1 {
+               // The client asked for logging, and there is also a debug dir
+               logger.SetOutput(io.MultiWriter(seenlogwriters...))
+       }
+}
+
+// LogIfDebug arranges to write a log file in the directory
+// dirname, if it exists. If dirname is the empty string,
+// the function tries the directory it.Localdir/debug.
+func LogIfDebug(dirname string) error {
+       dname := filepath.Join(telemetry.LocalDir, "debug")
+       if dirname != "" {
+               dname = dirname
+       }
+       fd, err := os.Stat(dname)
+       if err != nil {
+               return err
+       }
+       if fd == nil || !fd.IsDir() {
+               // debug doesn't exist or isn't a directory
+               return nil
+       }
+       info, ok := debug.ReadBuildInfo()
+       if !ok {
+               return fmt.Errorf("no build info")
+       }
+       year, month, day := time.Now().UTC().Date()
+       goVers := info.GoVersion
+       // E.g.,  goVers:"go1.22-20240109-RC01 cl/597041403 +dcbe772469 X:loopvar"
+       words := strings.Fields(goVers)
+       goVers = words[0]
+       progPkgPath := info.Path
+       if progPkgPath == "" {
+               progPkgPath = strings.TrimSuffix(filepath.Base(os.Args[0]), ".exe")
+       }
+       prog := path.Base(progPkgPath)
+       progVers := info.Main.Version
+       fname := filepath.Join(dname, fmt.Sprintf("%s-%s-%s-%4d%02d%02d-%d.log",
+               prog, progVers, goVers, year, month, day, os.Getpid()))
+       fname = strings.ReplaceAll(fname, " ", "")
+       if _, err := os.Stat(fname); err == nil {
+               // This process previously called upload.Run
+               return nil
+       }
+       logfd, err := os.Create(fname)
+       if err != nil {
+               return err
+       }
+       SetLogOutput(logfd)
+       return nil
+}
+
+// Uploader carries parameters needed for upload.
+type Uploader struct {
+       // Config is used to select counters to upload.
+       Config *telemetry.UploadConfig
+       // ConfigVersion is the version of the config.
+       ConfigVersion string
+
+       // LocalDir is where the local counter files are.
+       LocalDir string
+       // UploadDir is where uploader leaves the copy of uploaded data.
+       UploadDir string
+       // ModeFilePath is the file.
+       ModeFilePath telemetry.ModeFilePath
+
+       UploadServerURL string
+       StartTime       time.Time
+
+       cache parsedCache
+}
+
+// NewUploader creates a default uploader.
+func NewUploader(config *telemetry.UploadConfig) *Uploader {
+       return &Uploader{
+               Config:          config,
+               ConfigVersion:   "custom",
+               LocalDir:        telemetry.LocalDir,
+               UploadDir:       telemetry.UploadDir,
+               ModeFilePath:    telemetry.ModeFile,
+               UploadServerURL: "https://telemetry.go.dev/upload",
+               StartTime:       time.Now().UTC(),
+       }
+}
+
+// Run generates and uploads reports
+func (u *Uploader) Run() {
+       if telemetry.DisabledOnPlatform {
+               return
+       }
+       todo := u.findWork()
+       ready, err := u.reports(&todo)
+       if err != nil {
+               logger.Printf("reports: %v", err)
+       }
+       for _, f := range ready {
+               u.uploadReport(f)
+       }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/internal/upload/upload.go b/src/cmd/vendor/golang.org/x/telemetry/internal/upload/upload.go
new file mode 100644 (file)
index 0000000..1b64c8e
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package upload
+
+import (
+       "bytes"
+       "net/http"
+       "os"
+       "path/filepath"
+       "regexp"
+       "strings"
+       "time"
+)
+
+var (
+       dateRE     = regexp.MustCompile(`(\d\d\d\d-\d\d-\d\d)[.]json$`)
+       dateFormat = "2006-01-02"
+       // TODO(rfindley): use dateFormat throughout.
+)
+
+// uploadReportDate returns the date component of the upload file name, or "" if the
+// date was unmatched.
+func uploadReportDate(fname string) time.Time {
+       match := dateRE.FindStringSubmatch(fname)
+       if match == nil || len(match) < 2 {
+               logger.Printf("malformed report name: missing date: %q", filepath.Base(fname))
+               return time.Time{}
+       }
+       d, err := time.Parse(dateFormat, match[1])
+       if err != nil {
+               logger.Printf("malformed report name: bad date: %q", filepath.Base(fname))
+               return time.Time{}
+       }
+       return d
+}
+
+func (u *Uploader) uploadReport(fname string) {
+       thisInstant := u.StartTime
+       // TODO(rfindley): use uploadReportDate here, once we've done a gopls release.
+
+       // first make sure it is not in the future
+       today := thisInstant.Format("2006-01-02")
+       match := dateRE.FindStringSubmatch(fname)
+       if match == nil || len(match) < 2 {
+               logger.Printf("report name seemed to have no date %q", filepath.Base(fname))
+       } else if match[1] > today {
+               logger.Printf("report %q is later than today %s", filepath.Base(fname), today)
+               return // report is in the future, which shouldn't happen
+       }
+       buf, err := os.ReadFile(fname)
+       if err != nil {
+               logger.Printf("%v reading %s", err, fname)
+               return
+       }
+       if u.uploadReportContents(fname, buf) {
+               // anything left to do?
+       }
+}
+
+// try to upload the report, 'true' if successful
+func (u *Uploader) uploadReportContents(fname string, buf []byte) bool {
+       b := bytes.NewReader(buf)
+       fdate := strings.TrimSuffix(filepath.Base(fname), ".json")
+       fdate = fdate[len(fdate)-len("2006-01-02"):]
+       server := u.UploadServerURL + "/" + fdate
+
+       resp, err := http.Post(server, "application/json", b)
+       if err != nil {
+               logger.Printf("error on Post: %v %q for %q", err, server, fname)
+               return false
+       }
+       if resp.StatusCode != 200 {
+               logger.Printf("resp error on upload %q: %v for %q %q [%+v]", server, resp.Status, fname, fdate, resp)
+               return false
+       }
+       // put a copy in the uploaded directory
+       newname := filepath.Join(u.UploadDir, fdate+".json")
+       if err := os.WriteFile(newname, buf, 0644); err == nil {
+               os.Remove(fname) // if it exists
+       }
+       logger.Printf("uploaded %s to %q", fdate+".json", server)
+       return true
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/mode.go b/src/cmd/vendor/golang.org/x/telemetry/mode.go
new file mode 100644 (file)
index 0000000..fb9672c
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package telemetry
+
+import (
+       "golang.org/x/telemetry/internal/telemetry"
+)
+
+// Mode returns the current telemetry mode.
+//
+// The telemetry mode is a global value that controls both the local collection
+// and uploading of telemetry data. Possible mode values are:
+//   - "on":    both collection and uploading is enabled
+//   - "local": collection is enabled, but uploading is disabled
+//   - "off":   both collection and uploading are disabled
+//
+// When mode is "on", or "local", telemetry data is written to the local file
+// system and may be inspected with the [gotelemetry] command.
+//
+// If an error occurs while reading the telemetry mode from the file system,
+// Mode returns the default value "local".
+//
+// [gotelemetry]: https://pkg.go.dev/golang.org/x/telemetry/cmd/gotelemetry
+func Mode() string {
+       mode, _ := telemetry.Mode()
+       return mode
+}
+
+// SetMode sets the global telemetry mode to the given value.
+//
+// See the documentation of [Mode] for a description of the supported mode
+// values.
+//
+// An error is returned if the provided mode value is invalid, or if an error
+// occurs while persisting the mode value to the file system.
+func SetMode(mode string) error {
+       return telemetry.SetMode(mode)
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/npm b/src/cmd/vendor/golang.org/x/telemetry/npm
new file mode 100644 (file)
index 0000000..a5455cf
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 2022 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+docker run \
+  --rm \
+  --volume $(pwd):/workspace \
+  --workdir /workspace \
+  --env NODE_OPTIONS="--dns-result-order=ipv4first" \
+  --entrypoint npm \
+  node:18.16.0-slim \
+  $@
diff --git a/src/cmd/vendor/golang.org/x/telemetry/npx b/src/cmd/vendor/golang.org/x/telemetry/npx
new file mode 100644 (file)
index 0000000..47bb38b
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 2022 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+docker run \
+  --rm \
+  --volume $(pwd):/workspace \
+  --workdir /workspace \
+  --env NODE_OPTIONS="--dns-result-order=ipv4first" \
+  --entrypoint npx \
+  node:18.16.0-slim \
+  $@
diff --git a/src/cmd/vendor/golang.org/x/telemetry/package-lock.json b/src/cmd/vendor/golang.org/x/telemetry/package-lock.json
new file mode 100644 (file)
index 0000000..9c86033
--- /dev/null
@@ -0,0 +1,4363 @@
+{
+  "name": "workspace",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "dependencies": {
+        "@observablehq/plot": "0.6.9",
+        "d3": "7.8.5"
+      },
+      "devDependencies": {
+        "@typescript-eslint/eslint-plugin": "5.59.6",
+        "@typescript-eslint/parser": "5.59.6",
+        "eslint": "8.40.0",
+        "eslint-config-prettier": "8.8.0",
+        "npm-run-all": "4.1.5",
+        "prettier": "2.8.8",
+        "stylelint": "15.6.2",
+        "stylelint-config-standard": "33.0.0",
+        "typescript": "5.0.4"
+      }
+    },
+    "node_modules/@aashutoshrathi/word-wrap": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.21.4",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
+      "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.19.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/highlight": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.18.6",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@csstools/css-parser-algorithms": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz",
+      "integrity": "sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA==",
+      "dev": true,
+      "engines": {
+        "node": "^14 || ^16 || >=18"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "@csstools/css-tokenizer": "^2.1.1"
+      }
+    },
+    "node_modules/@csstools/css-tokenizer": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz",
+      "integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==",
+      "dev": true,
+      "engines": {
+        "node": "^14 || ^16 || >=18"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      }
+    },
+    "node_modules/@csstools/media-query-list-parser": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz",
+      "integrity": "sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA==",
+      "dev": true,
+      "engines": {
+        "node": "^14 || ^16 || >=18"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "@csstools/css-parser-algorithms": "^2.1.1",
+        "@csstools/css-tokenizer": "^2.1.1"
+      }
+    },
+    "node_modules/@csstools/selector-specificity": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz",
+      "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==",
+      "dev": true,
+      "engines": {
+        "node": "^14 || ^16 || >=18"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss-selector-parser": "^6.0.10"
+      }
+    },
+    "node_modules/@eslint-community/eslint-utils": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+      "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+      "dev": true,
+      "dependencies": {
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+      }
+    },
+    "node_modules/@eslint-community/regexpp": {
+      "version": "4.5.1",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz",
+      "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==",
+      "dev": true,
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
+    "node_modules/@eslint/eslintrc": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
+      "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^6.12.4",
+        "debug": "^4.3.2",
+        "espree": "^9.5.2",
+        "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"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
+      "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/@eslint/eslintrc/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==",
+      "dev": true
+    },
+    "node_modules/@eslint/js": {
+      "version": "8.40.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
+      "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/@humanwhocodes/config-array": {
+      "version": "0.11.8",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
+      "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
+      "dev": true,
+      "dependencies": {
+        "@humanwhocodes/object-schema": "^1.2.1",
+        "debug": "^4.1.1",
+        "minimatch": "^3.0.5"
+      },
+      "engines": {
+        "node": ">=10.10.0"
+      }
+    },
+    "node_modules/@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.22"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
+    "node_modules/@humanwhocodes/object-schema": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@observablehq/plot": {
+      "version": "0.6.9",
+      "resolved": "https://registry.npmjs.org/@observablehq/plot/-/plot-0.6.9.tgz",
+      "integrity": "sha512-vwV6bzQsGjv2XrPEpc3Voixcz2e5EVvCSzzcs/uW9KXO5ZM8GdMVXtNTaRwYXUOk98nbiYFCFwzMaIyRjrt9IA==",
+      "dependencies": {
+        "d3": "^7.8.0",
+        "interval-tree-1d": "^1.0.0",
+        "isoformat": "^0.2.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@types/json-schema": {
+      "version": "7.0.11",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+      "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+      "dev": true
+    },
+    "node_modules/@types/minimist": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
+      "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
+      "dev": true
+    },
+    "node_modules/@types/normalize-package-data": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
+      "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
+      "dev": true
+    },
+    "node_modules/@types/semver": {
+      "version": "7.5.0",
+      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
+      "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==",
+      "dev": true
+    },
+    "node_modules/@typescript-eslint/eslint-plugin": {
+      "version": "5.59.6",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.6.tgz",
+      "integrity": "sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.4.0",
+        "@typescript-eslint/scope-manager": "5.59.6",
+        "@typescript-eslint/type-utils": "5.59.6",
+        "@typescript-eslint/utils": "5.59.6",
+        "debug": "^4.3.4",
+        "grapheme-splitter": "^1.0.4",
+        "ignore": "^5.2.0",
+        "natural-compare-lite": "^1.4.0",
+        "semver": "^7.3.7",
+        "tsutils": "^3.21.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "@typescript-eslint/parser": "^5.0.0",
+        "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/parser": {
+      "version": "5.59.6",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.6.tgz",
+      "integrity": "sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/scope-manager": "5.59.6",
+        "@typescript-eslint/types": "5.59.6",
+        "@typescript-eslint/typescript-estree": "5.59.6",
+        "debug": "^4.3.4"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/scope-manager": {
+      "version": "5.59.6",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz",
+      "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "5.59.6",
+        "@typescript-eslint/visitor-keys": "5.59.6"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/type-utils": {
+      "version": "5.59.6",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.6.tgz",
+      "integrity": "sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/typescript-estree": "5.59.6",
+        "@typescript-eslint/utils": "5.59.6",
+        "debug": "^4.3.4",
+        "tsutils": "^3.21.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "*"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/types": {
+      "version": "5.59.6",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz",
+      "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/typescript-estree": {
+      "version": "5.59.6",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz",
+      "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "5.59.6",
+        "@typescript-eslint/visitor-keys": "5.59.6",
+        "debug": "^4.3.4",
+        "globby": "^11.1.0",
+        "is-glob": "^4.0.3",
+        "semver": "^7.3.7",
+        "tsutils": "^3.21.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/utils": {
+      "version": "5.59.6",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.6.tgz",
+      "integrity": "sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@types/json-schema": "^7.0.9",
+        "@types/semver": "^7.3.12",
+        "@typescript-eslint/scope-manager": "5.59.6",
+        "@typescript-eslint/types": "5.59.6",
+        "@typescript-eslint/typescript-estree": "5.59.6",
+        "eslint-scope": "^5.1.1",
+        "semver": "^7.3.7"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      }
+    },
+    "node_modules/@typescript-eslint/visitor-keys": {
+      "version": "5.59.6",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz",
+      "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "5.59.6",
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/acorn": {
+      "version": "8.8.2",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+      "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
+      "dev": true,
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "peerDependencies": {
+        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "8.12.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+      "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+      "dev": true,
+      "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/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/array-buffer-byte-length": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
+      "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "is-array-buffer": "^3.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/astral-regex": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/available-typed-arrays": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+      "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz",
+      "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
+      "dev": true
+    },
+    "node_modules/binary-search-bounds": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.5.tgz",
+      "integrity": "sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA=="
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/brace-expansion/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==",
+      "dev": true
+    },
+    "node_modules/braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dev": true,
+      "dependencies": {
+        "fill-range": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      },
+      "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/camelcase-keys": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
+      "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
+      "dev": true,
+      "dependencies": {
+        "camelcase": "^5.3.1",
+        "map-obj": "^4.0.0",
+        "quick-lru": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/colord": {
+      "version": "2.9.3",
+      "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
+      "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+      "dev": true
+    },
+    "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/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+      "dev": true
+    },
+    "node_modules/cosmiconfig": {
+      "version": "8.1.3",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz",
+      "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==",
+      "dev": true,
+      "dependencies": {
+        "import-fresh": "^3.2.1",
+        "js-yaml": "^4.1.0",
+        "parse-json": "^5.0.0",
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/d-fischer"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/cross-spawn/node_modules/which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/css-functions-list": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz",
+      "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.22"
+      }
+    },
+    "node_modules/css-tree": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
+      "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+      "dev": true,
+      "dependencies": {
+        "mdn-data": "2.0.30",
+        "source-map-js": "^1.0.1"
+      },
+      "engines": {
+        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "bin": {
+        "cssesc": "bin/cssesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/d3": {
+      "version": "7.8.5",
+      "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
+      "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
+      "dependencies": {
+        "d3-array": "3",
+        "d3-axis": "3",
+        "d3-brush": "3",
+        "d3-chord": "3",
+        "d3-color": "3",
+        "d3-contour": "4",
+        "d3-delaunay": "6",
+        "d3-dispatch": "3",
+        "d3-drag": "3",
+        "d3-dsv": "3",
+        "d3-ease": "3",
+        "d3-fetch": "3",
+        "d3-force": "3",
+        "d3-format": "3",
+        "d3-geo": "3",
+        "d3-hierarchy": "3",
+        "d3-interpolate": "3",
+        "d3-path": "3",
+        "d3-polygon": "3",
+        "d3-quadtree": "3",
+        "d3-random": "3",
+        "d3-scale": "4",
+        "d3-scale-chromatic": "3",
+        "d3-selection": "3",
+        "d3-shape": "3",
+        "d3-time": "3",
+        "d3-time-format": "4",
+        "d3-timer": "3",
+        "d3-transition": "3",
+        "d3-zoom": "3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-array": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.3.tgz",
+      "integrity": "sha512-JRHwbQQ84XuAESWhvIPaUV4/1UYTBOLiOPGWqgFDHZS1D5QN9c57FbH3QpEnQMYiOXNzKUQyGTZf+EVO7RT5TQ==",
+      "dependencies": {
+        "internmap": "1 - 2"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-axis": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
+      "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-brush": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
+      "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "3",
+        "d3-transition": "3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-chord": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
+      "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
+      "dependencies": {
+        "d3-path": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-color": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+      "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-contour": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz",
+      "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",
+      "dependencies": {
+        "d3-array": "^3.2.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-delaunay": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
+      "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
+      "dependencies": {
+        "delaunator": "5"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-dispatch": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
+      "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-drag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
+      "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "d3-selection": "3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-dsv": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
+      "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
+      "dependencies": {
+        "commander": "7",
+        "iconv-lite": "0.6",
+        "rw": "1"
+      },
+      "bin": {
+        "csv2json": "bin/dsv2json.js",
+        "csv2tsv": "bin/dsv2dsv.js",
+        "dsv2dsv": "bin/dsv2dsv.js",
+        "dsv2json": "bin/dsv2json.js",
+        "json2csv": "bin/json2dsv.js",
+        "json2dsv": "bin/json2dsv.js",
+        "json2tsv": "bin/json2dsv.js",
+        "tsv2csv": "bin/dsv2dsv.js",
+        "tsv2json": "bin/dsv2json.js"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-ease": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+      "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-fetch": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
+      "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
+      "dependencies": {
+        "d3-dsv": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-force": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
+      "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "d3-quadtree": "1 - 3",
+        "d3-timer": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-format": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+      "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-geo": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz",
+      "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==",
+      "dependencies": {
+        "d3-array": "2.5.0 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-hierarchy": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+      "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-interpolate": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+      "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+      "dependencies": {
+        "d3-color": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-path": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-polygon": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
+      "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-quadtree": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
+      "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-random": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
+      "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-scale": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+      "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+      "dependencies": {
+        "d3-array": "2.10.0 - 3",
+        "d3-format": "1 - 3",
+        "d3-interpolate": "1.2.0 - 3",
+        "d3-time": "2.1.1 - 3",
+        "d3-time-format": "2 - 4"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-scale-chromatic": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+      "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+      "dependencies": {
+        "d3-color": "1 - 3",
+        "d3-interpolate": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-selection": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+      "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-shape": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+      "dependencies": {
+        "d3-path": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-time": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+      "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+      "dependencies": {
+        "d3-array": "2 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-time-format": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+      "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+      "dependencies": {
+        "d3-time": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-timer": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+      "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-transition": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
+      "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
+      "dependencies": {
+        "d3-color": "1 - 3",
+        "d3-dispatch": "1 - 3",
+        "d3-ease": "1 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-timer": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "peerDependencies": {
+        "d3-selection": "2 - 3"
+      }
+    },
+    "node_modules/d3-zoom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
+      "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "2 - 3",
+        "d3-transition": "2 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/decamelize-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
+      "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
+      "dev": true,
+      "dependencies": {
+        "decamelize": "^1.1.0",
+        "map-obj": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/decamelize-keys/node_modules/map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/deep-is": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+      "dev": true
+    },
+    "node_modules/define-properties": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
+      "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
+      "dev": true,
+      "dependencies": {
+        "has-property-descriptors": "^1.0.0",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/delaunator": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
+      "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==",
+      "dependencies": {
+        "robust-predicates": "^3.0.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "dev": true,
+      "dependencies": {
+        "esutils": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "node_modules/es-abstract": {
+      "version": "1.21.2",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz",
+      "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==",
+      "dev": true,
+      "dependencies": {
+        "array-buffer-byte-length": "^1.0.0",
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "es-set-tostringtag": "^2.0.1",
+        "es-to-primitive": "^1.2.1",
+        "function.prototype.name": "^1.1.5",
+        "get-intrinsic": "^1.2.0",
+        "get-symbol-description": "^1.0.0",
+        "globalthis": "^1.0.3",
+        "gopd": "^1.0.1",
+        "has": "^1.0.3",
+        "has-property-descriptors": "^1.0.0",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3",
+        "internal-slot": "^1.0.5",
+        "is-array-buffer": "^3.0.2",
+        "is-callable": "^1.2.7",
+        "is-negative-zero": "^2.0.2",
+        "is-regex": "^1.1.4",
+        "is-shared-array-buffer": "^1.0.2",
+        "is-string": "^1.0.7",
+        "is-typed-array": "^1.1.10",
+        "is-weakref": "^1.0.2",
+        "object-inspect": "^1.12.3",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.4",
+        "regexp.prototype.flags": "^1.4.3",
+        "safe-regex-test": "^1.0.0",
+        "string.prototype.trim": "^1.2.7",
+        "string.prototype.trimend": "^1.0.6",
+        "string.prototype.trimstart": "^1.0.6",
+        "typed-array-length": "^1.0.4",
+        "unbox-primitive": "^1.0.2",
+        "which-typed-array": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+      "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.1.3",
+        "has": "^1.0.3",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-to-primitive": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+      "dev": true,
+      "dependencies": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/eslint": {
+      "version": "8.40.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
+      "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.4.0",
+        "@eslint/eslintrc": "^2.0.3",
+        "@eslint/js": "8.40.0",
+        "@humanwhocodes/config-array": "^0.11.8",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
+        "ajv": "^6.10.0",
+        "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.0",
+        "eslint-visitor-keys": "^3.4.1",
+        "espree": "^9.5.2",
+        "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",
+        "grapheme-splitter": "^1.0.4",
+        "ignore": "^5.2.0",
+        "import-fresh": "^3.0.0",
+        "imurmurhash": "^0.1.4",
+        "is-glob": "^4.0.0",
+        "is-path-inside": "^3.0.3",
+        "js-sdsl": "^4.1.4",
+        "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.1",
+        "strip-ansi": "^6.0.1",
+        "strip-json-comments": "^3.1.0",
+        "text-table": "^0.2.0"
+      },
+      "bin": {
+        "eslint": "bin/eslint.js"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint-config-prettier": {
+      "version": "8.8.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz",
+      "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==",
+      "dev": true,
+      "bin": {
+        "eslint-config-prettier": "bin/cli.js"
+      },
+      "peerDependencies": {
+        "eslint": ">=7.0.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/eslint-visitor-keys": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
+      "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint/node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
+      "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/eslint/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==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/eslint/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "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/eslint/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==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/eslint/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==",
+      "dev": true
+    },
+    "node_modules/eslint/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/eslint-scope": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
+      "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/eslint/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==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^6.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/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==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/eslint/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/eslint/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==",
+      "dev": true
+    },
+    "node_modules/eslint/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==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/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==",
+      "dev": true,
+      "dependencies": {
+        "yocto-queue": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/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==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/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==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/espree": {
+      "version": "9.5.2",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
+      "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
+      "dev": true,
+      "dependencies": {
+        "acorn": "^8.8.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^3.4.1"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/esquery": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+      "dev": true,
+      "dependencies": {
+        "estraverse": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/esquery/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.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==",
+      "dev": true,
+      "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==",
+      "dev": true
+    },
+    "node_modules/fast-glob": {
+      "version": "3.2.12",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+      "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+      "dev": true,
+      "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==",
+      "dev": true
+    },
+    "node_modules/fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+      "dev": true
+    },
+    "node_modules/fastest-levenshtein": {
+      "version": "1.0.16",
+      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+      "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.9.1"
+      }
+    },
+    "node_modules/fastq": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+      "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+      "dev": true,
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "node_modules/file-entry-cache": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+      "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+      "dev": true,
+      "dependencies": {
+        "flat-cache": "^3.0.4"
+      },
+      "engines": {
+        "node": "^10.12.0 || >=12.0.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==",
+      "dev": true,
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/flat-cache": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+      "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+      "dev": true,
+      "dependencies": {
+        "flatted": "^3.1.0",
+        "rimraf": "^3.0.2"
+      },
+      "engines": {
+        "node": "^10.12.0 || >=12.0.0"
+      }
+    },
+    "node_modules/flatted": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+      "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
+      "dev": true
+    },
+    "node_modules/for-each": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+      "dev": true,
+      "dependencies": {
+        "is-callable": "^1.1.3"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "node_modules/function.prototype.name": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+      "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.19.0",
+        "functions-have-names": "^1.2.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/functions-have-names": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+      "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-symbol-description": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
+      "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "dependencies": {
+        "ini": "^1.3.5",
+        "kind-of": "^6.0.2",
+        "which": "^1.3.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/globals": {
+      "version": "13.20.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+      "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/globals/node_modules/type-fest": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/globalthis": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+      "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.1.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/globby": {
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+      "dev": true,
+      "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/globjoin": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+      "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==",
+      "dev": true
+    },
+    "node_modules/gopd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+      "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.1.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+      "dev": true
+    },
+    "node_modules/hard-rejection": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
+      "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-bigints": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+      "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/has-property-descriptors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+      "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.1.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+      "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+      "dev": true,
+      "dependencies": {
+        "has-symbols": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hosted-git-info": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ignore": {
+      "version": "5.2.4",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+      "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/import-fresh/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "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==",
+      "dev": true,
+      "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==",
+      "dev": true
+    },
+    "node_modules/ini": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+      "dev": true
+    },
+    "node_modules/internal-slot": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
+      "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.2.0",
+        "has": "^1.0.3",
+        "side-channel": "^1.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/internmap": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+      "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/interval-tree-1d": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/interval-tree-1d/-/interval-tree-1d-1.0.4.tgz",
+      "integrity": "sha512-wY8QJH+6wNI0uh4pDQzMvl+478Qh7Rl4qLmqiluxALlNvl+I+o5x38Pw3/z7mDPTPS1dQalZJXsmbvxx5gclhQ==",
+      "dependencies": {
+        "binary-search-bounds": "^2.0.0"
+      }
+    },
+    "node_modules/is-array-buffer": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
+      "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.2.0",
+        "is-typed-array": "^1.1.10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/is-bigint": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+      "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+      "dev": true,
+      "dependencies": {
+        "has-bigints": "^1.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-boolean-object": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+      "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-callable": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
+      "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-date-object": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-negative-zero": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+      "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-number-object": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+      "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-regex": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-shared-array-buffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+      "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-string": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+      "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-symbol": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+      "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+      "dev": true,
+      "dependencies": {
+        "has-symbols": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-typed-array": {
+      "version": "1.1.10",
+      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+      "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
+      "dev": true,
+      "dependencies": {
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-weakref": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+      "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+      "dev": true
+    },
+    "node_modules/isoformat": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/isoformat/-/isoformat-0.2.1.tgz",
+      "integrity": "sha512-tFLRAygk9NqrRPhJSnNGh7g7oaVWDwR0wKh/GM2LgmPa50Eg4UfyaCO4I8k6EqJHl1/uh2RAD6g06n5ygEnrjQ=="
+    },
+    "node_modules/js-sdsl": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
+      "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
+      "dev": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/js-sdsl"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
+    "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==",
+      "dev": true
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/known-css-properties": {
+      "version": "0.27.0",
+      "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz",
+      "integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==",
+      "dev": true
+    },
+    "node_modules/levn": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "^1.2.1",
+        "type-check": "~0.4.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/load-json-file": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+      "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "parse-json": "^4.0.0",
+        "pify": "^3.0.0",
+        "strip-bom": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/load-json-file/node_modules/parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+      "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+      "dev": true,
+      "dependencies": {
+        "error-ex": "^1.3.1",
+        "json-parse-better-errors": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/lodash.merge": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+      "dev": true
+    },
+    "node_modules/lodash.truncate": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+      "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/map-obj": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
+      "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/mathml-tag-names": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
+      "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==",
+      "dev": true,
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/mdn-data": {
+      "version": "2.0.30",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+      "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
+      "dev": true
+    },
+    "node_modules/memorystream": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+      "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/meow": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
+      "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/minimist": "^1.2.0",
+        "camelcase-keys": "^6.2.2",
+        "decamelize": "^1.2.0",
+        "decamelize-keys": "^1.1.0",
+        "hard-rejection": "^2.1.0",
+        "minimist-options": "4.1.0",
+        "normalize-package-data": "^3.0.0",
+        "read-pkg-up": "^7.0.1",
+        "redent": "^3.0.0",
+        "trim-newlines": "^3.0.0",
+        "type-fest": "^0.18.0",
+        "yargs-parser": "^20.2.3"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+      "dev": true,
+      "dependencies": {
+        "braces": "^3.0.2",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/min-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+      "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/minimist-options": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
+      "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
+      "dev": true,
+      "dependencies": {
+        "arrify": "^1.0.1",
+        "is-plain-obj": "^1.1.0",
+        "kind-of": "^6.0.3"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+      "dev": true,
+      "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/natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+      "dev": true
+    },
+    "node_modules/natural-compare-lite": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+      "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
+      "dev": true
+    },
+    "node_modules/nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
+    },
+    "node_modules/normalize-package-data": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
+      "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^4.0.1",
+        "is-core-module": "^2.5.0",
+        "semver": "^7.3.4",
+        "validate-npm-package-license": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/npm-run-all": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
+      "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "chalk": "^2.4.1",
+        "cross-spawn": "^6.0.5",
+        "memorystream": "^0.3.1",
+        "minimatch": "^3.0.4",
+        "pidtree": "^0.3.0",
+        "read-pkg": "^3.0.0",
+        "shell-quote": "^1.6.1",
+        "string.prototype.padend": "^3.0.0"
+      },
+      "bin": {
+        "npm-run-all": "bin/npm-run-all/index.js",
+        "run-p": "bin/run-p/index.js",
+        "run-s": "bin/run-s/index.js"
+      },
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/npm-run-all/node_modules/cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/npm-run-all/node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true
+    },
+    "node_modules/npm-run-all/node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/npm-run-all/node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/npm-run-all/node_modules/path-type": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+      "dev": true,
+      "dependencies": {
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/npm-run-all/node_modules/read-pkg": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+      "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
+      "dev": true,
+      "dependencies": {
+        "load-json-file": "^4.0.0",
+        "normalize-package-data": "^2.3.2",
+        "path-type": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/npm-run-all/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/npm-run-all/node_modules/shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/npm-run-all/node_modules/shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.12.3",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+      "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.assign": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
+      "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.4",
+        "has-symbols": "^1.0.3",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/optionator": {
+      "version": "0.9.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+      "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+      "dev": true,
+      "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"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "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==",
+      "dev": true,
+      "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/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "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==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "dev": true
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/pidtree": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
+      "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
+      "dev": true,
+      "bin": {
+        "pidtree": "bin/pidtree.js"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.4.23",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
+      "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
+      "dev": true,
+      "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.6",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/postcss-media-query-parser": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
+      "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
+      "dev": true
+    },
+    "node_modules/postcss-resolve-nested-selector": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
+      "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==",
+      "dev": true
+    },
+    "node_modules/postcss-safe-parser": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
+      "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/postcss/"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3.3"
+      }
+    },
+    "node_modules/postcss-selector-parser": {
+      "version": "6.0.13",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
+      "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
+      "dev": true,
+      "dependencies": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/prelude-ls": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/prettier": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+      "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "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==",
+      "dev": true,
+      "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": "4.0.1",
+      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
+      "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+      "dev": true,
+      "dependencies": {
+        "@types/normalize-package-data": "^2.4.0",
+        "normalize-package-data": "^2.5.0",
+        "parse-json": "^5.0.0",
+        "type-fest": "^0.6.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^4.1.0",
+        "read-pkg": "^5.2.0",
+        "type-fest": "^0.8.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/type-fest": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg/node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true
+    },
+    "node_modules/read-pkg/node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/read-pkg/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/read-pkg/node_modules/type-fest": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/redent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+      "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+      "dev": true,
+      "dependencies": {
+        "indent-string": "^4.0.0",
+        "strip-indent": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/regexp.prototype.flags": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
+      "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "functions-have-names": "^1.2.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/resolve": {
+      "version": "1.22.2",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
+      "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.11.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-from": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/reusify": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/robust-predicates": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz",
+      "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g=="
+    },
+    "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==",
+      "dev": true,
+      "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/rw": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+      "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
+    },
+    "node_modules/safe-regex-test": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
+      "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.1.3",
+        "is-regex": "^1.1.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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.5.4",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+      "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/signal-exit": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+      "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/slash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/slice-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+      }
+    },
+    "node_modules/slice-ansi/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==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/slice-ansi/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==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/slice-ansi/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==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/spdx-correct": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+      "dev": true,
+      "dependencies": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-exceptions": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+      "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+      "dev": true
+    },
+    "node_modules/spdx-expression-parse": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+      "dev": true,
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.13",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
+      "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/string.prototype.padend": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz",
+      "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.4",
+        "es-abstract": "^1.20.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trim": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz",
+      "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.4",
+        "es-abstract": "^1.20.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trimend": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
+      "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.4",
+        "es-abstract": "^1.20.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trimstart": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz",
+      "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.4",
+        "es-abstract": "^1.20.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/strip-bom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/strip-indent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+      "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+      "dev": true,
+      "dependencies": {
+        "min-indent": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/style-search": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
+      "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==",
+      "dev": true
+    },
+    "node_modules/stylelint": {
+      "version": "15.6.2",
+      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.6.2.tgz",
+      "integrity": "sha512-fjQWwcdUye4DU+0oIxNGwawIPC5DvG5kdObY5Sg4rc87untze3gC/5g/ikePqVjrAsBUZjwMN+pZsAYbDO6ArQ==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/css-parser-algorithms": "^2.1.1",
+        "@csstools/css-tokenizer": "^2.1.1",
+        "@csstools/media-query-list-parser": "^2.0.4",
+        "@csstools/selector-specificity": "^2.2.0",
+        "balanced-match": "^2.0.0",
+        "colord": "^2.9.3",
+        "cosmiconfig": "^8.1.3",
+        "css-functions-list": "^3.1.0",
+        "css-tree": "^2.3.1",
+        "debug": "^4.3.4",
+        "fast-glob": "^3.2.12",
+        "fastest-levenshtein": "^1.0.16",
+        "file-entry-cache": "^6.0.1",
+        "global-modules": "^2.0.0",
+        "globby": "^11.1.0",
+        "globjoin": "^0.1.4",
+        "html-tags": "^3.3.1",
+        "ignore": "^5.2.4",
+        "import-lazy": "^4.0.0",
+        "imurmurhash": "^0.1.4",
+        "is-plain-object": "^5.0.0",
+        "known-css-properties": "^0.27.0",
+        "mathml-tag-names": "^2.1.3",
+        "meow": "^9.0.0",
+        "micromatch": "^4.0.5",
+        "normalize-path": "^3.0.0",
+        "picocolors": "^1.0.0",
+        "postcss": "^8.4.23",
+        "postcss-media-query-parser": "^0.2.3",
+        "postcss-resolve-nested-selector": "^0.1.1",
+        "postcss-safe-parser": "^6.0.0",
+        "postcss-selector-parser": "^6.0.12",
+        "postcss-value-parser": "^4.2.0",
+        "resolve-from": "^5.0.0",
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1",
+        "style-search": "^0.1.0",
+        "supports-hyperlinks": "^3.0.0",
+        "svg-tags": "^1.0.0",
+        "table": "^6.8.1",
+        "v8-compile-cache": "^2.3.0",
+        "write-file-atomic": "^5.0.1"
+      },
+      "bin": {
+        "stylelint": "bin/stylelint.js"
+      },
+      "engines": {
+        "node": "^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/stylelint"
+      }
+    },
+    "node_modules/stylelint-config-recommended": {
+      "version": "12.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-12.0.0.tgz",
+      "integrity": "sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==",
+      "dev": true,
+      "peerDependencies": {
+        "stylelint": "^15.5.0"
+      }
+    },
+    "node_modules/stylelint-config-standard": {
+      "version": "33.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-33.0.0.tgz",
+      "integrity": "sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==",
+      "dev": true,
+      "dependencies": {
+        "stylelint-config-recommended": "^12.0.0"
+      },
+      "peerDependencies": {
+        "stylelint": "^15.5.0"
+      }
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/supports-hyperlinks": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
+      "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0",
+        "supports-color": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=14.18"
+      }
+    },
+    "node_modules/supports-hyperlinks/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/supports-hyperlinks/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==",
+      "dev": true,
+      "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==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/svg-tags": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+      "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
+      "dev": true
+    },
+    "node_modules/table": {
+      "version": "6.8.1",
+      "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz",
+      "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^8.0.1",
+        "lodash.truncate": "^4.4.2",
+        "slice-ansi": "^4.0.0",
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "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==",
+      "dev": true,
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/trim-newlines": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
+      "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+      "dev": true
+    },
+    "node_modules/tsutils": {
+      "version": "3.21.0",
+      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+      "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+      "dev": true,
+      "dependencies": {
+        "tslib": "^1.8.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      },
+      "peerDependencies": {
+        "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+      }
+    },
+    "node_modules/type-check": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/type-fest": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/typed-array-length": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
+      "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "is-typed-array": "^1.1.9"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
+      "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=12.20"
+      }
+    },
+    "node_modules/unbox-primitive": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+      "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-bigints": "^1.0.2",
+        "has-symbols": "^1.0.3",
+        "which-boxed-primitive": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/v8-compile-cache": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+      "dev": true
+    },
+    "node_modules/validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "dependencies": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/which-boxed-primitive": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+      "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+      "dev": true,
+      "dependencies": {
+        "is-bigint": "^1.0.1",
+        "is-boolean-object": "^1.1.0",
+        "is-number-object": "^1.0.4",
+        "is-string": "^1.0.5",
+        "is-symbol": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-typed-array": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+      "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
+      "dev": true,
+      "dependencies": {
+        "available-typed-arrays": "^1.0.5",
+        "call-bind": "^1.0.2",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-tostringtag": "^1.0.0",
+        "is-typed-array": "^1.1.10"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "node_modules/write-file-atomic": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
+      "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
+      "dev": true,
+      "dependencies": {
+        "imurmurhash": "^0.1.4",
+        "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
+    "node_modules/yargs-parser": {
+      "version": "20.2.9",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    }
+  }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/package.json b/src/cmd/vendor/golang.org/x/telemetry/package.json
new file mode 100644 (file)
index 0000000..3680ce2
--- /dev/null
@@ -0,0 +1,23 @@
+{
+  "scripts": {
+    "eslint": "eslint . --fix",
+    "stylelint": "stylelint '**/*.css' --fix",
+    "prettier": "prettier --write **/*.{css,ts,md,yaml} !**/*.min.css",
+    "all": "run-s --continue-on-error eslint stylelint prettier"
+  },
+  "devDependencies": {
+    "@typescript-eslint/eslint-plugin": "5.59.6",
+    "@typescript-eslint/parser": "5.59.6",
+    "eslint": "8.40.0",
+    "eslint-config-prettier": "8.8.0",
+    "npm-run-all": "4.1.5",
+    "prettier": "2.8.8",
+    "stylelint": "15.6.2",
+    "stylelint-config-standard": "33.0.0",
+    "typescript": "5.0.4"
+  },
+  "dependencies": {
+    "@observablehq/plot": "0.6.9",
+    "d3": "7.8.5"
+  }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/start.go b/src/cmd/vendor/golang.org/x/telemetry/start.go
new file mode 100644 (file)
index 0000000..7f806c6
--- /dev/null
@@ -0,0 +1,213 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package telemetry
+
+import (
+       "fmt"
+       "log"
+       "os"
+       "os/exec"
+       "path/filepath"
+       "time"
+
+       "golang.org/x/sync/errgroup"
+       "golang.org/x/telemetry/counter"
+       "golang.org/x/telemetry/internal/crashmonitor"
+       "golang.org/x/telemetry/internal/telemetry"
+       "golang.org/x/telemetry/upload"
+)
+
+// Config controls the behavior of [Start].
+type Config struct {
+       // ReportCrashes, if set, will enable crash reporting.
+       // ReportCrashes uses the [debug.SetCrashOutput] mechanism, which is a
+       // process-wide resource.
+       // Do not make other calls to that function within your application.
+       // ReportCrashes is a non-functional unless the program is built with go1.23+.
+       ReportCrashes bool
+
+       // Upload causes this program to periodically upload approved counters
+       // from the local telemetry database to telemetry.go.dev.
+       //
+       // This option has no effect unless the user has given consent
+       // to enable data collection, for example by running
+       // cmd/gotelemetry or affirming the gopls dialog.
+       //
+       // (This feature is expected to be used only by gopls.
+       // Longer term, the go command may become the sole program
+       // responsible for uploading.)
+       Upload bool
+}
+
+// Start initializes telemetry using the specified configuration.
+//
+// Start opens the local telemetry database so that counter increment
+// operations are durably recorded in the local file system.
+//
+// If [Config.Upload] is set, and the user has opted in to telemetry
+// uploading, this process may attempt to upload approved counters
+// to telemetry.go.dev.
+//
+// If [Config.ReportCrashes] is set, any fatal crash will be
+// recorded by incrementing a counter named for the stack of the
+// first running goroutine in the traceback.
+//
+// If either of these flags is set, Start re-executes the current
+// executable as a child process, in a special mode in which it
+// acts as a telemetry sidecar for the parent process (the application).
+// In that mode, the call to Start will never return, so Start must
+// be called immediately within main, even before such things as
+// inspecting the command line. The application should avoid expensive
+// steps or external side effects in init functions, as they will
+// be executed twice (parent and child).
+func Start(config Config) {
+       counter.Open()
+
+       // Crash monitoring and uploading both require a sidecar process.
+       if (config.ReportCrashes && crashmonitor.Supported()) || config.Upload {
+               if os.Getenv(telemetryChildVar) != "" {
+                       child(config)
+                       os.Exit(0)
+               }
+
+               parent(config)
+       }
+}
+
+var daemonize = func(cmd *exec.Cmd) {}
+
+const telemetryChildVar = "X_TELEMETRY_CHILD"
+
+func parent(config Config) {
+       // This process is the application (parent).
+       // Fork+exec the telemetry child.
+       exe, err := os.Executable()
+       if err != nil {
+               log.Fatal(err)
+       }
+       cmd := exec.Command(exe, "** telemetry **") // this unused arg is just for ps(1)
+       daemonize(cmd)
+       cmd.Env = append(os.Environ(), telemetryChildVar+"=1")
+
+       // The child process must write to a log file, not
+       // the stderr file it inherited from the parent, as
+       // the child may outlive the parent but should not prolong
+       // the life of any pipes created (by the grandparent)
+       // to gather the output of the parent.
+       //
+       // By default, we discard the child process's stderr,
+       // but in line with the uploader, log to a file in local/debug
+       // only if that directory was created by the user.
+       localDebug := filepath.Join(telemetry.LocalDir, "debug")
+       fd, err := os.Stat(localDebug)
+       if err != nil {
+               if !os.IsNotExist(err) {
+                       log.Fatalf("failed to stat debug directory: %v", err)
+               }
+       } else if fd.IsDir() {
+               // local/debug exists and is a directory. Set stderr to a log file path
+               // in local/debug.
+               childLogPath := filepath.Join(localDebug, "sidecar.log")
+               childLog, err := os.OpenFile(childLogPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
+               if err != nil {
+                       log.Fatalf("opening sidecar log file for child: %v", err)
+               }
+               defer childLog.Close()
+               cmd.Stderr = childLog
+       }
+
+       if config.ReportCrashes {
+               pipe, err := cmd.StdinPipe()
+               if err != nil {
+                       log.Fatalf("StdinPipe: %v", err)
+               }
+
+               crashmonitor.Parent(pipe.(*os.File)) // (this conversion is safe)
+       }
+
+       if err := cmd.Start(); err != nil {
+               log.Fatalf("can't start telemetry child process: %v", err)
+       }
+       go cmd.Wait() // Release resources if cmd happens not to outlive this process.
+}
+
+func child(config Config) {
+       log.SetPrefix(fmt.Sprintf("telemetry-sidecar (pid %v): ", os.Getpid()))
+
+       // Start crashmonitoring and uploading depending on what's requested
+       // and wait for the longer running child to complete before exiting:
+       // if we collected a crash before the upload finished, wait for the
+       // upload to finish before exiting
+       var g errgroup.Group
+
+       if config.Upload {
+               g.Go(func() error {
+                       uploaderChild()
+                       return nil
+               })
+       }
+       if config.ReportCrashes {
+               g.Go(func() error {
+                       crashmonitor.Child()
+                       return nil
+               })
+       }
+       g.Wait()
+}
+
+func uploaderChild() {
+       tokenfilepath := filepath.Join(telemetry.LocalDir, "upload.token")
+       ok, err := acquireUploadToken(tokenfilepath)
+       if err != nil {
+               log.Printf("error acquiring upload token: %v", err)
+               return
+       } else if !ok {
+               // It hasn't been a day since the last upload.Run attempt or there's
+               // a concurrently running uploader.
+               return
+       }
+       upload.Run(&upload.Control{Logger: os.Stderr})
+}
+
+// acquireUploadToken acquires a token permitting the caller to upload.
+// To limit the frequency of uploads, only one token is issue per
+// machine per time period.
+// The boolean indicates whether the token was acquired.
+func acquireUploadToken(tokenfile string) (bool, error) {
+       const period = 24 * time.Hour
+
+       // A process acquires a token by successfully creating a
+       // well-known file. If the file already exists and has an
+       // mtime age less then than the period, the process does
+       // not acquire the token. If the file is older than the
+       // period, the process is allowed to remove the file and
+       // try to re-create it.
+       fi, err := os.Stat(tokenfile)
+       if err == nil {
+               if time.Since(fi.ModTime()) < period {
+                       return false, nil
+               }
+               // There's a possible race here where two processes check the
+               // token file and see that it's older than the period, then the
+               // first one removes it and creates another, and then a second one
+               // removes the newly created file and creates yet another
+               // file. Then both processes would act as though they had the token.
+               // This is very rare, but it's also okay because we're only grabbing
+               // the token to do rate limiting, not for correctness.
+               _ = os.Remove(tokenfile)
+       } else if !os.IsNotExist(err) {
+               return false, fmt.Errorf("statting token file: %v", err)
+       }
+
+       f, err := os.OpenFile(tokenfile, os.O_CREATE|os.O_EXCL, 0666)
+       if err != nil {
+               if os.IsExist(err) {
+                       return false, nil
+               }
+               return false, fmt.Errorf("creating token file: %v", err)
+       }
+       _ = f.Close()
+       return true, nil
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/start_posix.go b/src/cmd/vendor/golang.org/x/telemetry/start_posix.go
new file mode 100644 (file)
index 0000000..078b235
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+
+package telemetry
+
+import (
+       "os/exec"
+       "syscall"
+)
+
+func init() {
+       daemonize = daemonizePosix
+}
+
+func daemonizePosix(cmd *exec.Cmd) {
+       cmd.SysProcAttr = &syscall.SysProcAttr{
+               Setsid: true,
+       }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/start_windows.go b/src/cmd/vendor/golang.org/x/telemetry/start_windows.go
new file mode 100644 (file)
index 0000000..ceb2c02
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build windows
+
+package telemetry
+
+import (
+       "os/exec"
+       "syscall"
+
+       "golang.org/x/sys/windows"
+)
+
+func init() {
+       daemonize = daemonizeWindows
+}
+
+func daemonizeWindows(cmd *exec.Cmd) {
+       // Set DETACHED_PROCESS creation flag so that closing
+       // the console window the parent process was run in
+       // does not kill the child.
+       // See documentation of creation flags in the Microsoft documentation:
+       // https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
+       cmd.SysProcAttr = &syscall.SysProcAttr{
+               CreationFlags: windows.DETACHED_PROCESS,
+       }
+}
diff --git a/src/cmd/vendor/golang.org/x/telemetry/tsconfig.json b/src/cmd/vendor/golang.org/x/telemetry/tsconfig.json
new file mode 100644 (file)
index 0000000..7833e31
--- /dev/null
@@ -0,0 +1,26 @@
+{
+  /* Visit https://aka.ms/tsconfig.json to read more about this file */
+  "compilerOptions": {
+    "target": "ES2022",
+    "module": "ES2022",
+    "moduleResolution": "node",
+
+    "strict": true,
+    "allowUnusedLabels": false,
+    "allowUnreachableCode": false,
+    "exactOptionalPropertyTypes": true,
+    "noFallthroughCasesInSwitch": true,
+    "noImplicitOverride": true,
+    "noImplicitReturns": true,
+    "noPropertyAccessFromIndexSignature": true,
+    "noUncheckedIndexedAccess": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+
+    "checkJs": true,
+
+    "esModuleInterop": true,
+    "skipLibCheck": true,
+    "forceConsistentCasingInFileNames": true
+  },
+}
\ No newline at end of file
diff --git a/src/cmd/vendor/golang.org/x/telemetry/types_alias.go b/src/cmd/vendor/golang.org/x/telemetry/types_alias.go
new file mode 100644 (file)
index 0000000..83ba7e0
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package telemetry
+
+import "golang.org/x/telemetry/internal/telemetry"
+
+// Common types and directories used by multiple packages.
+
+// An UploadConfig controls what data is uploaded.
+type UploadConfig = telemetry.UploadConfig
+
+type ProgramConfig = telemetry.ProgramConfig
+
+type CounterConfig = telemetry.CounterConfig
+
+// A Report is what's uploaded (or saved locally)
+type Report = telemetry.Report
+
+type ProgramReport = telemetry.ProgramReport
diff --git a/src/cmd/vendor/golang.org/x/telemetry/upload/upload.go b/src/cmd/vendor/golang.org/x/telemetry/upload/upload.go
new file mode 100644 (file)
index 0000000..122b725
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package upload
+
+import (
+       "io"
+       "log"
+
+       "golang.org/x/telemetry/internal/upload"
+)
+
+// Run generates and uploads reports, as allowed by the mode file.
+// A nil Control is legal.
+func Run(c *Control) {
+       if c != nil && c.Logger != nil {
+               upload.SetLogOutput(c.Logger)
+       }
+       // ignore error: failed logging should not block uploads
+       upload.LogIfDebug("")
+
+       defer func() {
+               if err := recover(); err != nil {
+                       log.Printf("upload recover: %v", err)
+               }
+       }()
+       upload.NewUploader(nil).Run()
+}
+
+// A Control allows the user to override various default
+// reporting and uploading choices.
+// Future versions may also allow the user to set the upload URL.
+type Control struct {
+       // Logger provides a io.Writer for error messages during uploading
+       // nil is legal and no log messages get generated
+       Logger io.Writer
+}
index 642c0608eb13be31fca9e52d9a0fb627811fb19f..6f3b61d878ec5e5f8a257cb576ca13e926fcc51e 100644 (file)
@@ -38,6 +38,7 @@ golang.org/x/mod/sumdb/tlog
 golang.org/x/mod/zip
 # golang.org/x/sync v0.6.0
 ## explicit; go 1.18
+golang.org/x/sync/errgroup
 golang.org/x/sync/semaphore
 # golang.org/x/sys v0.17.0
 ## explicit; go 1.18
@@ -46,10 +47,17 @@ golang.org/x/sys/unix
 golang.org/x/sys/windows
 # golang.org/x/telemetry v0.0.0-20240229223025-3d5706d2d0fb
 ## explicit; go 1.20
+golang.org/x/telemetry
 golang.org/x/telemetry/counter
+golang.org/x/telemetry/counter/countertest
+golang.org/x/telemetry/internal/config
+golang.org/x/telemetry/internal/configstore
 golang.org/x/telemetry/internal/counter
+golang.org/x/telemetry/internal/crashmonitor
 golang.org/x/telemetry/internal/mmap
 golang.org/x/telemetry/internal/telemetry
+golang.org/x/telemetry/internal/upload
+golang.org/x/telemetry/upload
 # golang.org/x/term v0.17.0
 ## explicit; go 1.18
 golang.org/x/term