diff --git a/go.mod b/go.mod
index 58aefd19..de0355cc 100644
--- a/go.mod
+++ b/go.mod
@@ -24,6 +24,7 @@ require (
github.com/oapi-codegen/runtime v1.1.1
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/pkg/errors v0.9.1
+ github.com/samber/lo v1.47.0
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.18.2
diff --git a/go.sum b/go.sum
index cada5711..bb0dd108 100644
--- a/go.sum
+++ b/go.sum
@@ -275,6 +275,8 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y=
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
+github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
+github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
diff --git a/internal/dev_server/adapters/api.go b/internal/dev_server/adapters/api.go
index 6833d32e..308ef224 100644
--- a/internal/dev_server/adapters/api.go
+++ b/internal/dev_server/adapters/api.go
@@ -2,6 +2,9 @@ package adapters
import (
"context"
+ "log"
+ "net/url"
+ "strconv"
ldapi "github.com/launchdarkly/api-client-go/v14"
"github.com/pkg/errors"
@@ -20,6 +23,7 @@ func GetApi(ctx context.Context) Api {
//go:generate go run go.uber.org/mock/mockgen -destination mocks/api.go -package mocks . Api
type Api interface {
GetSdkKey(ctx context.Context, projectKey, environmentKey string) (string, error)
+ GetAllFlags(ctx context.Context, projectKey string) ([]ldapi.FeatureFlag, error)
}
type apiClientApi struct {
@@ -31,9 +35,73 @@ func NewApi(client ldapi.APIClient) Api {
}
func (a apiClientApi) GetSdkKey(ctx context.Context, projectKey, environmentKey string) (string, error) {
+ log.Printf("GetSdkKey - projectKey: %s, environmentKey: %s", projectKey, environmentKey)
environment, _, err := a.apiClient.EnvironmentsApi.GetEnvironment(ctx, projectKey, environmentKey).Execute()
if err != nil {
return "", errors.Wrap(err, "unable to get SDK key from LD API")
}
return environment.ApiKey, nil
}
+
+func (a apiClientApi) GetAllFlags(ctx context.Context, projectKey string) ([]ldapi.FeatureFlag, error) {
+ log.Printf("Fetching all flags for project '%s'", projectKey)
+ flags, err := a.getFlags(ctx, projectKey, nil)
+ if err != nil {
+ err = errors.Wrap(err, "unable to get all flags from LD API")
+ }
+ return flags, err
+}
+
+func (a apiClientApi) getFlags(ctx context.Context, projectKey string, href *string) ([]ldapi.FeatureFlag, error) {
+ var featureFlags *ldapi.FeatureFlags
+ var err error
+ if href == nil {
+ featureFlags, _, err = a.apiClient.FeatureFlagsApi.GetFeatureFlags(ctx, projectKey).
+ Summary(false).
+ Execute()
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ limit, offset, err := parseHref(*href)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to parse href for next link: %s", *href)
+ }
+ featureFlags, _, err = a.apiClient.FeatureFlagsApi.GetFeatureFlags(ctx, projectKey).
+ Summary(false).
+ Limit(limit).
+ Offset(offset).
+ Execute()
+ if err != nil {
+ return nil, err
+ }
+ }
+ flags := featureFlags.Items
+ if next, ok := featureFlags.Links["next"]; ok && next.Href != nil {
+ newFlags, err := a.getFlags(ctx, projectKey, next.Href)
+ if err != nil {
+ return nil, err
+ }
+ flags = append(flags, newFlags...)
+ }
+ return flags, nil
+}
+
+func parseHref(href string) (limit, offset int64, err error) {
+ parsedUrl, err := url.Parse(href)
+ if err != nil {
+ return
+ }
+ l, err := strconv.Atoi(parsedUrl.Query().Get("limit"))
+ if err != nil {
+ return
+ }
+ o, err := strconv.Atoi(parsedUrl.Query().Get("offset"))
+ if err != nil {
+ return
+ }
+
+ limit = int64(l)
+ offset = int64(o)
+ return
+}
diff --git a/internal/dev_server/adapters/mocks/api.go b/internal/dev_server/adapters/mocks/api.go
index efacb902..26d75bc6 100644
--- a/internal/dev_server/adapters/mocks/api.go
+++ b/internal/dev_server/adapters/mocks/api.go
@@ -13,6 +13,7 @@ import (
context "context"
reflect "reflect"
+ ldapi "github.com/launchdarkly/api-client-go/v14"
gomock "go.uber.org/mock/gomock"
)
@@ -39,6 +40,21 @@ func (m *MockApi) EXPECT() *MockApiMockRecorder {
return m.recorder
}
+// GetAllFlags mocks base method.
+func (m *MockApi) GetAllFlags(arg0 context.Context, arg1 string) ([]ldapi.FeatureFlag, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetAllFlags", arg0, arg1)
+ ret0, _ := ret[0].([]ldapi.FeatureFlag)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetAllFlags indicates an expected call of GetAllFlags.
+func (mr *MockApiMockRecorder) GetAllFlags(arg0, arg1 any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllFlags", reflect.TypeOf((*MockApi)(nil).GetAllFlags), arg0, arg1)
+}
+
// GetSdkKey mocks base method.
func (m *MockApi) GetSdkKey(arg0 context.Context, arg1, arg2 string) (string, error) {
m.ctrl.T.Helper()
diff --git a/internal/dev_server/api/api.yaml b/internal/dev_server/api/api.yaml
index 6bd6e55d..bdb9c89e 100644
--- a/internal/dev_server/api/api.yaml
+++ b/internal/dev_server/api/api.yaml
@@ -28,7 +28,7 @@ paths:
summary: updates the flag state for the given project and source environment
parameters:
- $ref: "#/components/parameters/projectKey"
- - $ref: "#/components/parameters/expand"
+ - $ref: "#/components/parameters/projectExpand"
responses:
200:
$ref: "#/components/responses/Project"
@@ -39,7 +39,7 @@ paths:
summary: get the specified project and its configuration for syncing from the LaunchDarkly Service
parameters:
- $ref: "#/components/parameters/projectKey"
- - $ref: "#/components/parameters/expand"
+ - $ref: "#/components/parameters/projectExpand"
responses:
200:
$ref: "#/components/responses/Project"
@@ -49,7 +49,7 @@ paths:
summary: updates the project context or sourceEnvironmentKey
parameters:
- $ref: "#/components/parameters/projectKey"
- - $ref: "#/components/parameters/expand"
+ - $ref: "#/components/parameters/projectExpand"
requestBody:
content:
application/json:
@@ -79,7 +79,7 @@ paths:
summary: Add the project to the dev server
parameters:
- $ref: "#/components/parameters/projectKey"
- - $ref: "#/components/parameters/expand"
+ - $ref: "#/components/parameters/projectExpand"
requestBody:
content:
application/json:
@@ -143,7 +143,7 @@ components:
required: true
schema:
type: string
- expand:
+ projectExpand:
name: expand
description: Available expand options for this endpoint.
in: query
@@ -153,6 +153,7 @@ components:
type: string
enum:
- overrides
+ - availableVariations
schemas:
FlagValue:
description: value of a feature flag variation
@@ -173,6 +174,20 @@ components:
default:
key: "dev-environment"
kind: "user"
+ Variation:
+ description: variation of a flag
+ required:
+ - _id
+ - value
+ properties:
+ _id:
+ type: string
+ name:
+ type: string
+ description:
+ type: string
+ value:
+ $ref: '#/components/schemas/FlagValue'
Project:
description: Project
type: object
@@ -194,10 +209,17 @@ components:
path: github.com/launchdarkly/ldcli/internal/dev_server/model
overrides:
type: object
- description: flags and their values and version for a given project in the source environment
+ description: overridden flags for the project
x-go-type: model.FlagsState
x-go-type-import:
path: github.com/launchdarkly/ldcli/internal/dev_server/model
+ availableVariations:
+ type: object
+ description: variations
+ additionalProperties:
+ type: array
+ items:
+ $ref: '#/components/schemas/Variation'
_lastSyncedFromSource:
type: integer
x-go-type: int64
diff --git a/internal/dev_server/api/data_mapping.go b/internal/dev_server/api/data_mapping.go
new file mode 100644
index 00000000..57aead5b
--- /dev/null
+++ b/internal/dev_server/api/data_mapping.go
@@ -0,0 +1,20 @@
+package api
+
+import "github.com/launchdarkly/ldcli/internal/dev_server/model"
+
+func availableVariationsToResponseFormat(availableVariations map[string][]model.Variation) map[string][]Variation {
+ respAvailableVariations := make(map[string][]Variation, len(availableVariations))
+ for flagKey, variationsForFlag := range availableVariations {
+ respVariationsForFlag := make([]Variation, 0, len(variationsForFlag))
+ for _, variation := range variationsForFlag {
+ respVariationsForFlag = append(respVariationsForFlag, Variation{
+ Id: variation.Id,
+ Description: variation.Description,
+ Name: variation.Name,
+ Value: variation.Value,
+ })
+ }
+ respAvailableVariations[flagKey] = respVariationsForFlag
+ }
+ return respAvailableVariations
+}
diff --git a/internal/dev_server/api/server.gen.go b/internal/dev_server/api/server.gen.go
index 5d522be1..aef4e550 100644
--- a/internal/dev_server/api/server.gen.go
+++ b/internal/dev_server/api/server.gen.go
@@ -19,22 +19,26 @@ import (
// Defines values for GetDevProjectsProjectKeyParamsExpand.
const (
- GetDevProjectsProjectKeyParamsExpandOverrides GetDevProjectsProjectKeyParamsExpand = "overrides"
+ GetDevProjectsProjectKeyParamsExpandAvailableVariations GetDevProjectsProjectKeyParamsExpand = "availableVariations"
+ GetDevProjectsProjectKeyParamsExpandOverrides GetDevProjectsProjectKeyParamsExpand = "overrides"
)
// Defines values for PatchDevProjectsProjectKeyParamsExpand.
const (
- PatchDevProjectsProjectKeyParamsExpandOverrides PatchDevProjectsProjectKeyParamsExpand = "overrides"
+ PatchDevProjectsProjectKeyParamsExpandAvailableVariations PatchDevProjectsProjectKeyParamsExpand = "availableVariations"
+ PatchDevProjectsProjectKeyParamsExpandOverrides PatchDevProjectsProjectKeyParamsExpand = "overrides"
)
// Defines values for PostDevProjectsProjectKeyParamsExpand.
const (
- PostDevProjectsProjectKeyParamsExpandOverrides PostDevProjectsProjectKeyParamsExpand = "overrides"
+ PostDevProjectsProjectKeyParamsExpandAvailableVariations PostDevProjectsProjectKeyParamsExpand = "availableVariations"
+ PostDevProjectsProjectKeyParamsExpandOverrides PostDevProjectsProjectKeyParamsExpand = "overrides"
)
// Defines values for PatchDevProjectsProjectKeySyncParamsExpand.
const (
- PatchDevProjectsProjectKeySyncParamsExpandOverrides PatchDevProjectsProjectKeySyncParamsExpand = "overrides"
+ PatchDevProjectsProjectKeySyncParamsExpandAvailableVariations PatchDevProjectsProjectKeySyncParamsExpand = "availableVariations"
+ PatchDevProjectsProjectKeySyncParamsExpandOverrides PatchDevProjectsProjectKeySyncParamsExpand = "overrides"
)
// Context context object to use when evaluating flags in source environment
@@ -48,25 +52,38 @@ type Project struct {
// LastSyncedFromSource unix timestamp for the lat time the flag values were synced from the source environment
LastSyncedFromSource int64 `json:"_lastSyncedFromSource"`
+ // AvailableVariations variations
+ AvailableVariations *map[string][]Variation `json:"availableVariations,omitempty"`
+
// Context context object to use when evaluating flags in source environment
Context Context `json:"context"`
// FlagsState flags and their values and version for a given project in the source environment
FlagsState *model.FlagsState `json:"flagsState,omitempty"`
- // Overrides flags and their values and version for a given project in the source environment
+ // Overrides overridden flags for the project
Overrides *model.FlagsState `json:"overrides,omitempty"`
// SourceEnvironmentKey environment to copy flag values from
SourceEnvironmentKey string `json:"sourceEnvironmentKey"`
}
-// Expand defines model for expand.
-type Expand = []string
+// Variation variation of a flag
+type Variation struct {
+ Id string `json:"_id"`
+ Description *string `json:"description,omitempty"`
+ Name *string `json:"name,omitempty"`
+
+ // Value value of a feature flag variation
+ Value FlagValue `json:"value"`
+}
// FlagKey defines model for flagKey.
type FlagKey = string
+// ProjectExpand defines model for projectExpand.
+type ProjectExpand = []string
+
// ProjectKey defines model for projectKey.
type ProjectKey = string
@@ -91,7 +108,7 @@ type FlagOverride struct {
// GetDevProjectsProjectKeyParams defines parameters for GetDevProjectsProjectKey.
type GetDevProjectsProjectKeyParams struct {
// Expand Available expand options for this endpoint.
- Expand *Expand `form:"expand,omitempty" json:"expand,omitempty"`
+ Expand *ProjectExpand `form:"expand,omitempty" json:"expand,omitempty"`
}
// GetDevProjectsProjectKeyParamsExpand defines parameters for GetDevProjectsProjectKey.
@@ -109,7 +126,7 @@ type PatchDevProjectsProjectKeyJSONBody struct {
// PatchDevProjectsProjectKeyParams defines parameters for PatchDevProjectsProjectKey.
type PatchDevProjectsProjectKeyParams struct {
// Expand Available expand options for this endpoint.
- Expand *Expand `form:"expand,omitempty" json:"expand,omitempty"`
+ Expand *ProjectExpand `form:"expand,omitempty" json:"expand,omitempty"`
}
// PatchDevProjectsProjectKeyParamsExpand defines parameters for PatchDevProjectsProjectKey.
@@ -127,7 +144,7 @@ type PostDevProjectsProjectKeyJSONBody struct {
// PostDevProjectsProjectKeyParams defines parameters for PostDevProjectsProjectKey.
type PostDevProjectsProjectKeyParams struct {
// Expand Available expand options for this endpoint.
- Expand *Expand `form:"expand,omitempty" json:"expand,omitempty"`
+ Expand *ProjectExpand `form:"expand,omitempty" json:"expand,omitempty"`
}
// PostDevProjectsProjectKeyParamsExpand defines parameters for PostDevProjectsProjectKey.
@@ -136,7 +153,7 @@ type PostDevProjectsProjectKeyParamsExpand string
// PatchDevProjectsProjectKeySyncParams defines parameters for PatchDevProjectsProjectKeySync.
type PatchDevProjectsProjectKeySyncParams struct {
// Expand Available expand options for this endpoint.
- Expand *Expand `form:"expand,omitempty" json:"expand,omitempty"`
+ Expand *ProjectExpand `form:"expand,omitempty" json:"expand,omitempty"`
}
// PatchDevProjectsProjectKeySyncParamsExpand defines parameters for PatchDevProjectsProjectKeySync.
diff --git a/internal/dev_server/api/server.go b/internal/dev_server/api/server.go
index 7ae6bfcf..23cdccad 100644
--- a/internal/dev_server/api/server.go
+++ b/internal/dev_server/api/server.go
@@ -78,6 +78,14 @@ func (s Server) GetDevProjectsProjectKey(ctx context.Context, request GetDevProj
}
response.Overrides = &respOverrides
}
+ if item == "availableVariations" {
+ availableVariations, err := store.GetAvailableVariationsForProject(ctx, request.ProjectKey)
+ if err != nil {
+ return nil, err
+ }
+ respAvailableVariations := availableVariationsToResponseFormat(availableVariations)
+ response.AvailableVariations = &respAvailableVariations
+ }
}
}
@@ -135,6 +143,14 @@ func (s Server) PostDevProjectsProjectKey(ctx context.Context, request PostDevPr
}
response.Overrides = &respOverrides
}
+ if item == "availableVariations" {
+ availableVariations, err := store.GetAvailableVariationsForProject(ctx, request.ProjectKey)
+ if err != nil {
+ return nil, err
+ }
+ respAvailableVariations := availableVariationsToResponseFormat(availableVariations)
+ response.AvailableVariations = &respAvailableVariations
+ }
}
}
@@ -180,6 +196,14 @@ func (s Server) PatchDevProjectsProjectKey(ctx context.Context, request PatchDev
}
response.Overrides = &respOverrides
}
+ if item == "availableVariations" {
+ availableVariations, err := store.GetAvailableVariationsForProject(ctx, request.ProjectKey)
+ if err != nil {
+ return nil, err
+ }
+ respAvailableVariations := availableVariationsToResponseFormat(availableVariations)
+ response.AvailableVariations = &respAvailableVariations
+ }
}
}
@@ -191,7 +215,7 @@ func (s Server) PatchDevProjectsProjectKey(ctx context.Context, request PatchDev
func (s Server) PatchDevProjectsProjectKeySync(ctx context.Context, request PatchDevProjectsProjectKeySyncRequestObject) (PatchDevProjectsProjectKeySyncResponseObject, error) {
store := model.StoreFromContext(ctx)
- project, err := model.SyncProject(ctx, request.ProjectKey)
+ project, err := model.UpdateProject(ctx, request.ProjectKey, nil, nil)
if err != nil {
return nil, err
}
@@ -225,6 +249,14 @@ func (s Server) PatchDevProjectsProjectKeySync(ctx context.Context, request Patc
}
response.Overrides = &respOverrides
}
+ if item == "availableVariations" {
+ availableVariations, err := store.GetAvailableVariationsForProject(ctx, request.ProjectKey)
+ if err != nil {
+ return nil, err
+ }
+ respAvailableVariations := availableVariationsToResponseFormat(availableVariations)
+ response.AvailableVariations = &respAvailableVariations
+ }
}
}
diff --git a/internal/dev_server/db/sqlite.go b/internal/dev_server/db/sqlite.go
index 523b4b9f..ee9e2df3 100644
--- a/internal/dev_server/db/sqlite.go
+++ b/internal/dev_server/db/sqlite.go
@@ -16,6 +16,8 @@ type Sqlite struct {
database *sql.DB
}
+var _ model.Store = Sqlite{}
+
func (s Sqlite) GetDevProjectKeys(ctx context.Context) ([]string, error) {
rows, err := s.database.Query("select key from projects")
if err != nil {
@@ -70,7 +72,16 @@ func (s Sqlite) UpdateProject(ctx context.Context, project model.Project) (bool,
return false, errors.Wrap(err, "unable to marshal flags state when updating project")
}
- result, err := s.database.ExecContext(ctx, `
+ tx, err := s.database.BeginTx(ctx, nil)
+ if err != nil {
+ return false, err
+ }
+ defer func() {
+ if err != nil {
+ _ = tx.Rollback()
+ }
+ }()
+ result, err := tx.ExecContext(ctx, `
UPDATE projects
SET flag_state = ?, last_sync_time = ?, context=?
WHERE key = ?;
@@ -79,6 +90,24 @@ func (s Sqlite) UpdateProject(ctx context.Context, project model.Project) (bool,
return false, errors.Wrap(err, "unable to execute update project")
}
+ // Delete all and add all new variations. Definitely room for optimization...
+ _, err = tx.ExecContext(ctx, `
+ DELETE FROM available_variations
+ WHERE project_key = ?
+ `, project.Key)
+ if err != nil {
+ return false, err
+ }
+
+ err = InsertAvailableVariations(ctx, tx, project)
+ if err != nil {
+ return false, err
+ }
+ err = tx.Commit()
+ if err != nil {
+ return false, err
+ }
+
rowsAffected, err := result.RowsAffected()
if err != nil {
return false, err
@@ -106,6 +135,24 @@ func (s Sqlite) DeleteDevProject(ctx context.Context, key string) (bool, error)
return true, nil
}
+func InsertAvailableVariations(ctx context.Context, tx *sql.Tx, project model.Project) (err error) {
+ for _, variation := range project.AvailableVariations {
+ jsonValue, err := variation.Value.MarshalJSON()
+ if err != nil {
+ return err
+ }
+ _, err = tx.ExecContext(ctx, `
+ INSERT INTO available_variations
+ (project_key, flag_key, id, value, description, name)
+ VALUES (?, ?, ?, ?, ?, ?)
+ `, project.Key, variation.FlagKey, variation.Id, string(jsonValue), variation.Description, variation.Name)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
func (s Sqlite) InsertProject(ctx context.Context, project model.Project) (err error) {
flagsStateJson, err := json.Marshal(project.AllFlagsState)
if err != nil {
@@ -148,8 +195,59 @@ VALUES (?, ?, ?, ?, ?)
if err != nil {
return
}
- err = tx.Commit()
- return
+
+ err = InsertAvailableVariations(ctx, tx, project)
+ if err != nil {
+ return err
+ }
+ return tx.Commit()
+}
+
+func (s Sqlite) GetAvailableVariationsForProject(ctx context.Context, projectKey string) (map[string][]model.Variation, error) {
+ rows, err := s.database.QueryContext(ctx, `
+ SELECT flag_key, id, name, description, value
+ FROM available_variations
+ WHERE project_key = ?
+ `, projectKey)
+
+ if err != nil {
+ return nil, err
+ }
+
+ availableVariations := make(map[string][]model.Variation)
+ for rows.Next() {
+ var flagKey string
+ var id string
+ var nameNullable sql.NullString
+ var descriptionNullable sql.NullString
+ var valueJson string
+
+ err = rows.Scan(&flagKey, &id, &nameNullable, &descriptionNullable, &valueJson)
+ if err != nil {
+ return nil, err
+ }
+
+ var value ldvalue.Value
+ err = json.Unmarshal([]byte(valueJson), &value)
+ if err != nil {
+ return nil, err
+ }
+
+ var name, description *string
+ if nameNullable.Valid {
+ name = &nameNullable.String
+ }
+ if descriptionNullable.Valid {
+ description = &descriptionNullable.String
+ }
+ availableVariations[flagKey] = append(availableVariations[flagKey], model.Variation{
+ Id: id,
+ Name: name,
+ Description: description,
+ Value: value,
+ })
+ }
+ return availableVariations, nil
}
func (s Sqlite) GetOverridesForProject(ctx context.Context, projectKey string) (model.Overrides, error) {
@@ -267,6 +365,11 @@ func (s Sqlite) runMigrations(ctx context.Context) error {
if err != nil {
return err
}
+ defer func() {
+ if err != nil {
+ _ = tx.Rollback()
+ }
+ }()
_, err = tx.Exec(`
CREATE TABLE IF NOT EXISTS projects (
key text PRIMARY KEY,
@@ -291,5 +394,21 @@ func (s Sqlite) runMigrations(ctx context.Context) error {
if err != nil {
return err
}
+
+ _, err = tx.Exec(`
+ CREATE TABLE IF NOT EXISTS available_variations (
+ project_key text NOT NULL,
+ flag_key text NOT NULL,
+ id text NOT NULL,
+ value text NOT NULL,
+ description text,
+ name text,
+ FOREIGN KEY (project_key) REFERENCES projects (key) ON DELETE CASCADE,
+ UNIQUE (project_key, flag_key, id) ON CONFLICT REPLACE
+ )`)
+ if err != nil {
+ return err
+ }
+
return tx.Commit()
}
diff --git a/internal/dev_server/db/sqlite_test.go b/internal/dev_server/db/sqlite_test.go
index acbed71f..2352915f 100644
--- a/internal/dev_server/db/sqlite_test.go
+++ b/internal/dev_server/db/sqlite_test.go
@@ -10,6 +10,7 @@ import (
"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
"github.com/launchdarkly/ldcli/internal/dev_server/db"
"github.com/launchdarkly/ldcli/internal/dev_server/model"
+ "github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -38,6 +39,31 @@ func TestDBFunctions(t *testing.T) {
"flag-1": model.FlagState{Value: ldvalue.Bool(true), Version: 2},
"flag-2": model.FlagState{Value: ldvalue.String("cool"), Version: 2},
},
+ AvailableVariations: []model.FlagVariation{
+ {
+ FlagKey: "flag-1",
+ Variation: model.Variation{
+ Id: "1",
+ Value: ldvalue.Bool(true),
+ },
+ },
+ {
+ FlagKey: "flag-1",
+ Variation: model.Variation{
+ Id: "2",
+ Value: ldvalue.Bool(false),
+ },
+ },
+ {
+ FlagKey: "flag-2",
+ Variation: model.Variation{
+ Id: "3",
+ Description: lo.ToPtr("cool description"),
+ Name: lo.ToPtr("cool name"),
+ Value: ldvalue.String("Cool"),
+ },
+ },
+ },
},
{
Key: "proj-to-delete",
@@ -48,6 +74,22 @@ func TestDBFunctions(t *testing.T) {
"flag-1": model.FlagState{Value: ldvalue.Int(123), Version: 2},
"flag-2": model.FlagState{Value: ldvalue.Float64(99.99), Version: 2},
},
+ AvailableVariations: []model.FlagVariation{
+ {
+ FlagKey: "flag-1",
+ Variation: model.Variation{
+ Id: "1",
+ Value: ldvalue.Int(123),
+ },
+ },
+ {
+ FlagKey: "flag-2",
+ Variation: model.Variation{
+ Id: "2",
+ Value: ldvalue.Float64(99.99),
+ },
+ },
+ },
},
}
actualProjectKeys := make(map[string]bool, len(projects))
@@ -93,28 +135,93 @@ func TestDBFunctions(t *testing.T) {
assert.True(t, expected.LastSyncTime.Equal(p.LastSyncTime))
})
+ t.Run("GetAvailableVariations returns variations", func(t *testing.T) {
+ availableVariations, err := store.GetAvailableVariationsForProject(ctx, projects[0].Key)
+ require.NoError(t, err)
+ require.Len(t, availableVariations, 2)
+ flag1Variations := availableVariations["flag-1"]
+ assert.Len(t, flag1Variations, 2)
+ flag2Variations := availableVariations["flag-2"]
+ assert.Len(t, flag2Variations, 1)
+
+ expectedFlagVariations := projects[0].AvailableVariations
+ assert.Equal(t, expectedFlagVariations[2].Id, flag2Variations[0].Id)
+ assert.Equal(t, *expectedFlagVariations[2].Name, *flag2Variations[0].Name)
+ assert.Equal(t, *expectedFlagVariations[2].Description, *flag2Variations[0].Description)
+ assert.Equal(t, expectedFlagVariations[2].Value.String(), flag2Variations[0].Value.String())
+ assert.Equal(t, ldvalue.StringType, flag2Variations[0].Value.Type())
+ for _, variation := range flag1Variations {
+ if variation.Value.BoolValue() {
+ assert.Equal(t, expectedFlagVariations[0].Variation, variation)
+ } else {
+ assert.Equal(t, expectedFlagVariations[1].Variation, variation)
+ }
+ }
+ })
+
t.Run("UpdateProject updates flag state, sync time, context but not source environment key", func(t *testing.T) {
- projects[0].Context = ldcontext.New(t.Name() + "blah")
- projects[0].AllFlagsState = model.FlagsState{
+ project := projects[0]
+ project.Context = ldcontext.New(t.Name() + "blah")
+ project.AllFlagsState = model.FlagsState{
"flag-1": model.FlagState{Value: ldvalue.Bool(false), Version: 3},
"flag-2": model.FlagState{Value: ldvalue.String("cool beeans"), Version: 3},
}
- projects[0].LastSyncTime = time.Now().Add(time.Hour)
+ project.LastSyncTime = time.Now().Add(time.Hour)
oldSourceEnvKey := projects[0].SourceEnvironmentKey
- projects[0].SourceEnvironmentKey = "new-env"
+ project.SourceEnvironmentKey = "new-env"
+ project.AvailableVariations = []model.FlagVariation{
+ {
+ FlagKey: "flag-1",
+ Variation: model.Variation{
+ Id: "1",
+ Value: ldvalue.Bool(true),
+ },
+ },
+ {
+ FlagKey: "flag-1",
+ Variation: model.Variation{
+ Id: "2",
+ Value: ldvalue.Bool(false),
+ },
+ },
+ {
+ FlagKey: "flag-2",
+ Variation: model.Variation{
+ Id: "3",
+ Description: lo.ToPtr("cool description"),
+ Name: lo.ToPtr("cool name"),
+ Value: ldvalue.String("cool beans"),
+ },
+ },
+ }
- updated, err := store.UpdateProject(ctx, projects[0])
+ updated, err := store.UpdateProject(ctx, project)
assert.NoError(t, err)
assert.True(t, updated)
- newProj, err := store.GetDevProject(ctx, projects[0].Key)
+ newProj, err := store.GetDevProject(ctx, project.Key)
assert.NoError(t, err)
assert.NotNil(t, newProj)
- assert.Equal(t, projects[0].Key, newProj.Key)
- assert.Equal(t, projects[0].AllFlagsState, newProj.AllFlagsState)
+ assert.Equal(t, project.Key, newProj.Key)
+ assert.Equal(t, project.AllFlagsState, newProj.AllFlagsState)
assert.Equal(t, oldSourceEnvKey, newProj.SourceEnvironmentKey)
- assert.Equal(t, projects[0].Context, newProj.Context)
- assert.True(t, projects[0].LastSyncTime.Equal(newProj.LastSyncTime))
+ assert.Equal(t, project.Context, newProj.Context)
+ assert.True(t, project.LastSyncTime.Equal(newProj.LastSyncTime))
+
+ availableVariations, err := store.GetAvailableVariationsForProject(ctx, projects[0].Key)
+ require.NoError(t, err)
+ require.Len(t, availableVariations, 2)
+ flag1Variations := availableVariations["flag-1"]
+ assert.Len(t, flag1Variations, 2)
+ flag2Variations := availableVariations["flag-2"]
+ assert.Len(t, flag2Variations, 1)
+
+ expectedFlagVariation := project.AvailableVariations[2]
+ assert.Equal(t, expectedFlagVariation.Id, flag2Variations[0].Id)
+ assert.Equal(t, *expectedFlagVariation.Name, *flag2Variations[0].Name)
+ assert.Equal(t, *expectedFlagVariation.Description, *flag2Variations[0].Description)
+ assert.Equal(t, expectedFlagVariation.Value.String(), flag2Variations[0].Value.String())
+ assert.Equal(t, ldvalue.StringType, flag2Variations[0].Value.Type())
})
t.Run("UpdateProject returns false if project does not exist", func(t *testing.T) {
diff --git a/internal/dev_server/model/mocks/store.go b/internal/dev_server/model/mocks/store.go
index 2ea32011..1fd95209 100644
--- a/internal/dev_server/model/mocks/store.go
+++ b/internal/dev_server/model/mocks/store.go
@@ -69,6 +69,21 @@ func (mr *MockStoreMockRecorder) DeleteDevProject(arg0, arg1 any) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevProject", reflect.TypeOf((*MockStore)(nil).DeleteDevProject), arg0, arg1)
}
+// GetAvailableVariationsForProject mocks base method.
+func (m *MockStore) GetAvailableVariationsForProject(arg0 context.Context, arg1 string) (map[string][]model.Variation, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetAvailableVariationsForProject", arg0, arg1)
+ ret0, _ := ret[0].(map[string][]model.Variation)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetAvailableVariationsForProject indicates an expected call of GetAvailableVariationsForProject.
+func (mr *MockStoreMockRecorder) GetAvailableVariationsForProject(arg0, arg1 any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAvailableVariationsForProject", reflect.TypeOf((*MockStore)(nil).GetAvailableVariationsForProject), arg0, arg1)
+}
+
// GetDevProject mocks base method.
func (m *MockStore) GetDevProject(arg0 context.Context, arg1 string) (*model.Project, error) {
m.ctrl.T.Helper()
diff --git a/internal/dev_server/model/project.go b/internal/dev_server/model/project.go
index 6d2677cb..b594abaf 100644
--- a/internal/dev_server/model/project.go
+++ b/internal/dev_server/model/project.go
@@ -5,6 +5,7 @@ import (
"time"
"github.com/launchdarkly/go-sdk-common/v3/ldcontext"
+ "github.com/launchdarkly/go-sdk-common/v3/ldvalue"
"github.com/launchdarkly/ldcli/internal/dev_server/adapters"
"github.com/pkg/errors"
)
@@ -15,6 +16,7 @@ type Project struct {
Context ldcontext.Context
LastSyncTime time.Time
AllFlagsState FlagsState
+ AvailableVariations []FlagVariation
}
// CreateProject creates a project and adds it to the database.
@@ -29,15 +31,10 @@ func CreateProject(ctx context.Context, projectKey, sourceEnvironmentKey string,
} else {
project.Context = *ldCtx
}
-
- flagsState, err := project.FetchFlagState(ctx)
+ err := project.refreshExternalState(ctx)
if err != nil {
return Project{}, err
}
-
- project.AllFlagsState = flagsState
- project.LastSyncTime = time.Now()
-
store := StoreFromContext(ctx)
err = store.InsertProject(ctx, project)
if err != nil {
@@ -46,6 +43,22 @@ func CreateProject(ctx context.Context, projectKey, sourceEnvironmentKey string,
return project, nil
}
+func (project *Project) refreshExternalState(ctx context.Context) error {
+ flagsState, err := project.fetchFlagState(ctx)
+ if err != nil {
+ return err
+ }
+ project.AllFlagsState = flagsState
+ project.LastSyncTime = time.Now()
+
+ availableVariations, err := project.fetchAvailableVariations(ctx)
+ if err != nil {
+ return err
+ }
+ project.AvailableVariations = availableVariations
+ return nil
+}
+
func UpdateProject(ctx context.Context, projectKey string, context *ldcontext.Context, sourceEnvironmentKey *string) (Project, error) {
store := StoreFromContext(ctx)
project, err := store.GetDevProject(ctx, projectKey)
@@ -60,40 +73,11 @@ func UpdateProject(ctx context.Context, projectKey string, context *ldcontext.Co
project.SourceEnvironmentKey = *sourceEnvironmentKey
}
- if context != nil || sourceEnvironmentKey != nil {
- flagsState, err := project.FetchFlagState(ctx)
- if err != nil {
- return Project{}, err
- }
- project.AllFlagsState = flagsState
- project.LastSyncTime = time.Now()
- }
-
- updated, err := store.UpdateProject(ctx, *project)
- if err != nil {
- return Project{}, err
- }
- if !updated {
- return Project{}, errors.New("Project not updated")
- }
-
- return *project, nil
-}
-
-func SyncProject(ctx context.Context, projectKey string) (Project, error) {
- store := StoreFromContext(ctx)
- project, err := store.GetDevProject(ctx, projectKey)
- if err != nil {
- return Project{}, err
- }
- flagsState, err := project.FetchFlagState(ctx)
+ err = project.refreshExternalState(ctx)
if err != nil {
return Project{}, err
}
- project.AllFlagsState = flagsState
- project.LastSyncTime = time.Now()
-
updated, err := store.UpdateProject(ctx, *project)
if err != nil {
return Project{}, err
@@ -114,14 +98,14 @@ func SyncProject(ctx context.Context, projectKey string) (Project, error) {
return *project, nil
}
-func (p Project) GetFlagStateWithOverridesForProject(ctx context.Context) (FlagsState, error) {
+func (project Project) GetFlagStateWithOverridesForProject(ctx context.Context) (FlagsState, error) {
store := StoreFromContext(ctx)
- overrides, err := store.GetOverridesForProject(ctx, p.Key)
+ overrides, err := store.GetOverridesForProject(ctx, project.Key)
if err != nil {
- return FlagsState{}, errors.Wrapf(err, "unable to fetch overrides for project %s", p.Key)
+ return FlagsState{}, errors.Wrapf(err, "unable to fetch overrides for project %s", project.Key)
}
- withOverrides := make(FlagsState, len(p.AllFlagsState))
- for flagKey, flagState := range p.AllFlagsState {
+ withOverrides := make(FlagsState, len(project.AllFlagsState))
+ for flagKey, flagState := range project.AllFlagsState {
if override, ok := overrides.GetFlag(flagKey); ok {
flagState = override.Apply(flagState)
}
@@ -130,16 +114,40 @@ func (p Project) GetFlagStateWithOverridesForProject(ctx context.Context) (Flags
return withOverrides, nil
}
-func (p Project) FetchFlagState(ctx context.Context) (FlagsState, error) {
+func (project Project) fetchAvailableVariations(ctx context.Context) ([]FlagVariation, error) {
+ apiAdapter := adapters.GetApi(ctx)
+ flags, err := apiAdapter.GetAllFlags(ctx, project.Key)
+ if err != nil {
+ return nil, err
+ }
+ var allVariations []FlagVariation
+ for _, flag := range flags {
+ flagKey := flag.Key
+ for _, variation := range flag.Variations {
+ allVariations = append(allVariations, FlagVariation{
+ FlagKey: flagKey,
+ Variation: Variation{
+ Id: *variation.Id,
+ Description: variation.Description,
+ Name: variation.Name,
+ Value: ldvalue.CopyArbitraryValue(variation.Value),
+ },
+ })
+ }
+ }
+ return allVariations, nil
+}
+
+func (project Project) fetchFlagState(ctx context.Context) (FlagsState, error) {
apiAdapter := adapters.GetApi(ctx)
- sdkKey, err := apiAdapter.GetSdkKey(ctx, p.Key, p.SourceEnvironmentKey)
+ sdkKey, err := apiAdapter.GetSdkKey(ctx, project.Key, project.SourceEnvironmentKey)
flagsState := make(FlagsState)
if err != nil {
return flagsState, err
}
sdkAdapter := adapters.GetSdk(ctx)
- sdkFlags, err := sdkAdapter.GetAllFlagsState(ctx, p.Context, sdkKey)
+ sdkFlags, err := sdkAdapter.GetAllFlagsState(ctx, project.Context, sdkKey)
if err != nil {
return flagsState, err
}
diff --git a/internal/dev_server/model/project_test.go b/internal/dev_server/model/project_test.go
index 9add089c..0e7bf880 100644
--- a/internal/dev_server/model/project_test.go
+++ b/internal/dev_server/model/project_test.go
@@ -5,13 +5,16 @@ import (
"errors"
"testing"
+ ldapi "github.com/launchdarkly/api-client-go/v14"
"github.com/launchdarkly/go-sdk-common/v3/ldcontext"
"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
"github.com/launchdarkly/go-server-sdk/v7/interfaces/flagstate"
adapters_mocks "github.com/launchdarkly/ldcli/internal/dev_server/adapters/mocks"
"github.com/launchdarkly/ldcli/internal/dev_server/model"
"github.com/launchdarkly/ldcli/internal/dev_server/model/mocks"
+ "github.com/samber/lo"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
)
@@ -25,10 +28,27 @@ func TestCreateProject(t *testing.T) {
sourceEnvKey := "env"
sdkKey := "thing"
- allFlags := flagstate.NewAllFlagsBuilder().
+ allFlagsState := flagstate.NewAllFlagsBuilder().
AddFlag("boolFlag", flagstate.FlagState{Value: ldvalue.Bool(true)}).
Build()
+ trueVariationId, falseVariationId := "true", "false"
+ allFlags := []ldapi.FeatureFlag{{
+ Name: "bool flag",
+ Kind: "bool",
+ Key: "boolFlag",
+ Variations: []ldapi.Variation{
+ {
+ Id: &trueVariationId,
+ Value: true,
+ },
+ {
+ Id: &falseVariationId,
+ Value: false,
+ },
+ },
+ }}
+
t.Run("Returns error if it cant fetch flag state", func(t *testing.T) {
api.EXPECT().GetSdkKey(gomock.Any(), projKey, sourceEnvKey).Return("", errors.New("fetch flag state fails"))
_, err := model.CreateProject(ctx, projKey, sourceEnvKey, nil)
@@ -36,9 +56,19 @@ func TestCreateProject(t *testing.T) {
assert.Equal(t, "fetch flag state fails", err.Error())
})
+ t.Run("Returns error if it can't fetch flags", func(t *testing.T) {
+ api.EXPECT().GetSdkKey(gomock.Any(), projKey, sourceEnvKey).Return(sdkKey, nil)
+ sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), sdkKey).Return(allFlagsState, nil)
+ api.EXPECT().GetAllFlags(gomock.Any(), projKey).Return(nil, errors.New("fetch flags failed"))
+ _, err := model.CreateProject(ctx, projKey, sourceEnvKey, nil)
+ assert.NotNil(t, err)
+ assert.Equal(t, "fetch flags failed", err.Error())
+ })
+
t.Run("Returns error if it fails to insert the project", func(t *testing.T) {
api.EXPECT().GetSdkKey(gomock.Any(), projKey, sourceEnvKey).Return(sdkKey, nil)
- sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), sdkKey).Return(allFlags, nil)
+ sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), sdkKey).Return(allFlagsState, nil)
+ api.EXPECT().GetAllFlags(gomock.Any(), projKey).Return(allFlags, nil)
store.EXPECT().InsertProject(gomock.Any(), gomock.Any()).Return(errors.New("insert fails"))
_, err := model.CreateProject(ctx, projKey, sourceEnvKey, nil)
@@ -48,7 +78,8 @@ func TestCreateProject(t *testing.T) {
t.Run("Successfully creates project", func(t *testing.T) {
api.EXPECT().GetSdkKey(gomock.Any(), projKey, sourceEnvKey).Return(sdkKey, nil)
- sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), sdkKey).Return(allFlags, nil)
+ sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), sdkKey).Return(allFlagsState, nil)
+ api.EXPECT().GetAllFlags(gomock.Any(), projKey).Return(allFlags, nil)
store.EXPECT().InsertProject(gomock.Any(), gomock.Any()).Return(nil)
p, err := model.CreateProject(ctx, projKey, sourceEnvKey, nil)
@@ -58,13 +89,14 @@ func TestCreateProject(t *testing.T) {
Key: projKey,
SourceEnvironmentKey: sourceEnvKey,
Context: ldcontext.NewBuilder("user").Key("dev-environment").Build(),
- AllFlagsState: model.FromAllFlags(allFlags),
+ AllFlagsState: model.FromAllFlags(allFlagsState),
}
assert.Equal(t, expectedProj.Key, p.Key)
assert.Equal(t, expectedProj.SourceEnvironmentKey, p.SourceEnvironmentKey)
assert.Equal(t, expectedProj.Context, p.Context)
assert.Equal(t, expectedProj.AllFlagsState, p.AllFlagsState)
+ //TODO add assertion on AvailableVariations
})
}
@@ -73,6 +105,12 @@ func TestUpdateProject(t *testing.T) {
store := mocks.NewMockStore(mockController)
ctx := model.ContextWithStore(context.Background(), store)
ctx, api, sdk := adapters_mocks.WithMockApiAndSdk(ctx, mockController)
+
+ observer := mocks.NewMockObserver(mockController)
+ observers := model.NewObservers()
+ observers.RegisterObserver(observer)
+ ctx = model.SetObserversOnContext(ctx, observers)
+
ldCtx := ldcontext.New(t.Name())
newSrcEnv := "newEnv"
@@ -82,6 +120,22 @@ func TestUpdateProject(t *testing.T) {
Context: ldcontext.New(t.Name()),
}
+ allFlagsState := flagstate.NewAllFlagsBuilder().
+ AddFlag("stringFlag", flagstate.FlagState{Value: ldvalue.String("cool")}).
+ Build()
+
+ allFlags := []ldapi.FeatureFlag{{
+ Name: "string flag",
+ Kind: "multivariate",
+ Key: "stringFlag",
+ Variations: []ldapi.Variation{
+ {
+ Id: lo.ToPtr("string"),
+ Value: "cool",
+ },
+ },
+ }}
+
t.Run("Returns error if GetDevProject fails", func(t *testing.T) {
store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&model.Project{}, errors.New("GetDevProject fails"))
_, err := model.UpdateProject(ctx, proj.Key, nil, nil)
@@ -89,7 +143,7 @@ func TestUpdateProject(t *testing.T) {
assert.Equal(t, "GetDevProject fails", err.Error())
})
- t.Run("Passing in context triggers FetchFlagState, returns error if the fetch fails", func(t *testing.T) {
+ t.Run("returns error if the fetch flag state fails", func(t *testing.T) {
store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&proj, nil)
api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, proj.SourceEnvironmentKey).Return("", errors.New("FetchFlagState fails"))
@@ -98,10 +152,11 @@ func TestUpdateProject(t *testing.T) {
assert.Equal(t, "FetchFlagState fails", err.Error())
})
- t.Run("Passing in sourceEnvironmentKey triggers FetchFlagState, returns error if UpdateProject fails", func(t *testing.T) {
+ t.Run("Returns error if UpdateProject fails", func(t *testing.T) {
store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&proj, nil)
api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, newSrcEnv).Return("sdkKey", nil)
- sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "sdkKey").Return(flagstate.AllFlags{}, nil)
+ sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "sdkKey").Return(allFlagsState, nil)
+ api.EXPECT().GetAllFlags(gomock.Any(), proj.Key).Return(allFlags, nil)
store.EXPECT().UpdateProject(gomock.Any(), gomock.Any()).Return(false, errors.New("UpdateProject fails"))
_, err := model.UpdateProject(ctx, proj.Key, nil, &newSrcEnv)
@@ -110,75 +165,13 @@ func TestUpdateProject(t *testing.T) {
})
t.Run("Returns error if project was not actually updated", func(t *testing.T) {
- store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&proj, nil)
- store.EXPECT().UpdateProject(gomock.Any(), gomock.Any()).Return(false, nil)
-
- _, err := model.UpdateProject(ctx, proj.Key, nil, nil)
- assert.NotNil(t, err)
- assert.Equal(t, "Project not updated", err.Error())
- })
-
- t.Run("Return successfully", func(t *testing.T) {
- store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&proj, nil)
- store.EXPECT().UpdateProject(gomock.Any(), gomock.Any()).Return(true, nil)
-
- project, err := model.UpdateProject(ctx, proj.Key, nil, nil)
- assert.Nil(t, err)
- assert.Equal(t, proj, project)
- })
-}
-
-func TestSyncProject(t *testing.T) {
- mockController := gomock.NewController(t)
- store := mocks.NewMockStore(mockController)
- ctx := model.ContextWithStore(context.Background(), store)
- ctx, api, sdk := adapters_mocks.WithMockApiAndSdk(ctx, mockController)
-
- observer := mocks.NewMockObserver(mockController)
- observers := model.NewObservers()
- observers.RegisterObserver(observer)
- ctx = model.SetObserversOnContext(ctx, observers)
-
- proj := model.Project{
- Key: "projKey",
- SourceEnvironmentKey: "srcEnvKey",
- Context: ldcontext.New(t.Name()),
- }
-
- t.Run("Returns error if GetDevProject fails", func(t *testing.T) {
- store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&model.Project{}, errors.New("GetDevProject fails"))
- _, err := model.SyncProject(ctx, proj.Key)
- assert.NotNil(t, err)
- assert.Equal(t, "GetDevProject fails", err.Error())
- })
-
- t.Run("returns error if FetchFlagState fails", func(t *testing.T) {
- store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&proj, nil)
- api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, proj.SourceEnvironmentKey).Return("", errors.New("FetchFlagState fails"))
-
- _, err := model.SyncProject(ctx, proj.Key)
- assert.NotNil(t, err)
- assert.Equal(t, "FetchFlagState fails", err.Error())
- })
-
- t.Run("returns error if UpdateProject fails", func(t *testing.T) {
store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&proj, nil)
api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, proj.SourceEnvironmentKey).Return("sdkKey", nil)
- sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "sdkKey").Return(flagstate.AllFlags{}, nil)
- store.EXPECT().UpdateProject(gomock.Any(), gomock.Any()).Return(false, errors.New("UpdateProject fails"))
-
- _, err := model.SyncProject(ctx, proj.Key)
- assert.NotNil(t, err)
- assert.Equal(t, "UpdateProject fails", err.Error())
- })
-
- t.Run("Returns error if project was not actually updated", func(t *testing.T) {
- store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&proj, nil)
- api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, proj.SourceEnvironmentKey).Return("sdkKey", nil)
- sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "sdkKey").Return(flagstate.AllFlags{}, nil)
+ sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "sdkKey").Return(allFlagsState, nil)
+ api.EXPECT().GetAllFlags(gomock.Any(), proj.Key).Return(allFlags, nil)
store.EXPECT().UpdateProject(gomock.Any(), gomock.Any()).Return(false, nil)
- _, err := model.SyncProject(ctx, proj.Key)
+ _, err := model.UpdateProject(ctx, proj.Key, nil, nil)
assert.NotNil(t, err)
assert.Equal(t, "Project not updated", err.Error())
})
@@ -186,18 +179,19 @@ func TestSyncProject(t *testing.T) {
t.Run("Return successfully", func(t *testing.T) {
store.EXPECT().GetDevProject(gomock.Any(), proj.Key).Return(&proj, nil)
api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, proj.SourceEnvironmentKey).Return("sdkKey", nil)
- sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "sdkKey").Return(flagstate.AllFlags{}, nil)
+ sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "sdkKey").Return(allFlagsState, nil)
+ api.EXPECT().GetAllFlags(gomock.Any(), proj.Key).Return(allFlags, nil)
store.EXPECT().UpdateProject(gomock.Any(), gomock.Any()).Return(true, nil)
store.EXPECT().GetOverridesForProject(gomock.Any(), proj.Key).Return(model.Overrides{}, nil)
observer.
EXPECT().
Handle(model.SyncEvent{
ProjectKey: proj.Key,
- AllFlagsState: model.FlagsState{},
+ AllFlagsState: model.FromAllFlags(allFlagsState),
})
- project, err := model.SyncProject(ctx, proj.Key)
- assert.Nil(t, err)
+ project, err := model.UpdateProject(ctx, proj.Key, nil, nil)
+ require.Nil(t, err)
assert.Equal(t, proj, project)
})
}
@@ -244,44 +238,3 @@ func TestGetFlagStateWithOverridesForProject(t *testing.T) {
assert.Equal(t, 2, overriddenFlag.Version)
})
}
-
-func TestFetchFlagState(t *testing.T) {
- ctx := context.Background()
- mockController := gomock.NewController(t)
- ctx, api, sdk := adapters_mocks.WithMockApiAndSdk(ctx, mockController)
- allFlags := flagstate.NewAllFlagsBuilder().
- AddFlag("boolFlag", flagstate.FlagState{Value: ldvalue.Bool(true)}).
- Build()
-
- proj := model.Project{
- Key: "projKey",
- SourceEnvironmentKey: "srcEnvKey",
- Context: ldcontext.New(t.Name()),
- }
-
- t.Run("Returns error if fails to fetch sdk key", func(t *testing.T) {
- api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, proj.SourceEnvironmentKey).Return("", errors.New("sdk key fail"))
-
- _, err := proj.FetchFlagState(ctx)
- assert.NotNil(t, err)
- assert.Equal(t, "sdk key fail", err.Error())
- })
-
- t.Run("Returns error if fails to fetch flags state", func(t *testing.T) {
- api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, proj.SourceEnvironmentKey).Return("key", nil)
- sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "key").Return(flagstate.AllFlags{}, errors.New("fetch fail"))
-
- _, err := proj.FetchFlagState(ctx)
- assert.NotNil(t, err)
- assert.Equal(t, "fetch fail", err.Error())
- })
-
- t.Run("Successfully fetches flag state", func(t *testing.T) {
- api.EXPECT().GetSdkKey(gomock.Any(), proj.Key, proj.SourceEnvironmentKey).Return("key", nil)
- sdk.EXPECT().GetAllFlagsState(gomock.Any(), gomock.Any(), "key").Return(allFlags, nil)
-
- flagState, err := proj.FetchFlagState(ctx)
- assert.Nil(t, err)
- assert.Equal(t, model.FromAllFlags(allFlags), flagState)
- })
-}
diff --git a/internal/dev_server/model/store.go b/internal/dev_server/model/store.go
index 2686a1bb..8859b944 100644
--- a/internal/dev_server/model/store.go
+++ b/internal/dev_server/model/store.go
@@ -25,6 +25,7 @@ type Store interface {
InsertProject(ctx context.Context, project Project) error
UpsertOverride(ctx context.Context, override Override) (Override, error)
GetOverridesForProject(ctx context.Context, projectKey string) (Overrides, error)
+ GetAvailableVariationsForProject(ctx context.Context, projectKey string) (map[string][]Variation, error)
}
func ContextWithStore(ctx context.Context, store Store) context.Context {
diff --git a/internal/dev_server/model/variations.go b/internal/dev_server/model/variations.go
new file mode 100644
index 00000000..92450ea6
--- /dev/null
+++ b/internal/dev_server/model/variations.go
@@ -0,0 +1,15 @@
+package model
+
+import "github.com/launchdarkly/go-sdk-common/v3/ldvalue"
+
+type Variation struct {
+ Id string
+ Description *string
+ Name *string
+ Value ldvalue.Value
+}
+
+type FlagVariation struct {
+ FlagKey string
+ Variation
+}
diff --git a/internal/dev_server/sdk/go_sdk_test.go b/internal/dev_server/sdk/go_sdk_test.go
index b6a32370..06579661 100644
--- a/internal/dev_server/sdk/go_sdk_test.go
+++ b/internal/dev_server/sdk/go_sdk_test.go
@@ -45,6 +45,9 @@ func TestSDKRoutesViaGoSDK(t *testing.T) {
ctx, api, sdk := mocks.WithMockApiAndSdk(ctx, mockController)
api.EXPECT().GetSdkKey(gomock.Any(), projectKey, environmentKey).Return(testSdkKey, nil).AnyTimes()
+ api.EXPECT().GetAllFlags(gomock.Any(), projectKey).
+ Return(nil, nil). // Available variations are not used for evaluation
+ AnyTimes()
// Wire up sdk routes in test server
router := mux.NewRouter()
@@ -129,7 +132,7 @@ func TestSDKRoutesViaGoSDK(t *testing.T) {
trackers[flagKey] = flagUpdateChan
}
- _, err := model.SyncProject(ctx, projectKey)
+ _, err := model.UpdateProject(ctx, projectKey, nil, nil)
require.NoError(t, err)
for flagKey, value := range valuesMap {
diff --git a/internal/dev_server/ui/.prettierignore b/internal/dev_server/ui/.prettierignore
new file mode 100644
index 00000000..1521c8b7
--- /dev/null
+++ b/internal/dev_server/ui/.prettierignore
@@ -0,0 +1 @@
+dist
diff --git a/internal/dev_server/ui/dist/index.html b/internal/dev_server/ui/dist/index.html
index 284059d0..edbb4cd2 100644
--- a/internal/dev_server/ui/dist/index.html
+++ b/internal/dev_server/ui/dist/index.html
@@ -5,7 +5,7 @@
LaunchDevly
-
-
diff --git a/internal/dev_server/ui/package-lock.json b/internal/dev_server/ui/package-lock.json
index de1937d9..92289af8 100644
--- a/internal/dev_server/ui/package-lock.json
+++ b/internal/dev_server/ui/package-lock.json
@@ -8,17 +8,22 @@
"name": "ldcli-dev-server-ui",
"version": "0.0.0",
"dependencies": {
- "@launchpad-ui/components": "0.2.12",
+ "@launchpad-ui/components": "0.4.4",
"@launchpad-ui/core": "0.49.22",
- "@launchpad-ui/icons": "0.18.4",
- "@launchpad-ui/tokens": "0.9.12",
+ "@launchpad-ui/icons": "0.18.13",
+ "@launchpad-ui/tokens": "0.11.3",
+ "fuzzysort": "3.0.2",
"launchdarkly-js-client-sdk": "3.4.0",
+ "lodash": "4.17.21",
"react": "18.3.1",
- "react-dom": "18.3.1"
+ "react-dom": "18.3.1",
+ "react-window": "1.8.10"
},
"devDependencies": {
+ "@types/lodash": "4.17.7",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
+ "@types/react-window": "1.8.8",
"@typescript-eslint/eslint-plugin": "7.13.1",
"@typescript-eslint/parser": "7.13.1",
"@vitejs/plugin-react": "4.3.1",
@@ -59,30 +64,30 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz",
- "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==",
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
+ "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz",
- "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
+ "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.24.7",
- "@babel/helper-compilation-targets": "^7.24.7",
- "@babel/helper-module-transforms": "^7.24.7",
- "@babel/helpers": "^7.24.7",
- "@babel/parser": "^7.24.7",
- "@babel/template": "^7.24.7",
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7",
+ "@babel/generator": "^7.25.0",
+ "@babel/helper-compilation-targets": "^7.25.2",
+ "@babel/helper-module-transforms": "^7.25.2",
+ "@babel/helpers": "^7.25.0",
+ "@babel/parser": "^7.25.0",
+ "@babel/template": "^7.25.0",
+ "@babel/traverse": "^7.25.2",
+ "@babel/types": "^7.25.2",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -107,12 +112,12 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz",
- "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
+ "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.24.7",
+ "@babel/types": "^7.25.6",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
@@ -122,14 +127,14 @@
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz",
- "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
+ "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
"dev": true,
"dependencies": {
- "@babel/compat-data": "^7.24.7",
- "@babel/helper-validator-option": "^7.24.7",
- "browserslist": "^4.22.2",
+ "@babel/compat-data": "^7.25.2",
+ "@babel/helper-validator-option": "^7.24.8",
+ "browserslist": "^4.23.1",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
@@ -137,6 +142,15 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -146,43 +160,6 @@
"semver": "bin/semver.js"
}
},
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
- "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
- "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
- "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-module-imports": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
@@ -197,16 +174,15 @@
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz",
- "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
+ "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
"dev": true,
"dependencies": {
- "@babel/helper-environment-visitor": "^7.24.7",
"@babel/helper-module-imports": "^7.24.7",
"@babel/helper-simple-access": "^7.24.7",
- "@babel/helper-split-export-declaration": "^7.24.7",
- "@babel/helper-validator-identifier": "^7.24.7"
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/traverse": "^7.25.2"
},
"engines": {
"node": ">=6.9.0"
@@ -216,9 +192,9 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz",
- "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
+ "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -237,22 +213,10 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
- "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz",
- "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
+ "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -268,22 +232,22 @@
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz",
- "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
+ "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz",
- "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz",
+ "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==",
"dev": true,
"dependencies": {
- "@babel/template": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/template": "^7.25.0",
+ "@babel/types": "^7.25.6"
},
"engines": {
"node": ">=6.9.0"
@@ -305,10 +269,13 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
- "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
+ "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
"dev": true,
+ "dependencies": {
+ "@babel/types": "^7.25.6"
+ },
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -347,9 +314,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
- "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
+ "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -358,33 +325,30 @@
}
},
"node_modules/@babel/template": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
- "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
+ "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.24.7",
- "@babel/parser": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/parser": "^7.25.0",
+ "@babel/types": "^7.25.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz",
- "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
+ "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.24.7",
- "@babel/helper-environment-visitor": "^7.24.7",
- "@babel/helper-function-name": "^7.24.7",
- "@babel/helper-hoist-variables": "^7.24.7",
- "@babel/helper-split-export-declaration": "^7.24.7",
- "@babel/parser": "^7.24.7",
- "@babel/types": "^7.24.7",
+ "@babel/generator": "^7.25.6",
+ "@babel/parser": "^7.25.6",
+ "@babel/template": "^7.25.0",
+ "@babel/types": "^7.25.6",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -393,12 +357,12 @@
}
},
"node_modules/@babel/types": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz",
- "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
+ "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
"dev": true,
"dependencies": {
- "@babel/helper-string-parser": "^7.24.7",
+ "@babel/helper-string-parser": "^7.24.8",
"@babel/helper-validator-identifier": "^7.24.7",
"to-fast-properties": "^2.0.0"
},
@@ -407,9 +371,9 @@
}
},
"node_modules/@emotion/hash": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
- "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==",
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
"peer": true
},
"node_modules/@esbuild/aix-ppc64": {
@@ -796,9 +760,9 @@
}
},
"node_modules/@eslint-community/regexpp": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
- "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==",
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
+ "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@@ -891,9 +855,9 @@
}
},
"node_modules/@floating-ui/utils": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.3.tgz",
- "integrity": "sha512-XGndio0l5/Gvd6CLIABvsav9HHezgDFFhDfHk1bvLfr9ni8dojqLSvBbotJEjmIwNHL7vK4QzBJTdBRoB+c1ww=="
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz",
+ "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA=="
},
"node_modules/@formatjs/ecma402-abstract": {
"version": "2.0.0",
@@ -997,9 +961,9 @@
"dev": true
},
"node_modules/@internationalized/date": {
- "version": "3.5.4",
- "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.4.tgz",
- "integrity": "sha512-qoVJVro+O0rBaw+8HPjUB1iH8Ihf8oziEnqMnvhJUSuVIrHOuZ6eNLHNvzXJKUvAtaDiqMnRlg8Z2mgh09BlUw==",
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.5.tgz",
+ "integrity": "sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ==",
"dependencies": {
"@swc/helpers": "^0.5.0"
}
@@ -1062,9 +1026,9 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
@@ -1078,14 +1042,14 @@
}
},
"node_modules/@launchpad-ui/alert": {
- "version": "0.9.20",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/alert/-/alert-0.9.20.tgz",
- "integrity": "sha512-zKBAis4Mzxtj8+dsQ/wrVmhkLjWZ/eiN9iVTBYmfI8iqlK9ITM4+m4YzBfQHkMowML+tE405eI6gPYWYz/d7OQ==",
+ "version": "0.9.30",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/alert/-/alert-0.9.30.tgz",
+ "integrity": "sha512-Ypsw01C2/rXA7qQin0MhN+ok18kqV0Nar/WRE28hAGLGdepnYJ54qyI/32Q5qRxH0s58DORYYt2lcCdmuLN6NA==",
"dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
- "@react-stately/utils": "3.10.1",
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@react-stately/utils": "3.10.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1094,12 +1058,12 @@
}
},
"node_modules/@launchpad-ui/avatar": {
- "version": "0.6.30",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/avatar/-/avatar-0.6.30.tgz",
- "integrity": "sha512-b0IoCn0Jgq6DpxUI5lbiriyzxSKvFTd2b6/cx3mzD0y/6lgFBz3LaFNj6FXhb6b+qMchK2DkSfYKV+ErsqWa/w==",
+ "version": "0.6.39",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/avatar/-/avatar-0.6.39.tgz",
+ "integrity": "sha512-43In06/xZSCpCplH4L8wvgDlRTjMFhtwBOMk+zqvr1t+g22CWgxtdGJRLbrruuMNb+e/VbpsSqsV1AuNzHjJHw==",
"dependencies": {
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1108,13 +1072,13 @@
}
},
"node_modules/@launchpad-ui/banner": {
- "version": "0.10.30",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/banner/-/banner-0.10.30.tgz",
- "integrity": "sha512-b77fZA6es+lLMCoqKHidb3ayh3r9FsUo9Rq3ZZm4D4Wk8qxi2lwORU/5+R7rGWq5kTfaBRCNiDGbGWOGcQCZng==",
+ "version": "0.10.39",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/banner/-/banner-0.10.39.tgz",
+ "integrity": "sha512-2qAgxQxzDQi3syaDGQQcAgcR+KA5s4zzeiVFd222hJHpcfW2jq1vVmZYNl2h/6+XPd5Vws9B9CHdTsbTDPio6w==",
"dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1123,13 +1087,13 @@
}
},
"node_modules/@launchpad-ui/box": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/box/-/box-0.1.13.tgz",
- "integrity": "sha512-uoErz95ETafuMmAeSPVCMovT7gB7qyDWOkQB+kA8fQwtIl7/JxuawcsRl00cgVkyNv2mhs7o4PwIPhfAT3KDwg==",
+ "version": "0.1.18",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/box/-/box-0.1.18.tgz",
+ "integrity": "sha512-yliur10GFYFdeXkRSuccE6ws89aot3UqedNSiIQ/0Gzka2dwk0cZrMczmSmkld4reVQLePkE5Wnihk3WBSnKAA==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/vars": "~0.2.19",
- "@radix-ui/react-slot": "1.0.2",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/vars": "~0.2.24",
+ "@radix-ui/react-slot": "1.1.0",
"@vanilla-extract/dynamic": "2.1.0",
"rainbow-sprinkles": "0.17.0"
},
@@ -1140,13 +1104,13 @@
}
},
"node_modules/@launchpad-ui/button": {
- "version": "0.12.17",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/button/-/button-0.12.17.tgz",
- "integrity": "sha512-6XT0wXZxZKnfowU/H+hrlxjFCoVCKKMqaQsnViABubphLQvo8KXX8xskzwA1GXGGBEh2U5pykkfPlmFCEC5vzw==",
+ "version": "0.12.26",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/button/-/button-0.12.26.tgz",
+ "integrity": "sha512-kgsrcDSdb8mldqag/MtqO7jDduhFetjlSxo6mNikdoh2+R/aNNA1du1/7ClaaluJcVyS66n5L5YV2BnvAzfQcg==",
"dependencies": {
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
- "@radix-ui/react-slot": "1.0.2",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@radix-ui/react-slot": "1.1.0",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1155,12 +1119,12 @@
}
},
"node_modules/@launchpad-ui/card": {
- "version": "0.2.35",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/card/-/card-0.2.35.tgz",
- "integrity": "sha512-tMwD7ObfhS6YjbrboBep35nTzHogUeuNTI/27OtfdwmF0SRvuKmA/PaXAE1B5SSyepZmJMHKnzMn2suWfWarlA==",
+ "version": "0.2.46",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/card/-/card-0.2.46.tgz",
+ "integrity": "sha512-hIAUdQud6ubgouqJ/uH1ysqBLSG8QG4OwRLnk7Y3iYpVvYh7MUfuhjtKMHOMZZpfYFt6sMRvfFBVme0vdDmUZA==",
"dependencies": {
- "@launchpad-ui/form": "~0.11.20",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/form": "~0.11.31",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1169,12 +1133,12 @@
}
},
"node_modules/@launchpad-ui/chip": {
- "version": "0.9.30",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/chip/-/chip-0.9.30.tgz",
- "integrity": "sha512-+n/yYq3FU1JnFsKs5cYg0tsEBl7oU2a19iiiiTvDBXmcEV762plOwo/Vsh+9nbh5kbjUpwLypNgpsQqhz5wgCg==",
+ "version": "0.9.39",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/chip/-/chip-0.9.39.tgz",
+ "integrity": "sha512-tPxGmDF5E+D8jZ2woEJxTO8WYnaYcDRicw7L9X4+11TygyTuWPAMIiWu5e79O4tPEeHJgxJJTqXSlu0AeF9Jqw==",
"dependencies": {
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1183,14 +1147,14 @@
}
},
"node_modules/@launchpad-ui/clipboard": {
- "version": "0.11.35",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/clipboard/-/clipboard-0.11.35.tgz",
- "integrity": "sha512-ZXuRcFC3u00jbTAWhRmW6/rlcJYOXTXMCUtx/ytOpFdr7cD80gRuUFl/OyNgXJOOEnXP3ZT8TR4IHZWmlcrI9w==",
- "dependencies": {
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/tooltip": "~0.9.12",
- "@radix-ui/react-slot": "1.0.2",
+ "version": "0.11.46",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/clipboard/-/clipboard-0.11.46.tgz",
+ "integrity": "sha512-mpiHFtslmLLWMixbvR3EyKZqmO+Ujf0f1gGG+Xmc13fqsgX64l3N7Hmgg2ozYI6l3ANIvR3/7JeGju8RzSU+sg==",
+ "dependencies": {
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/tooltip": "~0.9.19",
+ "@radix-ui/react-slot": "1.1.0",
"@react-aria/live-announcer": "3.3.4",
"classix": "2.1.17"
},
@@ -1200,13 +1164,13 @@
}
},
"node_modules/@launchpad-ui/collapsible": {
- "version": "0.1.61",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/collapsible/-/collapsible-0.1.61.tgz",
- "integrity": "sha512-13jplhIlUUxgaCeLCBAM/pkCYCNLEW1TaBwMHEVgelhcCu08JDU9VmSzONnJDa5KdzOWv7Ob64868R8gwwb+CA==",
+ "version": "0.1.70",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/collapsible/-/collapsible-0.1.70.tgz",
+ "integrity": "sha512-Yg+PnmVoZI1jT3LDf2bWBoGm3CcCAzmG78Q5gGHO8cZw0w7FDZbLE84g0CVjkNq4Clge0RdNxFaQ/ZpzMK6MTg==",
"dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1215,11 +1179,11 @@
}
},
"node_modules/@launchpad-ui/columns": {
- "version": "0.1.22",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/columns/-/columns-0.1.22.tgz",
- "integrity": "sha512-HURsO+6Xk6QwnnLfFedXwAn38sdZ8xxFToXmbawtD07+uSnVDJULwDVAJytMD+NlXqFCsAYhjBZoBjrwUaRBCw==",
+ "version": "0.1.27",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/columns/-/columns-0.1.27.tgz",
+ "integrity": "sha512-5xROcntPUdlBxIvK/e2GNPm8539PAd1G7RbWL63A4ePmXqzGAHRUFqQAK865TknqepSqxQdLoporCYAYVvGkvg==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"@launchpad-ui/types": "~0.1.1",
"classix": "2.1.17"
},
@@ -1229,22 +1193,21 @@
}
},
"node_modules/@launchpad-ui/components": {
- "version": "0.2.12",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/components/-/components-0.2.12.tgz",
- "integrity": "sha512-bmhVFxcvmy+2F0dr04Qpfkp7mMNOp5AP/v7tftvTLLhfaya8Vh+75wCvsvgphoFQq0JSbf0KVfXOMQuxF5yGsQ==",
- "dependencies": {
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
- "@react-aria/interactions": "3.21.3",
- "@react-aria/toast": "3.0.0-beta.12",
- "@react-aria/utils": "3.24.1",
- "@react-stately/toast": "3.0.0-beta.4",
- "@react-types/shared": "3.23.1",
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/components/-/components-0.4.4.tgz",
+ "integrity": "sha512-xHUrCJ+jEbnACLaj4gZCFrxyS6GD6u2M6bD2vkwlSbNlH6+N1dd/DabWmsWkvYA8bFXdwqyiKeDlBx+k+onUeg==",
+ "dependencies": {
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@react-aria/toast": "3.0.0-beta.15",
+ "@react-aria/utils": "3.25.2",
+ "@react-stately/toast": "3.0.0-beta.5",
+ "@react-stately/utils": "3.10.3",
+ "@react-types/shared": "3.24.1",
"class-variance-authority": "0.7.0",
- "react-aria": "3.33.1",
- "react-aria-components": "1.2.1",
- "react-router-dom": "6.16.0",
- "react-stately": "3.31.1"
+ "react-aria": "3.34.3",
+ "react-aria-components": "1.3.3",
+ "react-router-dom": "6.16.0"
},
"peerDependencies": {
"react": "18.3.1",
@@ -1304,11 +1267,11 @@
}
},
"node_modules/@launchpad-ui/counter": {
- "version": "0.4.16",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/counter/-/counter-0.4.16.tgz",
- "integrity": "sha512-LH2uN4AV+cAHdVJuS2D3Rg/IJP706cw1nWXr0VPPW8ihW1fa1U/klUmmiSXKtvtjmcbdLyGB6Y7dKKithyAoUw==",
+ "version": "0.4.21",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/counter/-/counter-0.4.21.tgz",
+ "integrity": "sha512-XL2W99Ql2lFWSMaCxqlbAo3nzkRy23N5fovFDw4AwToQn9M/EQFz7b0Gx0r/rWImu7liQ4JshFqHho9FuaariA==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1317,45 +1280,45 @@
}
},
"node_modules/@launchpad-ui/data-table": {
- "version": "0.2.21",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/data-table/-/data-table-0.2.21.tgz",
- "integrity": "sha512-GEqR07JKgC18O2YYwyxKl7SNLgkI6KCbcnGa0eHP/6YAZSAZFwPJ289JEfyKZTLKEosgbplQV1SGNglKOWaLRQ==",
- "dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/vars": "~0.2.19",
- "@react-aria/checkbox": "3.14.3",
- "@react-aria/focus": "3.17.1",
- "@react-aria/table": "3.14.1",
- "@react-aria/utils": "3.24.1",
- "@react-aria/visually-hidden": "3.8.12",
- "@react-stately/table": "3.11.8",
- "@react-stately/toggle": "3.7.4",
- "@react-types/grid": "3.2.6",
+ "version": "0.2.28",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/data-table/-/data-table-0.2.28.tgz",
+ "integrity": "sha512-0phEF1k/xp0Al0NLvyccl653S+bAuP2JcziLSTDabkhExZAelP/HirqjPDkOi5x1It0D7aFxEk3qyvdBnv4Law==",
+ "dependencies": {
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/vars": "~0.2.24",
+ "@react-aria/checkbox": "3.14.6",
+ "@react-aria/focus": "3.18.2",
+ "@react-aria/table": "3.15.3",
+ "@react-aria/utils": "3.25.2",
+ "@react-aria/visually-hidden": "3.8.15",
+ "@react-stately/table": "3.12.2",
+ "@react-stately/toggle": "3.7.7",
+ "@react-types/grid": "3.2.8",
"@vanilla-extract/recipes": "^0.5.0",
"classix": "2.1.17"
},
"peerDependencies": {
- "@react-stately/table": "3.11.8",
+ "@react-stately/table": "3.12.2",
"@vanilla-extract/css": "^1.14.0",
"react": "18.3.1",
"react-dom": "18.3.1"
}
},
"node_modules/@launchpad-ui/drawer": {
- "version": "0.5.35",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/drawer/-/drawer-0.5.35.tgz",
- "integrity": "sha512-IlKpK38YHIJJPJSZSyX7W5GoixukOzYk0BRoYcG18GoYS5orf8w4yCBWx93xh56/s71ZyMaJSlYOmv0eh3WUEg==",
+ "version": "0.5.46",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/drawer/-/drawer-0.5.46.tgz",
+ "integrity": "sha512-92heu24Zzlmnk9Utf9rk+KrKMaJz8jijchTL6f/VhGC7Nv2sicpOrYq6hEhVqFWB4VHdHkQLxS+1aZWIQGLTLw==",
"dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/focus-trap": "~0.1.20",
- "@launchpad-ui/icons": "~0.18.4",
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/focus-trap": "~0.1.23",
+ "@launchpad-ui/icons": "~0.18.13",
"@launchpad-ui/portal": "~0.1.5",
- "@launchpad-ui/progress": "~0.5.47",
- "@launchpad-ui/tokens": "~0.9.12",
- "@react-aria/interactions": "3.21.3",
- "@react-aria/overlays": "3.22.1",
+ "@launchpad-ui/progress": "~0.5.52",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@react-aria/interactions": "3.22.2",
+ "@react-aria/overlays": "3.23.2",
"classix": "2.1.17",
- "framer-motion": "11.2.4"
+ "framer-motion": "11.3.0"
},
"peerDependencies": {
"react": "18.3.1",
@@ -1363,15 +1326,15 @@
}
},
"node_modules/@launchpad-ui/dropdown": {
- "version": "0.6.109",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/dropdown/-/dropdown-0.6.109.tgz",
- "integrity": "sha512-vKwDHSniDZCyK4NZo7Q8GhxK56HexSnFb7dc5075K6zgIDNkVMyY9WiUbD/PYkOIVWuKWn+2F+4tla6fIHQ5dA==",
- "dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/popover": "~0.11.23",
- "@launchpad-ui/tokens": "~0.9.12",
- "@react-aria/utils": "3.24.1",
+ "version": "0.6.120",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/dropdown/-/dropdown-0.6.120.tgz",
+ "integrity": "sha512-3feDZFSGjdqu/o7CKttSPdeljBg4fghogYP7D7+m9zJBEOyqSojsHQTjvoSOrGWKFPzEh77g9LBH5QLFvmtigg==",
+ "dependencies": {
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/popover": "~0.11.30",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@react-aria/utils": "3.25.2",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1380,17 +1343,17 @@
}
},
"node_modules/@launchpad-ui/filter": {
- "version": "0.7.20",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/filter/-/filter-0.7.20.tgz",
- "integrity": "sha512-8+KcL5xZKH7sYsyj8Tz2pr2QtMA1AjDF5bv/JkIKWgFLXsUdzvXk2JoTKDRq3wI72T3A9UGiYI4zxX7+5VpFfw==",
- "dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/dropdown": "~0.6.109",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/menu": "~0.13.20",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/tooltip": "~0.9.12",
- "@react-aria/visually-hidden": "3.8.12",
+ "version": "0.7.31",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/filter/-/filter-0.7.31.tgz",
+ "integrity": "sha512-Ei9vHhGsrTnC8mft6WOJm0ui4ewp096lyxGqi3l5XuDhVKsTmHlfvMKc89xK/TVz6GehLPdmQFmPrclCSJYG/Q==",
+ "dependencies": {
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/dropdown": "~0.6.120",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/menu": "~0.13.31",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/tooltip": "~0.9.19",
+ "@react-aria/visually-hidden": "3.8.15",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1399,11 +1362,11 @@
}
},
"node_modules/@launchpad-ui/focus-trap": {
- "version": "0.1.20",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/focus-trap/-/focus-trap-0.1.20.tgz",
- "integrity": "sha512-n/nHfKaj5G8rxw9ok10llFff4QmyUPUhMlISBuh7ZuMW0GeBD5EqLiE64IyXDCSAFJqUt6nvx+peN9tHyqatsQ==",
+ "version": "0.1.23",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/focus-trap/-/focus-trap-0.1.23.tgz",
+ "integrity": "sha512-2yxkEeLXojMGg3r2Tdogt+3s8phOR4VJRUmmbdC8+l5PlmFnoU6+yMRuW1MynXor2Ty9Ee+5oo55zVNqirTYnw==",
"dependencies": {
- "@react-aria/focus": "3.17.1"
+ "@react-aria/focus": "3.18.2"
},
"peerDependencies": {
"react": "18.3.1",
@@ -1411,19 +1374,19 @@
}
},
"node_modules/@launchpad-ui/form": {
- "version": "0.11.20",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/form/-/form-0.11.20.tgz",
- "integrity": "sha512-X6Gx2p3wWC8wdZMYV7VM8K0Q9BMRi5jP8/RDR2GP9NyQ+4It6XXwL2vTmlaOQhdiJfILDlaSQqTYxYZNF342Pw==",
- "dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/tooltip": "~0.9.12",
- "@react-aria/button": "3.9.5",
- "@react-aria/i18n": "3.11.1",
- "@react-aria/numberfield": "3.11.3",
- "@react-aria/visually-hidden": "3.8.12",
- "@react-stately/numberfield": "3.9.3",
+ "version": "0.11.31",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/form/-/form-0.11.31.tgz",
+ "integrity": "sha512-XvhhOFvCEgxtjUiqsR4jvnLh8oXgIIvunhDOjqRZ36i9p1oMlc9/01H/Ox+kSrmw0vURcEHdaegQJ1mbTiHWqQ==",
+ "dependencies": {
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/tooltip": "~0.9.19",
+ "@react-aria/button": "3.9.8",
+ "@react-aria/i18n": "3.12.2",
+ "@react-aria/numberfield": "3.11.6",
+ "@react-aria/visually-hidden": "3.8.15",
+ "@react-stately/numberfield": "3.9.6",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1432,11 +1395,11 @@
}
},
"node_modules/@launchpad-ui/icons": {
- "version": "0.18.4",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/icons/-/icons-0.18.4.tgz",
- "integrity": "sha512-hcHUJFcxxPRs8PIWXZHAQGmezecEW+SUAoJ/FGAjtZFxse+iHD/IxMyzNIvNiWOqTFjew7Jt16U9veHvJfth4A==",
+ "version": "0.18.13",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/icons/-/icons-0.18.13.tgz",
+ "integrity": "sha512-/qzD3iDgzUQKr8Lv6G3ipNcLvNWkk5RsCAyLk2dECIsfkpLyIlBrrLgnjU4XcD4EykYQ/SxxMWwhL6/XYgumTg==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1445,11 +1408,11 @@
}
},
"node_modules/@launchpad-ui/inline": {
- "version": "0.1.22",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/inline/-/inline-0.1.22.tgz",
- "integrity": "sha512-v0gdWJzgQhWbLpo45Gw9DiT0bK5OEmb6pf6zpIu1mavvfpgqRoI724DIKcgXJQ7zoP+Hna3YtCY8HZqGMfqpEw==",
+ "version": "0.1.27",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/inline/-/inline-0.1.27.tgz",
+ "integrity": "sha512-lthRDiZDt4ZOGt3vqOQtvhPX/9jhMtEAT3pWCMq2pwZIffwAq891VBi0opYAB8GPlUese+qeCbdA3ZI3Nnr4TA==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"@launchpad-ui/types": "~0.1.1",
"classix": "2.1.17"
},
@@ -1459,19 +1422,19 @@
}
},
"node_modules/@launchpad-ui/inline-edit": {
- "version": "0.3.20",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/inline-edit/-/inline-edit-0.3.20.tgz",
- "integrity": "sha512-TGyld7YP3I9xs/t4kR6xof/2QGHxX/jDJ/SnhbCYeiHW94AADT7MKwO60tcZElTBVRai6oSo4C2v6kqzgl7AQg==",
- "dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/form": "~0.11.20",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/vars": "~0.2.19",
- "@react-aria/button": "3.9.5",
- "@react-aria/focus": "3.17.1",
- "@react-aria/interactions": "3.21.3",
- "@react-aria/utils": "3.24.1",
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/inline-edit/-/inline-edit-0.3.31.tgz",
+ "integrity": "sha512-3HWqJb3zx6gGuo7jTVSFNU2Gwdmqt0+Y79gp9rYruoeGtiMNcP1zP5qGyS4cXKOZGD0Jvwdf3HvG32kj+EGWZQ==",
+ "dependencies": {
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/form": "~0.11.31",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/vars": "~0.2.24",
+ "@react-aria/button": "3.9.8",
+ "@react-aria/focus": "3.18.2",
+ "@react-aria/interactions": "3.22.2",
+ "@react-aria/utils": "3.25.2",
"@vanilla-extract/recipes": "^0.5.0",
"classix": "2.1.17"
},
@@ -1482,14 +1445,14 @@
}
},
"node_modules/@launchpad-ui/markdown": {
- "version": "0.5.18",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/markdown/-/markdown-0.5.18.tgz",
- "integrity": "sha512-RT3Aeb1+7zlYMg+llp0aFv0ZGrm94maZ6KwQ2Tvl1jMpByqOJdOm6qkohOr713rNO2zykoZG2slCFICw9qbuhw==",
+ "version": "0.5.24",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/markdown/-/markdown-0.5.24.tgz",
+ "integrity": "sha512-PAwv2Qk5F9d3GwraxIPzspVKAGK/45fyCT4S5WrfEViFBEBK/xyDnpDMd7bQYeOWK0uMlvFAgkuSsea9V6ZXSQ==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17",
- "isomorphic-dompurify": "^2.12.0",
- "marked": "^13.0.0"
+ "isomorphic-dompurify": "^2.14.0",
+ "marked": "^14.1.0"
},
"peerDependencies": {
"react": "18.3.1",
@@ -1497,18 +1460,18 @@
}
},
"node_modules/@launchpad-ui/menu": {
- "version": "0.13.20",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/menu/-/menu-0.13.20.tgz",
- "integrity": "sha512-TmJQvN+6aEiCo96AAF7BJ1sprF8bNLMizyjr9ENOs9qVoe0zp37QmBVkSCq136Ccrohp5hCd7+X3ITxBuNbPeQ==",
- "dependencies": {
- "@launchpad-ui/form": "~0.11.20",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/popover": "~0.11.23",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/tooltip": "~0.9.12",
- "@radix-ui/react-slot": "1.0.2",
- "@react-aria/focus": "3.17.1",
- "@react-aria/separator": "3.3.13",
+ "version": "0.13.31",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/menu/-/menu-0.13.31.tgz",
+ "integrity": "sha512-U1CYzhplh0P9NR6hp0cs8e55UFeWL60NEKo2EfbRTqZSdAii7zWWeSctUGhYJWug3Av1WmxFNi/r85nEc8Yv2Q==",
+ "dependencies": {
+ "@launchpad-ui/form": "~0.11.31",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/popover": "~0.11.30",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/tooltip": "~0.9.19",
+ "@radix-ui/react-slot": "1.1.0",
+ "@react-aria/focus": "3.18.2",
+ "@react-aria/separator": "3.4.2",
"classix": "2.1.17",
"react-virtual": "2.10.4"
},
@@ -1518,19 +1481,19 @@
}
},
"node_modules/@launchpad-ui/modal": {
- "version": "0.17.35",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/modal/-/modal-0.17.35.tgz",
- "integrity": "sha512-XAcvaHN4TSPL+OSiTRlwEOK7F7fpiudRPPOtri77bRqW6RRqAHlrHJknYUTbxmj6ZixD9zQncFURG2Gb9jLw2A==",
+ "version": "0.17.46",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/modal/-/modal-0.17.46.tgz",
+ "integrity": "sha512-9J+m4Uz97AjzV4S6bWY0kupZ1nrIx64qSAyuitiQtPx9KkwuTxqBB5oUe2NY0yN/IubH1Sllt+JutNPmKj4PqQ==",
"dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/focus-trap": "~0.1.20",
- "@launchpad-ui/icons": "~0.18.4",
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/focus-trap": "~0.1.23",
+ "@launchpad-ui/icons": "~0.18.13",
"@launchpad-ui/portal": "~0.1.5",
- "@launchpad-ui/tokens": "~0.9.12",
- "@react-aria/interactions": "3.21.3",
- "@react-aria/overlays": "3.22.1",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@react-aria/interactions": "3.22.2",
+ "@react-aria/overlays": "3.23.2",
"classix": "2.1.17",
- "framer-motion": "11.2.4"
+ "framer-motion": "11.3.0"
},
"peerDependencies": {
"react": "18.3.1",
@@ -1538,20 +1501,20 @@
}
},
"node_modules/@launchpad-ui/navigation": {
- "version": "0.12.35",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/navigation/-/navigation-0.12.35.tgz",
- "integrity": "sha512-on4tScWncd+YMqKJAGhkaO06tgaNEhvAbDolBw8Kiiimwur5dN16BjGcWjEmfNMV5sd9wl8bZGBmQXoigBDV1g==",
- "dependencies": {
- "@launchpad-ui/chip": "~0.9.30",
- "@launchpad-ui/dropdown": "~0.6.109",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/menu": "~0.13.20",
- "@launchpad-ui/popover": "~0.11.23",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/tooltip": "~0.9.12",
- "@react-aria/utils": "3.24.1",
- "@react-stately/list": "3.10.5",
- "@react-types/shared": "3.23.1",
+ "version": "0.12.46",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/navigation/-/navigation-0.12.46.tgz",
+ "integrity": "sha512-Hw2TwvKGBxXw0RUI3K0LY/27yjVvDBXOe0j2EFbKq0cMUiREQUgs5eHcEPsh2vJBKRbRSA0sAfuKNcQ4rik2Mw==",
+ "dependencies": {
+ "@launchpad-ui/chip": "~0.9.39",
+ "@launchpad-ui/dropdown": "~0.6.120",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/menu": "~0.13.31",
+ "@launchpad-ui/popover": "~0.11.30",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/tooltip": "~0.9.19",
+ "@react-aria/utils": "3.25.2",
+ "@react-stately/list": "3.10.8",
+ "@react-types/shared": "3.24.1",
"classix": "2.1.17",
"react-router-dom": "6.16.0"
},
@@ -1573,15 +1536,15 @@
}
},
"node_modules/@launchpad-ui/pagination": {
- "version": "0.4.35",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/pagination/-/pagination-0.4.35.tgz",
- "integrity": "sha512-F+VQDXJ4pZnp99ZbJ6A0SrJX+WJ4RJHHqihZcX9vB+NVl3XZgjYE2+W/UWM/dK9KDMmsokGv9B+qV1FDNyKF+w==",
- "dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/progress": "~0.5.47",
- "@launchpad-ui/tokens": "~0.9.12",
- "@react-aria/visually-hidden": "3.8.12",
+ "version": "0.4.46",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/pagination/-/pagination-0.4.46.tgz",
+ "integrity": "sha512-wbpgkQqwIeO0WKe9fgHIhyPiuFmR/GdrN6nLwm33dhjx19xf+EUQW70RX24GQKEwCFhNL+U/c/mii1HbSEtXig==",
+ "dependencies": {
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/progress": "~0.5.52",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@react-aria/visually-hidden": "3.8.15",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1590,17 +1553,17 @@
}
},
"node_modules/@launchpad-ui/popover": {
- "version": "0.11.23",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/popover/-/popover-0.11.23.tgz",
- "integrity": "sha512-x6B+/cZm5NcJXwLMSBXK+xeg/Yfk12AjgNmhU3IDFC9XjDVaNNKIheQe/oFiz2/29FLkhYmU/numSzDojxexfg==",
+ "version": "0.11.30",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/popover/-/popover-0.11.30.tgz",
+ "integrity": "sha512-BDOE7CLPU+RWCDBXOYiaDzlU3WNpr3jGcppM+IAdaAXvmaMDViUtZX4vH1Ny08RwT8t4j6Re3dO1M0jtmp5N+g==",
"dependencies": {
"@floating-ui/core": "1.6.0",
"@floating-ui/dom": "1.6.1",
- "@launchpad-ui/focus-trap": "~0.1.20",
+ "@launchpad-ui/focus-trap": "~0.1.23",
"@launchpad-ui/overlay": "~0.3.30",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17",
- "framer-motion": "11.2.4"
+ "framer-motion": "11.3.0"
},
"peerDependencies": {
"react": "18.3.1",
@@ -1617,11 +1580,11 @@
}
},
"node_modules/@launchpad-ui/progress": {
- "version": "0.5.47",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/progress/-/progress-0.5.47.tgz",
- "integrity": "sha512-Ai1q0lQ2zOSdvn7bWePSzWy6aGn7xArkkq+osp0PFAf3gn+E2uw0VHWYUnf68XEWbDjZL60L+LxHv56AHBGd9w==",
+ "version": "0.5.52",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/progress/-/progress-0.5.52.tgz",
+ "integrity": "sha512-Llu3szSKWKSwCHUFSLfuRmWJnrK0gjaxrF8+PSs82FVY7NnZmTTORLI0D8FcH2movjFxho0zBdjWXiJpeInBeg==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1630,12 +1593,12 @@
}
},
"node_modules/@launchpad-ui/progress-bubbles": {
- "version": "0.7.23",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/progress-bubbles/-/progress-bubbles-0.7.23.tgz",
- "integrity": "sha512-vIBJBGmUFEBLusHzJmqPH+iT3MWZnoCPLGEsrE7WmwYQ2sQWJgAejKJAai3ulU1LOZ3TzL7JTUjiBQlczMERYw==",
+ "version": "0.7.30",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/progress-bubbles/-/progress-bubbles-0.7.30.tgz",
+ "integrity": "sha512-WZuLGVCXWVFCxjw42UMdvFInNEWYNWDp/3TDbRNpC59UuPUSRQ8uqs6XIQCm7HGe1TMql8ZrdXEv1zfbEeSHQg==",
"dependencies": {
- "@launchpad-ui/popover": "~0.11.23",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/popover": "~0.11.30",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1644,45 +1607,45 @@
}
},
"node_modules/@launchpad-ui/select": {
- "version": "0.4.35",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/select/-/select-0.4.35.tgz",
- "integrity": "sha512-U0VypPwXHghj/Ajew/Y+QpZjEXLdvotWcXrPqLrOTNE+QBNgkDqB34P29NUTd7MqBUlN/VzeNiX10RnVHlFY5A==",
- "dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/modal": "~0.17.35",
- "@launchpad-ui/popover": "~0.11.23",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/tooltip": "~0.9.12",
- "@react-aria/button": "3.9.5",
- "@react-aria/combobox": "3.9.1",
- "@react-aria/focus": "3.17.1",
- "@react-aria/gridlist": "3.8.1",
- "@react-aria/interactions": "3.21.3",
- "@react-aria/label": "3.7.8",
- "@react-aria/listbox": "3.12.1",
- "@react-aria/menu": "3.14.1",
- "@react-aria/overlays": "3.22.1",
- "@react-aria/select": "3.14.5",
- "@react-aria/selection": "3.18.1",
- "@react-aria/separator": "3.3.13",
- "@react-aria/textfield": "3.14.5",
- "@react-aria/utils": "3.24.1",
- "@react-aria/visually-hidden": "3.8.12",
- "@react-stately/collections": "3.10.7",
- "@react-stately/combobox": "3.8.4",
- "@react-stately/data": "3.11.4",
- "@react-stately/list": "3.10.5",
- "@react-stately/menu": "3.7.1",
- "@react-stately/overlays": "3.6.7",
- "@react-stately/select": "3.6.4",
- "@react-stately/selection": "3.15.1",
- "@react-stately/utils": "3.10.1",
- "@react-types/button": "3.9.4",
- "@react-types/combobox": "3.11.1",
- "@react-types/overlays": "3.8.7",
- "@react-types/select": "3.9.4",
- "@react-types/shared": "3.23.1",
+ "version": "0.4.46",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/select/-/select-0.4.46.tgz",
+ "integrity": "sha512-HelcsxdhwQJ5InVGpHqeAiuv5hq317liUZA//mkYOpFRZ6FH28O3XWekHPtRBqyTWNcTVhcj3NbnsPXlFdsBVQ==",
+ "dependencies": {
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/modal": "~0.17.46",
+ "@launchpad-ui/popover": "~0.11.30",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/tooltip": "~0.9.19",
+ "@react-aria/button": "3.9.8",
+ "@react-aria/combobox": "3.10.3",
+ "@react-aria/focus": "3.18.2",
+ "@react-aria/gridlist": "3.9.3",
+ "@react-aria/interactions": "3.22.2",
+ "@react-aria/label": "3.7.11",
+ "@react-aria/listbox": "3.13.3",
+ "@react-aria/menu": "3.15.3",
+ "@react-aria/overlays": "3.23.2",
+ "@react-aria/select": "3.14.9",
+ "@react-aria/selection": "3.19.3",
+ "@react-aria/separator": "3.4.2",
+ "@react-aria/textfield": "3.14.8",
+ "@react-aria/utils": "3.25.2",
+ "@react-aria/visually-hidden": "3.8.15",
+ "@react-stately/collections": "3.10.9",
+ "@react-stately/combobox": "3.9.2",
+ "@react-stately/data": "3.11.6",
+ "@react-stately/list": "3.10.8",
+ "@react-stately/menu": "3.8.2",
+ "@react-stately/overlays": "3.6.10",
+ "@react-stately/select": "3.6.7",
+ "@react-stately/selection": "3.16.2",
+ "@react-stately/utils": "3.10.3",
+ "@react-types/button": "3.9.6",
+ "@react-types/combobox": "3.12.1",
+ "@react-types/overlays": "3.8.9",
+ "@react-types/select": "3.9.6",
+ "@react-types/shared": "3.24.1",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1691,11 +1654,11 @@
}
},
"node_modules/@launchpad-ui/slider": {
- "version": "0.5.16",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/slider/-/slider-0.5.16.tgz",
- "integrity": "sha512-Qt5349CLr7M6ESEWwhesiVW4YHTHE37YhiFoGuIAJubw3xd44WcCSSM+54Y+pQT8P1ZxnZoQ+p9Nvrc7clGlGg==",
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/slider/-/slider-0.5.21.tgz",
+ "integrity": "sha512-cNnikivg9Xwg3k3JtGZ0x0BOcO3xUKxBeYdR1PVHowgE7TKQmJktn87dYD+ym55PogkX56R/ZByM+x9WUQ/c6g==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1704,15 +1667,15 @@
}
},
"node_modules/@launchpad-ui/snackbar": {
- "version": "0.5.18",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/snackbar/-/snackbar-0.5.18.tgz",
- "integrity": "sha512-Od+G4NCSw5mBqwTAaAOzzcpdgQjU8Id96tXCictGxRyJKb+oH3GExpcM0EAgDlPH1zBktIICcr8GN4YgsWZuxg==",
+ "version": "0.5.27",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/snackbar/-/snackbar-0.5.27.tgz",
+ "integrity": "sha512-1IWzpm2t4kV0/UrW5NL/wmjnIVeCfrUekmk20tftwwSKD8NIYbJNUyX0Jm+mIfdTw6sxteJ7mnXl7YtrCnXv3A==",
"dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17",
- "framer-motion": "11.2.4"
+ "framer-motion": "11.3.0"
},
"peerDependencies": {
"react": "18.3.1",
@@ -1720,15 +1683,15 @@
}
},
"node_modules/@launchpad-ui/split-button": {
- "version": "0.10.20",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/split-button/-/split-button-0.10.20.tgz",
- "integrity": "sha512-ZILhoKCaLfA1ZDF5fzL5N5nyBMk3BTD4FVU0p4RgJM9q8zYUU4HJBZ3Tasna407YxrsCZQTFV/jJry5KBJ7c6A==",
- "dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/dropdown": "~0.6.109",
- "@launchpad-ui/popover": "~0.11.23",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/tooltip": "~0.9.12",
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/split-button/-/split-button-0.10.31.tgz",
+ "integrity": "sha512-f6F3GiSz1TDjp3Fuk7c8upoThYLkJRPqxYuv4+IvWubP/QybbY3BfqzwskGIff1fawAgWsNy4i9Bc5ozxxKZAQ==",
+ "dependencies": {
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/dropdown": "~0.6.120",
+ "@launchpad-ui/popover": "~0.11.30",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/tooltip": "~0.9.19",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1737,11 +1700,11 @@
}
},
"node_modules/@launchpad-ui/stack": {
- "version": "0.1.22",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/stack/-/stack-0.1.22.tgz",
- "integrity": "sha512-3oQWEe+wmhiF6vy6ZgGaVNIcbiwSP4yJurhGSEYMNbxwK7XhnjZyziUucBBg+55z8M9nHYP7mS1t50k2hjSKKw==",
+ "version": "0.1.27",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/stack/-/stack-0.1.27.tgz",
+ "integrity": "sha512-i+yR3MAeMcc4/g01x3J4KuxqASFpHoKfUJRQHNsVLYzwsYIw5B+r1eGXi1szmGCDfiqILG5OtJm6tXlOOz1T7A==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"@launchpad-ui/types": "~0.1.1",
"classix": "2.1.17"
},
@@ -1751,29 +1714,29 @@
}
},
"node_modules/@launchpad-ui/tab-list": {
- "version": "0.5.22",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/tab-list/-/tab-list-0.5.22.tgz",
- "integrity": "sha512-k/8SpOOuqpNSGsIblwB8S1IaJfQUSBkqjz4osl5m9AE4+E4DGg+U0+QY8ssm/PjPMEaaOh/dn1SE5KufWo94Lw==",
- "dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
- "@react-aria/tabs": "3.9.1",
- "@react-stately/tabs": "3.6.6",
- "@react-types/shared": "3.23.1",
- "@react-types/tabs": "3.3.7",
+ "version": "0.5.29",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/tab-list/-/tab-list-0.5.29.tgz",
+ "integrity": "sha512-JYAIHReEeYAD8jzy5CJtGoIbJcOkpO2bvWWVZRTlEyV/a9ihpYZHEwS+wcnkYYJE9PaPBrWf4bQcVKlEhT7RLw==",
+ "dependencies": {
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@react-aria/tabs": "3.9.5",
+ "@react-stately/tabs": "3.6.9",
+ "@react-types/shared": "3.24.1",
+ "@react-types/tabs": "3.3.9",
"classix": "2.1.17"
},
"peerDependencies": {
- "@react-stately/collections": "3.10.7",
+ "@react-stately/collections": "3.10.9",
"react": "18.3.1",
"react-dom": "18.3.1"
}
},
"node_modules/@launchpad-ui/table": {
- "version": "0.6.17",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/table/-/table-0.6.17.tgz",
- "integrity": "sha512-rOcHHgLMVGFds8aa69UDOd3mcibvVZfAIvJ8F1AYUNVc6Ynb7uUzGkjEjySbaDakbQ0zcyjYMozVcZ4WBlDVAg==",
+ "version": "0.6.22",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/table/-/table-0.6.22.tgz",
+ "integrity": "sha512-/uazU0r/drBwICrCcPili1RoXR+OeeZJsRsX+q8zD+jzXjIzlAWJxx55Omf6F9QAf0L4LpzLFd9IwCDhiev8TQ==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1782,21 +1745,21 @@
}
},
"node_modules/@launchpad-ui/tag": {
- "version": "0.3.35",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/tag/-/tag-0.3.35.tgz",
- "integrity": "sha512-RRwiaF158Wcu4b+T6Aaefzr5Yn7SK4Mg7j0bPZ7XoboClzbzranxaTm2IwC3YOPyf1GTmJ8+3bT6dRPrgBxsQw==",
- "dependencies": {
- "@launchpad-ui/button": "~0.12.17",
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
- "@launchpad-ui/tooltip": "~0.9.12",
- "@react-aria/focus": "3.17.1",
- "@react-aria/interactions": "3.21.3",
- "@react-aria/selection": "3.18.1",
- "@react-aria/tag": "3.4.1",
- "@react-aria/utils": "3.24.1",
- "@react-stately/list": "3.10.5",
- "@react-types/shared": "3.23.1",
+ "version": "0.3.46",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/tag/-/tag-0.3.46.tgz",
+ "integrity": "sha512-f4hrU3q8zNP0EfnjDu22wbMSjMbcQHGSobliMacRZpB0BmTcXFIa3Civz2rVfci65THWX+J6R9JDraFaMUvSWw==",
+ "dependencies": {
+ "@launchpad-ui/button": "~0.12.26",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@launchpad-ui/tooltip": "~0.9.19",
+ "@react-aria/focus": "3.18.2",
+ "@react-aria/interactions": "3.22.2",
+ "@react-aria/selection": "3.19.3",
+ "@react-aria/tag": "3.4.5",
+ "@react-aria/utils": "3.25.2",
+ "@react-stately/list": "3.10.8",
+ "@react-types/shared": "3.24.1",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1805,14 +1768,14 @@
}
},
"node_modules/@launchpad-ui/toast": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/toast/-/toast-0.3.31.tgz",
- "integrity": "sha512-TdFFK2sw0xqTD1olN/zw6gh09q3s92zi0v98ub3wISfZtibGf4EPjMIcx0bFbdYC13kBMoemoVRbpew2cb5Pvw==",
+ "version": "0.3.40",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/toast/-/toast-0.3.40.tgz",
+ "integrity": "sha512-2gtj43MPwc5yyzK5J45DCaog6PXceNoJX+QBkUUUsSjSHD9ZAzzEH33FLuwSo7oVnZ67v4cf79MIzkBP+5s3Bw==",
"dependencies": {
- "@launchpad-ui/icons": "~0.18.4",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/icons": "~0.18.13",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17",
- "framer-motion": "11.2.4"
+ "framer-motion": "11.3.0"
},
"peerDependencies": {
"react": "18.3.1",
@@ -1820,14 +1783,14 @@
}
},
"node_modules/@launchpad-ui/toggle": {
- "version": "0.7.22",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/toggle/-/toggle-0.7.22.tgz",
- "integrity": "sha512-X3FXxdM1a32x1qbcCLQT3C6IdBwIkt07SfRjlbYql1socANcCmWOdRD1Qd0JWjARpoDMDediGZtJZ6EsLUxroQ==",
- "dependencies": {
- "@launchpad-ui/tokens": "~0.9.12",
- "@react-aria/focus": "3.17.1",
- "@react-aria/switch": "3.6.4",
- "@react-stately/toggle": "3.7.4",
+ "version": "0.7.29",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/toggle/-/toggle-0.7.29.tgz",
+ "integrity": "sha512-FSOsXK+0fgOoufW6GVc22pD0uWfHBBxzwm6QFje2K28n2Kb8x5khW9C+gruc3o1IcZBhJCOR5bry7ZNxgjui6g==",
+ "dependencies": {
+ "@launchpad-ui/tokens": "~0.11.3",
+ "@react-aria/focus": "3.18.2",
+ "@react-aria/switch": "3.6.7",
+ "@react-stately/toggle": "3.7.7",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1836,17 +1799,17 @@
}
},
"node_modules/@launchpad-ui/tokens": {
- "version": "0.9.12",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/tokens/-/tokens-0.9.12.tgz",
- "integrity": "sha512-FEDBt0s+b0hlwkhSU/TiY5YXseLQYGKeIgqZUngmUiPTgaSvttlBm4BSVtoly3JK00ihNGZsvEtZVoUgp+zoKA=="
+ "version": "0.11.3",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/tokens/-/tokens-0.11.3.tgz",
+ "integrity": "sha512-84Tm/duRQIs31TreFMYfFbhNZSk+FQl00/l0OZ9DHk1d4j9La0Od8dJ5d6pRJg1u7Q5q/vLWg3J+lZqlfdMqlA=="
},
"node_modules/@launchpad-ui/tooltip": {
- "version": "0.9.12",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/tooltip/-/tooltip-0.9.12.tgz",
- "integrity": "sha512-qsEnQAXOEpPyyoMEN0fa1D8mgKYPMd09VGQCg65RS0KNNbK/TjewbvtKi07AZdzol1hTzArnpCaM7/INPRLBoA==",
+ "version": "0.9.19",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/tooltip/-/tooltip-0.9.19.tgz",
+ "integrity": "sha512-4+N/rPH9DwS9zjb+ssWynjOT+1MqD4ZTu90+911jhiCvb9bOnCkmKWvysVlIS8eZYjLg6ZXRPHD9CvWhY8mJ3Q==",
"dependencies": {
- "@launchpad-ui/popover": "~0.11.23",
- "@launchpad-ui/tokens": "~0.9.12",
+ "@launchpad-ui/popover": "~0.11.30",
+ "@launchpad-ui/tokens": "~0.11.3",
"classix": "2.1.17"
},
"peerDependencies": {
@@ -1860,11 +1823,11 @@
"integrity": "sha512-0mHnqVNIHNwrRe4uw5DacWp1N+WNFt6PgVs/5xAuO6tlH5WXHq1WqEg3H4rKi46sXwsepEaijdhKQC3xlajcmA=="
},
"node_modules/@launchpad-ui/vars": {
- "version": "0.2.19",
- "resolved": "https://registry.npmjs.org/@launchpad-ui/vars/-/vars-0.2.19.tgz",
- "integrity": "sha512-fvSRN/mQ+DpuaLpXO4usLaqfaqb0u0M6ryMLIMpqK9kdv5gTjbha3GWOv0MVz5PKDBWFkXdgNtvvkWzYjlgZQA==",
+ "version": "0.2.24",
+ "resolved": "https://registry.npmjs.org/@launchpad-ui/vars/-/vars-0.2.24.tgz",
+ "integrity": "sha512-8Q2J19MvMqm8aF2MHVvZTNAtzZGxTK40otf9ufh1Tjomm+qVbonRz7kmRcm4TU77K5+7uWox3oQBm8Oi5dLclQ==",
"dependencies": {
- "@launchpad-ui/tokens": "~0.9.12"
+ "@launchpad-ui/tokens": "~0.11.3"
},
"peerDependencies": {
"@vanilla-extract/css": "^1.14.0"
@@ -1911,15 +1874,12 @@
}
},
"node_modules/@radix-ui/react-compose-refs": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
- "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- },
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -1928,16 +1888,15 @@
}
},
"node_modules/@radix-ui/react-slot": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
- "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -1951,367 +1910,382 @@
"integrity": "sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ=="
},
"node_modules/@react-aria/breadcrumbs": {
- "version": "3.5.13",
- "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.13.tgz",
- "integrity": "sha512-G1Gqf/P6kVdfs94ovwP18fTWuIxadIQgHsXS08JEVcFVYMjb9YjqnEBaohUxD1tq2WldMbYw53ahQblT4NTG+g==",
- "dependencies": {
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/link": "^3.7.1",
- "@react-aria/utils": "^3.24.1",
- "@react-types/breadcrumbs": "^3.7.5",
- "@react-types/shared": "^3.23.1",
+ "version": "3.5.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.16.tgz",
+ "integrity": "sha512-OXLKKu4SmjnSaSHkk4kow5/aH/SzlHWPJt+Uq3xec9TwDOr/Ob8aeFVGFoY0HxfGozuQlUz+4e+d29vfA0jNWg==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/link": "^3.7.4",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/breadcrumbs": "^3.7.7",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/button": {
- "version": "3.9.5",
- "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.5.tgz",
- "integrity": "sha512-dgcYR6j8WDOMLKuVrtxzx4jIC05cVKDzc+HnPO8lNkBAOfjcuN5tkGRtIjLtqjMvpZHhQT5aDbgFpIaZzxgFIg==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/toggle": "^3.7.4",
- "@react-types/button": "^3.9.4",
- "@react-types/shared": "^3.23.1",
+ "version": "3.9.8",
+ "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.8.tgz",
+ "integrity": "sha512-MdbMQ3t5KSCkvKtwYd/Z6sgw0v+r1VQFRYOZ4L53xOkn+u140z8vBpNeWKZh/45gxGv7SJn9s2KstLPdCWmIxw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/toggle": "^3.7.7",
+ "@react-types/button": "^3.9.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/calendar": {
- "version": "3.5.8",
- "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.8.tgz",
- "integrity": "sha512-Whlp4CeAA5/ZkzrAHUv73kgIRYjw088eYGSc+cvSOCxfrc/2XkBm9rNrnSBv0DvhJ8AG0Fjz3vYakTmF3BgZBw==",
+ "version": "3.5.11",
+ "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.11.tgz",
+ "integrity": "sha512-VLhBovLVu3uJXBkHbgEippmo/K58QLcc/tSJQ0aJUNyHsrvPgHEcj484cb+Uj/yOirXEIzaoW6WEvhcdKrb49Q==",
"dependencies": {
- "@internationalized/date": "^3.5.4",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
+ "@internationalized/date": "^3.5.5",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
"@react-aria/live-announcer": "^3.3.4",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/calendar": "^3.5.1",
- "@react-types/button": "^3.9.4",
- "@react-types/calendar": "^3.4.6",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/calendar": "^3.5.4",
+ "@react-types/button": "^3.9.6",
+ "@react-types/calendar": "^3.4.9",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/checkbox": {
- "version": "3.14.3",
- "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.14.3.tgz",
- "integrity": "sha512-EtBJL6iu0gvrw3A4R7UeVLR6diaVk/mh4kFBc7c8hQjpEJweRr4hmJT3hrNg3MBcTWLxFiMEXPGgWEwXDBygtA==",
- "dependencies": {
- "@react-aria/form": "^3.0.5",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/label": "^3.7.8",
- "@react-aria/toggle": "^3.10.4",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/checkbox": "^3.6.5",
- "@react-stately/form": "^3.0.3",
- "@react-stately/toggle": "^3.7.4",
- "@react-types/checkbox": "^3.8.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.14.6",
+ "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.14.6.tgz",
+ "integrity": "sha512-LICY1PR3WsW/VbuLMjZbxo75+poeo3XCXGcUnk6hxMlWfp/Iy/XHVsHlGu9stRPKRF8BSuOGteaHWVn6IXfwtA==",
+ "dependencies": {
+ "@react-aria/form": "^3.0.8",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/toggle": "^3.10.7",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/checkbox": "^3.6.8",
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/toggle": "^3.7.7",
+ "@react-types/checkbox": "^3.8.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/@react-aria/collections": {
+ "version": "3.0.0-alpha.4",
+ "resolved": "https://registry.npmjs.org/@react-aria/collections/-/collections-3.0.0-alpha.4.tgz",
+ "integrity": "sha512-chMNAlsubnpErBWN7sLhmAMOnE7o17hSfq3s0VDHlvRN9K/mPOPlYokmyWkkPqi7fYiR50EPVHDtwTWLJoqfnw==",
+ "dependencies": {
+ "@react-aria/ssr": "^3.9.5",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/color": {
- "version": "3.0.0-beta.33",
- "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.0-beta.33.tgz",
- "integrity": "sha512-nhqnIHYm5p6MbuF3cC6lnqzG7MjwBsBd0DtpO+ByFYO+zxpMMbeC5R+1SFxvapR4uqmAzTotbtiUCGsG+SUaIg==",
- "dependencies": {
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/numberfield": "^3.11.3",
- "@react-aria/slider": "^3.7.8",
- "@react-aria/spinbutton": "^3.6.5",
- "@react-aria/textfield": "^3.14.5",
- "@react-aria/utils": "^3.24.1",
- "@react-aria/visually-hidden": "^3.8.12",
- "@react-stately/color": "^3.6.1",
- "@react-stately/form": "^3.0.3",
- "@react-types/color": "3.0.0-beta.25",
- "@react-types/shared": "^3.23.1",
+ "version": "3.0.0-rc.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.0-rc.2.tgz",
+ "integrity": "sha512-h4P7LocDEHPOEWgHYb8VPJLRGkyMhcsXemmvGao6G23zGTpTX8Nr6pEuJhcXQlGWt8hXvj/ASnC750my+zb1yA==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/numberfield": "^3.11.6",
+ "@react-aria/slider": "^3.7.11",
+ "@react-aria/spinbutton": "^3.6.8",
+ "@react-aria/textfield": "^3.14.8",
+ "@react-aria/utils": "^3.25.2",
+ "@react-aria/visually-hidden": "^3.8.15",
+ "@react-stately/color": "^3.7.2",
+ "@react-stately/form": "^3.0.5",
+ "@react-types/color": "3.0.0-rc.1",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/combobox": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.9.1.tgz",
- "integrity": "sha512-SpK92dCmT8qn8aEcUAihRQrBb5LZUhwIbDExFII8PvUvEFy/PoQHXIo3j1V29WkutDBDpMvBv/6XRCHGXPqrhQ==",
+ "version": "3.10.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.10.3.tgz",
+ "integrity": "sha512-EdDwr2Rp1xy7yWjOYHt2qF1IpAtUrkaNKZJzlIw1XSwcqizQY6E8orNPdZr6ZwD6/tgujxF1N71JTKyffrR0Xw==",
"dependencies": {
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/listbox": "^3.12.1",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/listbox": "^3.13.3",
"@react-aria/live-announcer": "^3.3.4",
- "@react-aria/menu": "^3.14.1",
- "@react-aria/overlays": "^3.22.1",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/textfield": "^3.14.5",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/collections": "^3.10.7",
- "@react-stately/combobox": "^3.8.4",
- "@react-stately/form": "^3.0.3",
- "@react-types/button": "^3.9.4",
- "@react-types/combobox": "^3.11.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/menu": "^3.15.3",
+ "@react-aria/overlays": "^3.23.2",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/textfield": "^3.14.8",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/combobox": "^3.9.2",
+ "@react-stately/form": "^3.0.5",
+ "@react-types/button": "^3.9.6",
+ "@react-types/combobox": "^3.12.1",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/datepicker": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.10.1.tgz",
- "integrity": "sha512-4HZL593nrNMa1GjBmWEN/OTvNS6d3/16G1YJWlqiUlv11ADulSbqBIjMmkgwrJVFcjrgqtXFy+yyrTA/oq94Zw==",
+ "version": "3.11.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.11.2.tgz",
+ "integrity": "sha512-6sbLln3VXSBcBRDgSACBzIzF/5KV5NlNOhZvXPFE6KqFw6GbevjZQTv5BNDXiwA3CQoawIRF7zgRvTANw8HkNA==",
"dependencies": {
- "@internationalized/date": "^3.5.4",
+ "@internationalized/date": "^3.5.5",
"@internationalized/number": "^3.5.3",
"@internationalized/string": "^3.2.3",
- "@react-aria/focus": "^3.17.1",
- "@react-aria/form": "^3.0.5",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/label": "^3.7.8",
- "@react-aria/spinbutton": "^3.6.5",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/datepicker": "^3.9.4",
- "@react-stately/form": "^3.0.3",
- "@react-types/button": "^3.9.4",
- "@react-types/calendar": "^3.4.6",
- "@react-types/datepicker": "^3.7.4",
- "@react-types/dialog": "^3.5.10",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/form": "^3.0.8",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/spinbutton": "^3.6.8",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/datepicker": "^3.10.2",
+ "@react-stately/form": "^3.0.5",
+ "@react-types/button": "^3.9.6",
+ "@react-types/calendar": "^3.4.9",
+ "@react-types/datepicker": "^3.8.2",
+ "@react-types/dialog": "^3.5.12",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/dialog": {
- "version": "3.5.14",
- "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.14.tgz",
- "integrity": "sha512-oqDCjQ8hxe3GStf48XWBf2CliEnxlR9GgSYPHJPUc69WBj68D9rVcCW3kogJnLAnwIyf3FnzbX4wSjvUa88sAQ==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/overlays": "^3.22.1",
- "@react-aria/utils": "^3.24.1",
- "@react-types/dialog": "^3.5.10",
- "@react-types/shared": "^3.23.1",
+ "version": "3.5.17",
+ "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.17.tgz",
+ "integrity": "sha512-lvfEgaqg922J1hurscqCS600OZQVitGtdpo81kAefJaUzMnCxzrYviyT96aaW0simHOlimbYF5js8lxBLZJRaw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/overlays": "^3.23.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/dialog": "^3.5.12",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/dnd": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.6.1.tgz",
- "integrity": "sha512-6WnujUTD+cIYZVF/B+uXdHyJ+WSpbYa8jH282epvY4FUAq1qLmen12/HHcoj/5dswKQe8X6EM3OhkQM89d9vFw==",
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.7.2.tgz",
+ "integrity": "sha512-NuE3EGqoBbe9aXAO9mDfbu4kMO7S4MCgkjkCqYi16TWfRUf38ajQbIlqodCx91b3LVN3SYvNbE3D4Tj5ebkljw==",
"dependencies": {
"@internationalized/string": "^3.2.3",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
"@react-aria/live-announcer": "^3.3.4",
- "@react-aria/overlays": "^3.22.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/dnd": "^3.3.1",
- "@react-types/button": "^3.9.4",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/overlays": "^3.23.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/dnd": "^3.4.2",
+ "@react-types/button": "^3.9.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/focus": {
- "version": "3.17.1",
- "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.17.1.tgz",
- "integrity": "sha512-FLTySoSNqX++u0nWZJPPN5etXY0WBxaIe/YuL/GTEeuqUIuC/2bJSaw5hlsM6T2yjy6Y/VAxBcKSdAFUlU6njQ==",
+ "version": "3.18.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.2.tgz",
+ "integrity": "sha512-Jc/IY+StjA3uqN73o6txKQ527RFU7gnG5crEl5Xy3V+gbYp2O5L3ezAo/E0Ipi2cyMbG6T5Iit1IDs7hcGu8aw==",
"dependencies": {
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0",
"clsx": "^2.0.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/form": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.5.tgz",
- "integrity": "sha512-n290jRwrrRXO3fS82MyWR+OKN7yznVesy5Q10IclSTVYHHI3VI53xtAPr/WzNjJR1um8aLhOcDNFKwnNIUUCsQ==",
- "dependencies": {
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/form": "^3.0.3",
- "@react-types/shared": "^3.23.1",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.8.tgz",
+ "integrity": "sha512-8S2QiyUdAgK43M3flohI0R+2rTyzH088EmgeRArA8euvJTL16cj/oSOKMEgWVihjotJ9n6awPb43ZhKboyNsMg==",
+ "dependencies": {
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/form": "^3.0.5",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/grid": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.9.1.tgz",
- "integrity": "sha512-fGEZqAEaS8mqzV/II3N4ndoNWegIcbh+L3PmKbXdpKKUP8VgMs/WY5rYl5WAF0f5RoFwXqx3ibDLeR9tKj/bOg==",
+ "version": "3.10.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.10.3.tgz",
+ "integrity": "sha512-l0r9mz05Gwjq3t6JOTNQOf+oAoWN0bXELPJtIr8m0XyXMPFCQe1xsTaX8igVQdrDmXyBc75RAWS0BJo2JF2fIA==",
"dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
"@react-aria/live-announcer": "^3.3.4",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/collections": "^3.10.7",
- "@react-stately/grid": "^3.8.7",
- "@react-stately/selection": "^3.15.1",
- "@react-stately/virtualizer": "^3.7.1",
- "@react-types/checkbox": "^3.8.1",
- "@react-types/grid": "^3.2.6",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/grid": "^3.9.2",
+ "@react-stately/selection": "^3.16.2",
+ "@react-types/checkbox": "^3.8.3",
+ "@react-types/grid": "^3.2.8",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/gridlist": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.8.1.tgz",
- "integrity": "sha512-vVPkkA+Ct0NDcpnNm/tnYaBumg0fP9pXxsPLqL1rxvsTyj1PaIpFTZ4corabPTbTDExZwUSTS3LG1n+o1OvBtQ==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/grid": "^3.9.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/collections": "^3.10.7",
- "@react-stately/list": "^3.10.5",
- "@react-stately/tree": "^3.8.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.9.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.9.3.tgz",
+ "integrity": "sha512-bb9GnKKeuL6NljoVUcHxr9F0cy/2WDOXRYeMikTnviRw6cuX95oojrhFfCUvz2d6ID22Btrvh7LkE+oIPVuc+g==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/grid": "^3.10.3",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/list": "^3.10.8",
+ "@react-stately/tree": "^3.8.4",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/i18n": {
- "version": "3.11.1",
- "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.11.1.tgz",
- "integrity": "sha512-vuiBHw1kZruNMYeKkTGGnmPyMnM5T+gT8bz97H1FqIq1hQ6OPzmtBZ6W6l6OIMjeHI5oJo4utTwfZl495GALFQ==",
+ "version": "3.12.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.2.tgz",
+ "integrity": "sha512-PvEyC6JWylTpe8dQEWqQwV6GiA+pbTxHQd//BxtMSapRW3JT9obObAnb/nFhj3HthkUvqHyj0oO1bfeN+mtD8A==",
"dependencies": {
- "@internationalized/date": "^3.5.4",
+ "@internationalized/date": "^3.5.5",
"@internationalized/message": "^3.1.4",
"@internationalized/number": "^3.5.3",
"@internationalized/string": "^3.2.3",
- "@react-aria/ssr": "^3.9.4",
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/ssr": "^3.9.5",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/interactions": {
- "version": "3.21.3",
- "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.3.tgz",
- "integrity": "sha512-BWIuf4qCs5FreDJ9AguawLVS0lV9UU+sK4CCnbCNNmYqOWY+1+gRXCsnOM32K+oMESBxilAjdHW5n1hsMqYMpA==",
+ "version": "3.22.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.2.tgz",
+ "integrity": "sha512-xE/77fRVSlqHp2sfkrMeNLrqf2amF/RyuAS6T5oDJemRSgYM3UoxTbWjucPhfnoW7r32pFPHHgz4lbdX8xqD/g==",
"dependencies": {
- "@react-aria/ssr": "^3.9.4",
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/ssr": "^3.9.5",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/label": {
- "version": "3.7.8",
- "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.8.tgz",
- "integrity": "sha512-MzgTm5+suPA3KX7Ug6ZBK2NX9cin/RFLsv1BdafJ6CZpmUSpWnGE/yQfYUB7csN7j31OsZrD3/P56eShYWAQfg==",
+ "version": "3.7.11",
+ "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.11.tgz",
+ "integrity": "sha512-REgejE5Qr8cXG/b8H2GhzQmjQlII/0xQW/4eDzydskaTLvA7lF5HoJUE6biYTquH5va38d8XlH465RPk+bvHzA==",
"dependencies": {
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/landmark": {
- "version": "3.0.0-beta.12",
- "resolved": "https://registry.npmjs.org/@react-aria/landmark/-/landmark-3.0.0-beta.12.tgz",
- "integrity": "sha512-xCAYw0cxn115ZaTXyGXALW2Jebm56s7oX/R0/REubiHwkuDSRxRnYXbaaHxGXNsJWex5LGIZbUYaumGjGrzOnw==",
+ "version": "3.0.0-beta.15",
+ "resolved": "https://registry.npmjs.org/@react-aria/landmark/-/landmark-3.0.0-beta.15.tgz",
+ "integrity": "sha512-EEABy0IFzqoS7r11HoD2YwiGR5LFw4kWDFTFUFwJkRP5tHEzsrEgkKPSPJXScQr5m7tenV6j0/Zzl1+w1ki3lA==",
"dependencies": {
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0",
"use-sync-external-store": "^1.2.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/link": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.1.tgz",
- "integrity": "sha512-a4IaV50P3fXc7DQvEIPYkJJv26JknFbRzFT5MJOMgtzuhyJoQdILEUK6XHYjcSSNCA7uLgzpojArVk5Hz3lCpw==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/utils": "^3.24.1",
- "@react-types/link": "^3.5.5",
- "@react-types/shared": "^3.23.1",
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.4.tgz",
+ "integrity": "sha512-E8SLDuS9ssm/d42+3sDFNthfMcNXMUrT2Tq1DIZt22EsMcuEzmJ9B0P7bDP5RgvIw05xVGqZ20nOpU4mKTxQtA==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/link": "^3.5.7",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/listbox": {
- "version": "3.12.1",
- "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.12.1.tgz",
- "integrity": "sha512-7JiUp0NGykbv/HgSpmTY1wqhuf/RmjFxs1HZcNaTv8A+DlzgJYc7yQqFjP3ZA/z5RvJFuuIxggIYmgIFjaRYdA==",
- "dependencies": {
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/label": "^3.7.8",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/collections": "^3.10.7",
- "@react-stately/list": "^3.10.5",
- "@react-types/listbox": "^3.4.9",
- "@react-types/shared": "^3.23.1",
+ "version": "3.13.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.13.3.tgz",
+ "integrity": "sha512-htluPyDfFtn66OEYaJdIaFCYH9wGCNk30vOgZrQkPul9F9Cjce52tTyPVR0ERsf14oCUsjjS5qgeq3dGidRqEw==",
+ "dependencies": {
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/list": "^3.10.8",
+ "@react-types/listbox": "^3.5.1",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/live-announcer": {
@@ -2323,237 +2297,237 @@
}
},
"node_modules/@react-aria/menu": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.14.1.tgz",
- "integrity": "sha512-BYliRb38uAzq05UOFcD5XkjA5foQoXRbcH3ZufBsc4kvh79BcP1PMW6KsXKGJ7dC/PJWUwCui6QL1kUg8PqMHA==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/overlays": "^3.22.1",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/collections": "^3.10.7",
- "@react-stately/menu": "^3.7.1",
- "@react-stately/tree": "^3.8.1",
- "@react-types/button": "^3.9.4",
- "@react-types/menu": "^3.9.9",
- "@react-types/shared": "^3.23.1",
+ "version": "3.15.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.15.3.tgz",
+ "integrity": "sha512-vvUmVjJwIg3h2r+7isQXTwlmoDlPAFBckHkg94p3afrT1kNOTHveTsaVl17mStx/ymIioaAi3PrIXk/PZXp1jw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/overlays": "^3.23.2",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/menu": "^3.8.2",
+ "@react-stately/tree": "^3.8.4",
+ "@react-types/button": "^3.9.6",
+ "@react-types/menu": "^3.9.11",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/meter": {
- "version": "3.4.13",
- "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.13.tgz",
- "integrity": "sha512-oG6KvHQM3ri93XkYQkgEaMKSMO9KNDVpcW1MUqFfqyUXHFBRZRrJB4BTXMZ4nyjheFVQjVboU51fRwoLjOzThg==",
+ "version": "3.4.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.16.tgz",
+ "integrity": "sha512-hJqKnEE6mmK2Psx5kcI7NZ44OfTg0Bp7DatQSQ4zZE4yhnykRRwxqSKjze37tPR63cCqgRXtQ5LISfBfG54c0Q==",
"dependencies": {
- "@react-aria/progress": "^3.4.13",
- "@react-types/meter": "^3.4.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/progress": "^3.4.16",
+ "@react-types/meter": "^3.4.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/numberfield": {
- "version": "3.11.3",
- "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.3.tgz",
- "integrity": "sha512-QQ9ZTzBbRI8d9ksaBWm6YVXbgv+5zzUsdxVxwzJVXLznvivoORB8rpdFJzUEWVCo25lzoBxluCEPYtLOxP1B0w==",
- "dependencies": {
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/spinbutton": "^3.6.5",
- "@react-aria/textfield": "^3.14.5",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/form": "^3.0.3",
- "@react-stately/numberfield": "^3.9.3",
- "@react-types/button": "^3.9.4",
- "@react-types/numberfield": "^3.8.3",
- "@react-types/shared": "^3.23.1",
+ "version": "3.11.6",
+ "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.6.tgz",
+ "integrity": "sha512-nvEWiQcWRwj6O2JXmkXEeWoBX/GVZT9zumFJcew3XknGTWJUr3h2AOymIQFt9g4mpag8IgOFEpSIlwhtZHdp1A==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/spinbutton": "^3.6.8",
+ "@react-aria/textfield": "^3.14.8",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/numberfield": "^3.9.6",
+ "@react-types/button": "^3.9.6",
+ "@react-types/numberfield": "^3.8.5",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/overlays": {
- "version": "3.22.1",
- "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.22.1.tgz",
- "integrity": "sha512-GHiFMWO4EQ6+j6b5QCnNoOYiyx1Gk8ZiwLzzglCI4q1NY5AG2EAmfU4Z1+Gtrf2S5Y0zHbumC7rs9GnPoGLUYg==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/ssr": "^3.9.4",
- "@react-aria/utils": "^3.24.1",
- "@react-aria/visually-hidden": "^3.8.12",
- "@react-stately/overlays": "^3.6.7",
- "@react-types/button": "^3.9.4",
- "@react-types/overlays": "^3.8.7",
- "@react-types/shared": "^3.23.1",
+ "version": "3.23.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.23.2.tgz",
+ "integrity": "sha512-vjlplr953YAuJfHiP4O+CyrTlr6OaFgXAGrzWq4MVMjnpV/PT5VRJWYFHR0sUGlHTPqeKS4NZbi/xCSgl/3pGQ==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/ssr": "^3.9.5",
+ "@react-aria/utils": "^3.25.2",
+ "@react-aria/visually-hidden": "^3.8.15",
+ "@react-stately/overlays": "^3.6.10",
+ "@react-types/button": "^3.9.6",
+ "@react-types/overlays": "^3.8.9",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/progress": {
- "version": "3.4.13",
- "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.13.tgz",
- "integrity": "sha512-YBV9bOO5JzKvG8QCI0IAA00o6FczMgIDiK8Q9p5gKorFMatFUdRayxlbIPoYHMi+PguLil0jHgC7eOyaUcrZ0g==",
- "dependencies": {
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/label": "^3.7.8",
- "@react-aria/utils": "^3.24.1",
- "@react-types/progress": "^3.5.4",
- "@react-types/shared": "^3.23.1",
+ "version": "3.4.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.16.tgz",
+ "integrity": "sha512-RbDIFQg4+/LG+KYZeLAijt2zH7K2Gp0CY9RKWdho3nU5l3/w57Fa7NrfDGWtpImrt7bR2nRmXMA6ESfr7THfrg==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/progress": "^3.5.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/radio": {
- "version": "3.10.4",
- "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.4.tgz",
- "integrity": "sha512-3fmoMcQtCpgjTwJReFjnvIE/C7zOZeCeWUn4JKDqz9s1ILYsC3Rk5zZ4q66tFn6v+IQnecrKT52wH6+hlVLwTA==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/form": "^3.0.5",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/label": "^3.7.8",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/radio": "^3.10.4",
- "@react-types/radio": "^3.8.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.10.7",
+ "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.7.tgz",
+ "integrity": "sha512-o2tqIe7xd1y4HeCBQfz/sXIwLJuI6LQbVoCQ1hgk/5dGhQ0LiuXohRYitGRl9zvxW8jYdgLULmOEDt24IflE8A==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/form": "^3.0.8",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/radio": "^3.10.7",
+ "@react-types/radio": "^3.8.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/searchfield": {
- "version": "3.7.5",
- "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.7.5.tgz",
- "integrity": "sha512-h1sMUOWjhevaKKUHab/luHbM6yiyeN57L4RxZU0IIc9Ww0h5Rp2GUuKZA3pcdPiExHje0aijcImL3wBHEbKAzw==",
- "dependencies": {
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/textfield": "^3.14.5",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/searchfield": "^3.5.3",
- "@react-types/button": "^3.9.4",
- "@react-types/searchfield": "^3.5.5",
- "@react-types/shared": "^3.23.1",
+ "version": "3.7.8",
+ "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.7.8.tgz",
+ "integrity": "sha512-SsF5xwH8Us548QgzivvbM7nhFbw7pu23xnRRIuhlP3MwOR3jRUFh17NKxf3Z0jvrDv/u0xfm3JKHIgaUN0KJ2A==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/textfield": "^3.14.8",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/searchfield": "^3.5.6",
+ "@react-types/button": "^3.9.6",
+ "@react-types/searchfield": "^3.5.8",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/select": {
- "version": "3.14.5",
- "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.5.tgz",
- "integrity": "sha512-s8jixBuTUNdKWRHe2tIJqp55ORHeUObGMw1s7PQRRVrrHPdNSYseAOI9B2W7qpl3hKhvjJg40UW+45mcb1WKbw==",
- "dependencies": {
- "@react-aria/form": "^3.0.5",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/label": "^3.7.8",
- "@react-aria/listbox": "^3.12.1",
- "@react-aria/menu": "^3.14.1",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/utils": "^3.24.1",
- "@react-aria/visually-hidden": "^3.8.12",
- "@react-stately/select": "^3.6.4",
- "@react-types/button": "^3.9.4",
- "@react-types/select": "^3.9.4",
- "@react-types/shared": "^3.23.1",
+ "version": "3.14.9",
+ "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.9.tgz",
+ "integrity": "sha512-tiNgMyA2G9nKnFn3pB/lMSgidNToxSFU7r6l4OcG+Vyr63J7B/3dF2lTXq8IYhlfOR3K3uQkjroSx52CmC3NDw==",
+ "dependencies": {
+ "@react-aria/form": "^3.0.8",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/listbox": "^3.13.3",
+ "@react-aria/menu": "^3.15.3",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/utils": "^3.25.2",
+ "@react-aria/visually-hidden": "^3.8.15",
+ "@react-stately/select": "^3.6.7",
+ "@react-types/button": "^3.9.6",
+ "@react-types/select": "^3.9.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/selection": {
- "version": "3.18.1",
- "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.18.1.tgz",
- "integrity": "sha512-GSqN2jX6lh7v+ldqhVjAXDcrWS3N4IsKXxO6L6Ygsye86Q9q9Mq9twWDWWu5IjHD6LoVZLUBCMO+ENGbOkyqeQ==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/selection": "^3.15.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.19.3.tgz",
+ "integrity": "sha512-GYoObXCXlmGK08hp7Qfl6Bk0U+bKP5YDWSsX+MzNjJsqzQSLm4S06tRB9ACM7gIo9dDCvL4IRxdSYTJAlJc6bw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/selection": "^3.16.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/separator": {
- "version": "3.3.13",
- "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.3.13.tgz",
- "integrity": "sha512-hofA6JCPnAOqSE9vxnq7Dkazr7Kb2A0I5sR16fOG7ddjYRc/YEY5Nv7MWfKUGU0kNFHkgNjsDAILERtLechzeA==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.2.tgz",
+ "integrity": "sha512-Xql9Kg3VlGesEUC7QheE+L5b3KgBv0yxiUU+/4JP8V2vfU/XSz4xmprHEeq7KVQVOetn38iiXU8gA5g26SEsUA==",
"dependencies": {
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/slider": {
- "version": "3.7.8",
- "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.8.tgz",
- "integrity": "sha512-MYvPcM0K8jxEJJicUK2+WxUkBIM/mquBxOTOSSIL3CszA80nXIGVnLlCUnQV3LOUzpWtabbWaZokSPtGgOgQOw==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/label": "^3.7.8",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/slider": "^3.5.4",
- "@react-types/shared": "^3.23.1",
- "@react-types/slider": "^3.7.3",
+ "version": "3.7.11",
+ "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.11.tgz",
+ "integrity": "sha512-2WAwjANXPsA2LHJ5nxxV4c7ihFAzz2spaBz8+FJ7MDYE7WroYnE8uAXElea1aGo+Lk0DTiAdepLpBkggqPNanw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/slider": "^3.5.7",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/slider": "^3.7.5",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/spinbutton": {
- "version": "3.6.5",
- "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.5.tgz",
- "integrity": "sha512-0aACBarF/Xr/7ixzjVBTQ0NBwwwsoGkf5v6AVFVMTC0uYMXHTALvRs+ULHjHMa5e/cX/aPlEvaVT7jfSs+Xy9Q==",
+ "version": "3.6.8",
+ "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.8.tgz",
+ "integrity": "sha512-OJMAYRIZ0WrWE+5tZsywrSg4t+aOwl6vl/e1+J64YcGMM+p+AKd61KGG5T0OgNSORXjoVIZOmj6wZ6Od4xfPMw==",
"dependencies": {
- "@react-aria/i18n": "^3.11.1",
+ "@react-aria/i18n": "^3.12.2",
"@react-aria/live-announcer": "^3.3.4",
- "@react-aria/utils": "^3.24.1",
- "@react-types/button": "^3.9.4",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/button": "^3.9.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/ssr": {
- "version": "3.9.4",
- "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz",
- "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==",
+ "version": "3.9.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.5.tgz",
+ "integrity": "sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
@@ -2561,345 +2535,363 @@
"node": ">= 12"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/switch": {
- "version": "3.6.4",
- "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.4.tgz",
- "integrity": "sha512-2nVqz4ZuJyof47IpGSt3oZRmp+EdS8wzeDYgf42WHQXrx4uEOk1mdLJ20+NnsYhj/2NHZsvXVrjBeKMjlMs+0w==",
+ "version": "3.6.7",
+ "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.7.tgz",
+ "integrity": "sha512-yBNvKylhc3ZRQ0+7mD0mIenRRe+1yb8YaqMMZr8r3Bf87LaiFtQyhRFziq6ZitcwTJz5LEWjBihxbSVvUrf49w==",
"dependencies": {
- "@react-aria/toggle": "^3.10.4",
- "@react-stately/toggle": "^3.7.4",
- "@react-types/switch": "^3.5.3",
+ "@react-aria/toggle": "^3.10.7",
+ "@react-stately/toggle": "^3.7.7",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/switch": "^3.5.5",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/table": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.14.1.tgz",
- "integrity": "sha512-WaPgQe4zQF5OaluO5rm+Y2nEoFR63vsLd4BT4yjK1uaFhKhDY2Zk+1SCVQvBLLKS4WK9dhP05nrNzT0vp/ZPOw==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/grid": "^3.9.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
+ "version": "3.15.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.15.3.tgz",
+ "integrity": "sha512-nQCLjlEvyJHyuijHw8ESqnA9fxNJfQHx0WPcl08VDEb8VxcE/MVzSAIedSWaqjG5k9Oflz6o/F/zHtzw4AFAow==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/grid": "^3.10.3",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
"@react-aria/live-announcer": "^3.3.4",
- "@react-aria/utils": "^3.24.1",
- "@react-aria/visually-hidden": "^3.8.12",
- "@react-stately/collections": "^3.10.7",
+ "@react-aria/utils": "^3.25.2",
+ "@react-aria/visually-hidden": "^3.8.15",
+ "@react-stately/collections": "^3.10.9",
"@react-stately/flags": "^3.0.3",
- "@react-stately/table": "^3.11.8",
- "@react-stately/virtualizer": "^3.7.1",
- "@react-types/checkbox": "^3.8.1",
- "@react-types/grid": "^3.2.6",
- "@react-types/shared": "^3.23.1",
- "@react-types/table": "^3.9.5",
+ "@react-stately/table": "^3.12.2",
+ "@react-types/checkbox": "^3.8.3",
+ "@react-types/grid": "^3.2.8",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/table": "^3.10.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/tabs": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.1.tgz",
- "integrity": "sha512-S5v/0sRcOaSXaJYZuuy1ZVzYc7JD4sDyseG1133GjyuNjJOFHgoWMb+b4uxNIJbZxnLgynn/ZDBZSO+qU+fIxw==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/tabs": "^3.6.6",
- "@react-types/shared": "^3.23.1",
- "@react-types/tabs": "^3.3.7",
+ "version": "3.9.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.5.tgz",
+ "integrity": "sha512-aQZGAoOIg1B16qlvXIy6+rHbNBNVcWkGjOjeyvqTTPMjXt/FmElkICnqckI7MRJ1lTqzyppCOBitYOHSXRo8Uw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/tabs": "^3.6.9",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/tabs": "^3.3.9",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/tag": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.1.tgz",
- "integrity": "sha512-gcIGPYZ2OBwMT4IHnlczEezKlxr0KRPL/mSfm2Q91GE027ZGOJnqusH9az6DX1qxrQx8x3vRdqYT2KmuefkrBQ==",
- "dependencies": {
- "@react-aria/gridlist": "^3.8.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/label": "^3.7.8",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/list": "^3.10.5",
- "@react-types/button": "^3.9.4",
- "@react-types/shared": "^3.23.1",
+ "version": "3.4.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.5.tgz",
+ "integrity": "sha512-iyJuATQ8t2cdLC7hiZm143eeZze/MtgxaMq0OewlI9TUje54bkw2Q+CjERdgisIo3Eemf55JJgylGrTcalEJAg==",
+ "dependencies": {
+ "@react-aria/gridlist": "^3.9.3",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/list": "^3.10.8",
+ "@react-types/button": "^3.9.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/textfield": {
- "version": "3.14.5",
- "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.5.tgz",
- "integrity": "sha512-hj7H+66BjB1iTKKaFXwSZBZg88YT+wZboEXZ0DNdQB2ytzoz/g045wBItUuNi4ZjXI3P+0AOZznVMYadWBAmiA==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/form": "^3.0.5",
- "@react-aria/label": "^3.7.8",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/form": "^3.0.3",
- "@react-stately/utils": "^3.10.1",
- "@react-types/shared": "^3.23.1",
- "@react-types/textfield": "^3.9.3",
+ "version": "3.14.8",
+ "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.8.tgz",
+ "integrity": "sha512-FHEvsHdE1cMR2B7rlf+HIneITrC40r201oLYbHAp3q26jH/HUujzFBB9I20qhXjyBohMWfQLqJhSwhs1VW1RJQ==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/form": "^3.0.8",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/textfield": "^3.9.6",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/toast": {
- "version": "3.0.0-beta.12",
- "resolved": "https://registry.npmjs.org/@react-aria/toast/-/toast-3.0.0-beta.12.tgz",
- "integrity": "sha512-cNchqcvK+WJ+CTMzXBk8GzlsqEUUtbyLxz4BUgKHzysac50uhpbjdYbb+5cKetEaU6/wJ75VECk35wiLYkc16w==",
- "dependencies": {
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/landmark": "3.0.0-beta.12",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/toast": "3.0.0-beta.4",
- "@react-types/button": "^3.9.4",
- "@react-types/shared": "^3.23.1",
+ "version": "3.0.0-beta.15",
+ "resolved": "https://registry.npmjs.org/@react-aria/toast/-/toast-3.0.0-beta.15.tgz",
+ "integrity": "sha512-bg6ZXq4B5JYVt3GXVlf075tQOakcfumbDLnUMaijez4BhacuxF01+IvBPzAVEsARVNXfELoXa7Frb2K54Wgvtw==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/landmark": "3.0.0-beta.15",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/toast": "3.0.0-beta.5",
+ "@react-types/button": "^3.9.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/toggle": {
- "version": "3.10.4",
- "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.4.tgz",
- "integrity": "sha512-bRk+CdB8QzrSyGNjENXiTWxfzYKRw753iwQXsEAU7agPCUdB8cZJyrhbaUoD0rwczzTp2zDbZ9rRbUPdsBE2YQ==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/toggle": "^3.7.4",
- "@react-types/checkbox": "^3.8.1",
+ "version": "3.10.7",
+ "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.7.tgz",
+ "integrity": "sha512-/RJQU8QlPZXRElZ3Tt10F5K5STgUBUGPpfuFUGuwF3Kw3GpPxYsA1YAVjxXz2MMGwS0+y6+U/J1xIs1AF0Jwzg==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/toggle": "^3.7.7",
+ "@react-types/checkbox": "^3.8.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/toolbar": {
- "version": "3.0.0-beta.5",
- "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.5.tgz",
- "integrity": "sha512-c8spY7aeLI6L+ygdXvEbAzaT41vExsxZ1Ld0t7BB+6iEF3nyBNJHshjkgdR7nv8FLgNk0no4tj0GTq4Jj4UqHQ==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.0.0-beta.8",
+ "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.8.tgz",
+ "integrity": "sha512-nMlA1KK54/Kohb3HlHAzobg69PVIEr8Q1j5P3tLd9apY8FgGvnz7yLpcj6kO1GA872gseEzgiO0Rzk+yRHQRCA==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/tooltip": {
- "version": "3.7.4",
- "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.4.tgz",
- "integrity": "sha512-+XRx4HlLYqWY3fB8Z60bQi/rbWDIGlFUtXYbtoa1J+EyRWfhpvsYImP8qeeNO/vgjUtDy1j9oKa8p6App9mBMQ==",
- "dependencies": {
- "@react-aria/focus": "^3.17.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/tooltip": "^3.4.9",
- "@react-types/shared": "^3.23.1",
- "@react-types/tooltip": "^3.4.9",
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.7.tgz",
+ "integrity": "sha512-UOTTDbbUz7OaE48VjNSWl+XQbYCUs5Gss4I3Tv1pfRLXzVtGYXv3ur/vRayvZR0xd12ANY26fZPNkSmCFpmiXw==",
+ "dependencies": {
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/tooltip": "^3.4.12",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/tooltip": "^3.4.11",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/tree": {
- "version": "3.0.0-alpha.1",
- "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.0-alpha.1.tgz",
- "integrity": "sha512-CucyeJ4VeAvWO5UJHt/l9JO65CVtsOVUctMOVNCQS77Isqp3olX9pvfD3LXt8fD5Ph2g0Q/b7siVpX5ieVB32g==",
- "dependencies": {
- "@react-aria/gridlist": "^3.8.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/tree": "^3.8.1",
- "@react-types/button": "^3.9.4",
- "@react-types/shared": "^3.23.1",
+ "version": "3.0.0-alpha.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.0-alpha.5.tgz",
+ "integrity": "sha512-6JtkvQ/KQNFyqxc5M6JMVY63heHt2gZAwXxEt+Ojx/sbWDtDb5RrZVgkb44n7R/tMrFPJEiYZLMFPbGCsUQeJQ==",
+ "dependencies": {
+ "@react-aria/gridlist": "^3.9.3",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/tree": "^3.8.4",
+ "@react-types/button": "^3.9.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/utils": {
- "version": "3.24.1",
- "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.24.1.tgz",
- "integrity": "sha512-O3s9qhPMd6n42x9sKeJ3lhu5V1Tlnzhu6Yk8QOvDuXf7UGuUjXf9mzfHJt1dYzID4l9Fwm8toczBzPM9t0jc8Q==",
+ "version": "3.25.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.25.2.tgz",
+ "integrity": "sha512-GdIvG8GBJJZygB4L2QJP1Gabyn2mjFsha73I2wSe+o4DYeGWoJiMZRM06PyTIxLH4S7Sn7eVDtsSBfkc2VY/NA==",
"dependencies": {
- "@react-aria/ssr": "^3.9.4",
- "@react-stately/utils": "^3.10.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/ssr": "^3.9.5",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0",
"clsx": "^2.0.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/@react-aria/virtualizer": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-4.0.2.tgz",
+ "integrity": "sha512-HNhpZl53UM2Z8g0DNvjAW7aZRwOReYgKRxdTF/IlYHNMLpdqWZinKwLbxZCsbgX3SCjdIGns90YhkMSKVpfrpw==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-stately/virtualizer": "^4.0.2",
+ "@react-types/shared": "^3.24.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-aria/visually-hidden": {
- "version": "3.8.12",
- "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.12.tgz",
- "integrity": "sha512-Bawm+2Cmw3Xrlr7ARzl2RLtKh0lNUdJ0eNqzWcyx4c0VHUAWtThmH5l+HRqFUGzzutFZVo89SAy40BAbd0gjVw==",
+ "version": "3.8.15",
+ "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.15.tgz",
+ "integrity": "sha512-l+sJ7xTdD5Sd6+rDNDaeJCSPnHOsI+BaJyApvb/YcVgHa7rB47lp6TXCWUCDItcPY4JqRGyeByRJVrtzBFTWCw==",
"dependencies": {
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/calendar": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.1.tgz",
- "integrity": "sha512-7l7QhqGUJ5AzWHfvZzbTe3J4t72Ht5BmhW4hlVI7flQXtfrmYkVtl3ZdytEZkkHmWGYZRW9b4IQTQGZxhtlElA==",
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.4.tgz",
+ "integrity": "sha512-R2011mtFSXIjzMXaA+CZ1sflPm9XkTBMqVk77Bnxso2ZsG7FUX8nqFmaDavxwTuHFC6OUexAGSMs8bP9KycTNg==",
"dependencies": {
- "@internationalized/date": "^3.5.4",
- "@react-stately/utils": "^3.10.1",
- "@react-types/calendar": "^3.4.6",
- "@react-types/shared": "^3.23.1",
+ "@internationalized/date": "^3.5.5",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/calendar": "^3.4.9",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/checkbox": {
- "version": "3.6.5",
- "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.5.tgz",
- "integrity": "sha512-IXV3f9k+LtmfQLE+DKIN41Q5QB/YBLDCB1YVx5PEdRp52S9+EACD5683rjVm8NVRDwjMi2SP6RnFRk7fVb5Azg==",
- "dependencies": {
- "@react-stately/form": "^3.0.3",
- "@react-stately/utils": "^3.10.1",
- "@react-types/checkbox": "^3.8.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.6.8",
+ "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.8.tgz",
+ "integrity": "sha512-c8TWjU67XHHBCpqj6+FXXhQUWGr2Pil1IKggX81pkedhWiJl3/7+WHJuZI0ivGnRjp3aISNOG8UNVlBEjS9E8A==",
+ "dependencies": {
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/checkbox": "^3.8.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/collections": {
- "version": "3.10.7",
- "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.7.tgz",
- "integrity": "sha512-KRo5O2MWVL8n3aiqb+XR3vP6akmHLhLWYZEmPKjIv0ghQaEebBTrN3wiEjtd6dzllv0QqcWvDLM1LntNfJ2TsA==",
+ "version": "3.10.9",
+ "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.9.tgz",
+ "integrity": "sha512-plyrng6hOQMG8LrjArMA6ts/DgWyXln3g90/hFNbqe/hdVYF53sDVsj8Jb+5LtoYTpiAlV6eOvy1XR0vPZUf8w==",
"dependencies": {
- "@react-types/shared": "^3.23.1",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/color": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.6.1.tgz",
- "integrity": "sha512-iW0nAhl3+fUBegHMw5EcAbFVDpgwHBrivfC85pVoTM3pyzp66hqNN6R6xWxW6ETyljS8UOer59+/w4GDVGdPig==",
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.7.2.tgz",
+ "integrity": "sha512-tNJ7pQjBqXtfASdLRjIYzeI8q0b3JtxqkJbusyEEdLAumpcWkbOvl3Vp9un0Bu/XXWihDa4v2dEdpKxjM+pPxg==",
"dependencies": {
"@internationalized/number": "^3.5.3",
"@internationalized/string": "^3.2.3",
- "@react-aria/i18n": "^3.11.1",
- "@react-stately/form": "^3.0.3",
- "@react-stately/numberfield": "^3.9.3",
- "@react-stately/slider": "^3.5.4",
- "@react-stately/utils": "^3.10.1",
- "@react-types/color": "3.0.0-beta.25",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/numberfield": "^3.9.6",
+ "@react-stately/slider": "^3.5.7",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/color": "3.0.0-rc.1",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/combobox": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.8.4.tgz",
- "integrity": "sha512-iLVGvKRRz0TeJXZhZyK783hveHpYA6xovOSdzSD+WGYpiPXo1QrcrNoH3AE0Z2sHtorU+8nc0j58vh5PB+m2AA==",
- "dependencies": {
- "@react-stately/collections": "^3.10.7",
- "@react-stately/form": "^3.0.3",
- "@react-stately/list": "^3.10.5",
- "@react-stately/overlays": "^3.6.7",
- "@react-stately/select": "^3.6.4",
- "@react-stately/utils": "^3.10.1",
- "@react-types/combobox": "^3.11.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.9.2.tgz",
+ "integrity": "sha512-ZsbAcD58IvxZqwYxg9d2gOf8R/k5RUB2TPUiGKD6wgWfEKH6SDzY3bgRByHGOyMCyJB62cHjih/ZShizNTguqA==",
+ "dependencies": {
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/list": "^3.10.8",
+ "@react-stately/overlays": "^3.6.10",
+ "@react-stately/select": "^3.6.7",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/combobox": "^3.12.1",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/data": {
- "version": "3.11.4",
- "resolved": "https://registry.npmjs.org/@react-stately/data/-/data-3.11.4.tgz",
- "integrity": "sha512-PbnUQxeE6AznSuEWYnRmrYQ9t5z1Asx98Jtrl96EeA6Iapt9kOjTN9ySqCxtPxMKleb1NIqG3+uHU3veIqmLsg==",
+ "version": "3.11.6",
+ "resolved": "https://registry.npmjs.org/@react-stately/data/-/data-3.11.6.tgz",
+ "integrity": "sha512-S8q1Ejuhijl8SnyVOdDNFrMrWWnLk/Oh1ZT3KHSbTdpfMRtvhi5HukoiP06jlzz75phnpSPQL40npDtUB/kk3Q==",
"dependencies": {
- "@react-types/shared": "^3.23.1",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/datepicker": {
- "version": "3.9.4",
- "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.9.4.tgz",
- "integrity": "sha512-yBdX01jn6gq4NIVvHIqdjBUPo+WN8Bujc4OnPw+ZnfA4jI0eIgq04pfZ84cp1LVXW0IB0VaCu1AlQ/kvtZjfGA==",
+ "version": "3.10.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.10.2.tgz",
+ "integrity": "sha512-pa5IZUw+49AyOnddwu4XwU2kI5eo/1thbiIVNHP8uDpbbBrBkquSk3zVFDAGX1cu/I1U2VUkt64U/dxgkwaMQw==",
"dependencies": {
- "@internationalized/date": "^3.5.4",
+ "@internationalized/date": "^3.5.5",
"@internationalized/string": "^3.2.3",
- "@react-stately/form": "^3.0.3",
- "@react-stately/overlays": "^3.6.7",
- "@react-stately/utils": "^3.10.1",
- "@react-types/datepicker": "^3.7.4",
- "@react-types/shared": "^3.23.1",
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/overlays": "^3.6.10",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/datepicker": "^3.8.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/dnd": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.3.1.tgz",
- "integrity": "sha512-I/Ci5xB8hSgAXzoWYWScfMM9UK1MX/eTlARBhiSlfudewweOtNJAI+cXJgU7uiUnGjh4B4v3qDBtlAH1dWDCsw==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.4.2.tgz",
+ "integrity": "sha512-VrHmNoNdVGrx5JHdz/zewmN+N8rlZe+vL/iAOLmvQ74RRLEz8KDFnHdlhgKg1AZqaSg3JJ18BlHEkS7oL1n+tA==",
"dependencies": {
- "@react-stately/selection": "^3.15.1",
- "@react-types/shared": "^3.23.1",
+ "@react-stately/selection": "^3.16.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/flags": {
@@ -2911,574 +2903,591 @@
}
},
"node_modules/@react-stately/form": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.0.3.tgz",
- "integrity": "sha512-92YYBvlHEWUGUpXgIaQ48J50jU9XrxfjYIN8BTvvhBHdD63oWgm8DzQnyT/NIAMzdLnhkg7vP+fjG8LjHeyIAg==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.0.5.tgz",
+ "integrity": "sha512-J3plwJ63HQz109OdmaTqTA8Qhvl3gcYYK7DtgKyNP6mc/Me2Q4tl2avkWoA+22NRuv5m+J8TpBk4AVHUEOwqeQ==",
"dependencies": {
- "@react-types/shared": "^3.23.1",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/grid": {
- "version": "3.8.7",
- "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.8.7.tgz",
- "integrity": "sha512-he3TXCLAhF5C5z1/G4ySzcwyt7PEiWcVIupxebJQqRyFrNWemSuv+7tolnStmG8maMVIyV3P/3j4eRBbdSlOIg==",
- "dependencies": {
- "@react-stately/collections": "^3.10.7",
- "@react-stately/selection": "^3.15.1",
- "@react-types/grid": "^3.2.6",
- "@react-types/shared": "^3.23.1",
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.9.2.tgz",
+ "integrity": "sha512-2gK//sqAqg2Xaq6UITTFQwFUJnBRgcW+cKBVbFt+F8d152xB6UwwTS/K79E5PUkOotwqZgTEpkrSFs/aVxCLpw==",
+ "dependencies": {
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/selection": "^3.16.2",
+ "@react-types/grid": "^3.2.8",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/@react-stately/layout": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-4.0.2.tgz",
+ "integrity": "sha512-g3IOrYQcaWxWKW44fYCOLoLMYKEmoOAcT9vQIbgK8MLTQV9Zgt9sGREwn4WJPm85N58Ij6yP72aQ7og/PSymvg==",
+ "dependencies": {
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/table": "^3.12.2",
+ "@react-stately/virtualizer": "^4.0.2",
+ "@react-types/grid": "^3.2.8",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/table": "^3.10.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/list": {
- "version": "3.10.5",
- "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.5.tgz",
- "integrity": "sha512-fV9plO+6QDHiewsYIhboxcDhF17GO95xepC5ki0bKXo44gr14g/LSo/BMmsaMnV+1BuGdBunB05bO4QOIaigXA==",
- "dependencies": {
- "@react-stately/collections": "^3.10.7",
- "@react-stately/selection": "^3.15.1",
- "@react-stately/utils": "^3.10.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.10.8",
+ "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.8.tgz",
+ "integrity": "sha512-rHCiPLXd+Ry3ztR9DkLA5FPQeH4Zd4/oJAEDWJ77W3oBBOdiMp3ZdHDLP7KBRh17XGNLO/QruYoHWAQTPiMF4g==",
+ "dependencies": {
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/selection": "^3.16.2",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/menu": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.7.1.tgz",
- "integrity": "sha512-mX1w9HHzt+xal1WIT2xGrTQsoLvDwuB2R1Er1MBABs//MsJzccycatcgV/J/28m6tO5M9iuFQQvLV+i1dCtodg==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.8.2.tgz",
+ "integrity": "sha512-lt6hIHmSixMzkKx1rKJf3lbAf01EmEvvIlENL20GLiU9cRbpPnPJ1aJMZ5Ad5ygglA7wAemAx+daPhlTQfF2rg==",
"dependencies": {
- "@react-stately/overlays": "^3.6.7",
- "@react-types/menu": "^3.9.9",
- "@react-types/shared": "^3.23.1",
+ "@react-stately/overlays": "^3.6.10",
+ "@react-types/menu": "^3.9.11",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/numberfield": {
- "version": "3.9.3",
- "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.3.tgz",
- "integrity": "sha512-UlPTLSabhLEuHtgzM0PgfhtEaHy3yttbzcRb8yHNvGo4KbCHeHpTHd3QghKfTFm024Mug7+mVlWCmMtW0f5ttg==",
+ "version": "3.9.6",
+ "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.6.tgz",
+ "integrity": "sha512-p2R9admGLI439qZzB39dyANhkruprJJtZwuoGVtxW/VD0ficw6BrPVqAaKG25iwKPkmveleh9p8o+yRqjGedcQ==",
"dependencies": {
"@internationalized/number": "^3.5.3",
- "@react-stately/form": "^3.0.3",
- "@react-stately/utils": "^3.10.1",
- "@react-types/numberfield": "^3.8.3",
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/numberfield": "^3.8.5",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/overlays": {
- "version": "3.6.7",
- "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.7.tgz",
- "integrity": "sha512-6zp8v/iNUm6YQap0loaFx6PlvN8C0DgWHNlrlzMtMmNuvjhjR0wYXVaTfNoUZBWj25tlDM81ukXOjpRXg9rLrw==",
+ "version": "3.6.10",
+ "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.10.tgz",
+ "integrity": "sha512-XxZ2qScT5JPwGk9qiVJE4dtVh3AXTcYwGRA5RsHzC26oyVVsegPqY2PmNJGblAh6Q57VyodoVUyebE0Eo5CzRw==",
"dependencies": {
- "@react-stately/utils": "^3.10.1",
- "@react-types/overlays": "^3.8.7",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/overlays": "^3.8.9",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/radio": {
- "version": "3.10.4",
- "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.4.tgz",
- "integrity": "sha512-kCIc7tAl4L7Hu4Wt9l2jaa+MzYmAJm0qmC8G8yPMbExpWbLRu6J8Un80GZu+JxvzgDlqDyrVvyv9zFifwH/NkQ==",
- "dependencies": {
- "@react-stately/form": "^3.0.3",
- "@react-stately/utils": "^3.10.1",
- "@react-types/radio": "^3.8.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.10.7",
+ "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.7.tgz",
+ "integrity": "sha512-ZwGzFR+sGd42DxRlDTp3G2vLZyhMVtgHkwv2BxazPHxPMvLO9yYl7+3PPNxAmhMB4tg2u9CrzffpGX2rmEJEXA==",
+ "dependencies": {
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/radio": "^3.8.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/searchfield": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.3.tgz",
- "integrity": "sha512-H0OvlgwPIFdc471ypw79MDjz3WXaVq9+THaY6JM4DIohEJNN5Dwei7O9g6r6m/GqPXJIn5TT3b74kJ2Osc00YQ==",
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.6.tgz",
+ "integrity": "sha512-gVzU0FeWiLYD8VOYRgWlk79Qn7b2eirqOnWhtI5VNuGN8WyNaCIuBp6SkXTW2dY8hs2Hzn8HlMbgy1MIc7130Q==",
"dependencies": {
- "@react-stately/utils": "^3.10.1",
- "@react-types/searchfield": "^3.5.5",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/searchfield": "^3.5.8",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/select": {
- "version": "3.6.4",
- "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.4.tgz",
- "integrity": "sha512-whZgF1N53D0/dS8tOFdrswB0alsk5Q5620HC3z+5f2Hpi8gwgAZ8TYa+2IcmMYRiT+bxVuvEc/NirU9yPmqGbA==",
- "dependencies": {
- "@react-stately/form": "^3.0.3",
- "@react-stately/list": "^3.10.5",
- "@react-stately/overlays": "^3.6.7",
- "@react-types/select": "^3.9.4",
- "@react-types/shared": "^3.23.1",
+ "version": "3.6.7",
+ "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.7.tgz",
+ "integrity": "sha512-hCUIddw0mPxVy1OH6jhyaDwgNea9wESjf+MYdnnTG/abRB+OZv/dWScd87OjzVsHTHWcw7CN4ZzlJoXm0FJbKQ==",
+ "dependencies": {
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/list": "^3.10.8",
+ "@react-stately/overlays": "^3.6.10",
+ "@react-types/select": "^3.9.6",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/selection": {
- "version": "3.15.1",
- "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.15.1.tgz",
- "integrity": "sha512-6TQnN9L0UY9w19B7xzb1P6mbUVBtW840Cw1SjgNXCB3NPaCf59SwqClYzoj8O2ZFzMe8F/nUJtfU1NS65/OLlw==",
+ "version": "3.16.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.16.2.tgz",
+ "integrity": "sha512-C4eSKw7BIZHJLPzwqGqCnsyFHiUIEyryVQZTJDt6d0wYBOHU6k1pW+Q4VhrZuzSv+IMiI2RkiXeJKc55f0ZXrg==",
"dependencies": {
- "@react-stately/collections": "^3.10.7",
- "@react-stately/utils": "^3.10.1",
- "@react-types/shared": "^3.23.1",
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/slider": {
- "version": "3.5.4",
- "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.4.tgz",
- "integrity": "sha512-Jsf7K17dr93lkNKL9ij8HUcoM1sPbq8TvmibD6DhrK9If2lje+OOL8y4n4qreUnfMT56HCAeS9wCO3fg3eMyrw==",
+ "version": "3.5.7",
+ "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.7.tgz",
+ "integrity": "sha512-gEIGTcpBLcXixd8LYiLc8HKrBiGQJltrrEGoOvvTP8KVItXQxmeL+JiSsh8qgOoUdRRpzmAoFNUKGEg2/gtN8A==",
"dependencies": {
- "@react-stately/utils": "^3.10.1",
- "@react-types/shared": "^3.23.1",
- "@react-types/slider": "^3.7.3",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/slider": "^3.7.5",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/table": {
- "version": "3.11.8",
- "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.11.8.tgz",
- "integrity": "sha512-EdyRW3lT1/kAVDp5FkEIi1BQ7tvmD2YgniGdLuW/l9LADo0T+oxZqruv60qpUS6sQap+59Riaxl91ClDxrJnpg==",
+ "version": "3.12.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.12.2.tgz",
+ "integrity": "sha512-dUcsrdALylhWz6exqIoqtR/dnrzjIAptMyAUPT378Y/mCYs4PxKkHSvtPEQrZhdQS1ALIIgfeg9KUVIempoXPw==",
"dependencies": {
- "@react-stately/collections": "^3.10.7",
+ "@react-stately/collections": "^3.10.9",
"@react-stately/flags": "^3.0.3",
- "@react-stately/grid": "^3.8.7",
- "@react-stately/selection": "^3.15.1",
- "@react-stately/utils": "^3.10.1",
- "@react-types/grid": "^3.2.6",
- "@react-types/shared": "^3.23.1",
- "@react-types/table": "^3.9.5",
+ "@react-stately/grid": "^3.9.2",
+ "@react-stately/selection": "^3.16.2",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/grid": "^3.2.8",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/table": "^3.10.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/tabs": {
- "version": "3.6.6",
- "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.6.tgz",
- "integrity": "sha512-sOLxorH2uqjAA+v1ppkMCc2YyjgqvSGeBDgtR/lyPSDd4CVMoTExszROX2dqG0c8il9RQvzFuufUtQWMY6PgSA==",
+ "version": "3.6.9",
+ "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.9.tgz",
+ "integrity": "sha512-YZDqZng3HrRX+uXmg6u78x73Oi24G5ICpiXVqDKKDkO333XCA5H8MWItiuPZkYB2h3SbaCaLqSobLkvCoWYpNQ==",
"dependencies": {
- "@react-stately/list": "^3.10.5",
- "@react-types/shared": "^3.23.1",
- "@react-types/tabs": "^3.3.7",
+ "@react-stately/list": "^3.10.8",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/tabs": "^3.3.9",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/toast": {
- "version": "3.0.0-beta.4",
- "resolved": "https://registry.npmjs.org/@react-stately/toast/-/toast-3.0.0-beta.4.tgz",
- "integrity": "sha512-YzEyFNAAQqZ+7pZpRiejotxDzp5CHagN21btVGGwU2jHu/oQRR+todtB3wADAp7EF5lfAlAsLABiD9ZNWQeDTw==",
+ "version": "3.0.0-beta.5",
+ "resolved": "https://registry.npmjs.org/@react-stately/toast/-/toast-3.0.0-beta.5.tgz",
+ "integrity": "sha512-MEdQwcKsexlcJ4YQZ9cN5QSIqTlGGdgC5auzSKXXoq15DHuo4mtHfLzXPgcMDYOhOdmyphMto8Vt+21UL2FOrw==",
"dependencies": {
"@swc/helpers": "^0.5.0",
"use-sync-external-store": "^1.2.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/toggle": {
- "version": "3.7.4",
- "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.4.tgz",
- "integrity": "sha512-CoYFe9WrhLkDP4HGDpJYQKwfiYCRBAeoBQHv+JWl5eyK61S8xSwoHsveYuEZ3bowx71zyCnNAqWRrmNOxJ4CKA==",
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.7.tgz",
+ "integrity": "sha512-AS+xB4+hHWa3wzYkbS6pwBkovPfIE02B9SnuYTe0stKcuejpWKo5L3QMptW0ftFYsW3ZPCXuneImfObEw2T01A==",
"dependencies": {
- "@react-stately/utils": "^3.10.1",
- "@react-types/checkbox": "^3.8.1",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/checkbox": "^3.8.3",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/tooltip": {
- "version": "3.4.9",
- "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.9.tgz",
- "integrity": "sha512-P7CDJsdoKarz32qFwf3VNS01lyC+63gXpDZG31pUu+EO5BeQd4WKN/AH1Beuswpr4GWzxzFc1aXQgERFGVzraA==",
+ "version": "3.4.12",
+ "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.12.tgz",
+ "integrity": "sha512-QKYT/cze7n9qaBsk7o5ais3jRfhYCzcVRfps+iys/W+/9FFbbhjfQG995Lwi6b+vGOHWfXxXpwmyIO2tzM1Iog==",
"dependencies": {
- "@react-stately/overlays": "^3.6.7",
- "@react-types/tooltip": "^3.4.9",
+ "@react-stately/overlays": "^3.6.10",
+ "@react-types/tooltip": "^3.4.11",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/tree": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.1.tgz",
- "integrity": "sha512-LOdkkruJWch3W89h4B/bXhfr0t0t1aRfEp+IMrrwdRAl23NaPqwl5ILHs4Xu5XDHqqhg8co73pHrJwUyiTWEjw==",
- "dependencies": {
- "@react-stately/collections": "^3.10.7",
- "@react-stately/selection": "^3.15.1",
- "@react-stately/utils": "^3.10.1",
- "@react-types/shared": "^3.23.1",
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.4.tgz",
+ "integrity": "sha512-HFNclIXJ/3QdGQWxXbj+tdlmIX/XwCfzAMB5m26xpJ6HtJhia6dtx3GLfcdyHNjmuRbAsTBsAAnnVKBmNRUdIQ==",
+ "dependencies": {
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/selection": "^3.16.2",
+ "@react-stately/utils": "^3.10.3",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/utils": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.1.tgz",
- "integrity": "sha512-VS/EHRyicef25zDZcM/ClpzYMC5i2YGN6uegOeQawmgfGjb02yaCX0F0zR69Pod9m2Hr3wunTbtpgVXvYbZItg==",
+ "version": "3.10.3",
+ "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.3.tgz",
+ "integrity": "sha512-moClv7MlVSHpbYtQIkm0Cx+on8Pgt1XqtPx6fy9rQFb2DNc9u1G3AUVnqA17buOkH1vLxAtX4MedlxMWyRCYYA==",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-stately/virtualizer": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-3.7.1.tgz",
- "integrity": "sha512-voHgE6EQ+oZaLv6u2umKxakvIKNkCQuUihqKACTjdslp7SJh4Mvs3oLBI0hf0JOh+rCcFIKDvQtFwy1fXFRYBA==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.0.2.tgz",
+ "integrity": "sha512-LiSr6E6OoL/cKVFO088zEzkNGj41g02nlOAgLluYONncNEjoYiHmb8Yw0otPgViVLKiFjO6Kk4W+dbt8EZ51Ag==",
"dependencies": {
- "@react-aria/utils": "^3.24.1",
- "@react-types/shared": "^3.23.1",
+ "@react-aria/utils": "^3.25.2",
+ "@react-types/shared": "^3.24.1",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/breadcrumbs": {
- "version": "3.7.5",
- "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.5.tgz",
- "integrity": "sha512-lV9IDYsMiu2TgdMIjEmsOE0YWwjb3jhUNK1DCZZfq6uWuiHLgyx2EncazJBUWSjHJ4ta32j7xTuXch+8Ai6u/A==",
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.7.tgz",
+ "integrity": "sha512-ZmhXwD2LLzfEA2OvOCp/QvXu8A/Edsrn5q0qUDGsmOZj9SCVeT82bIv8P+mQnATM13mi2gyoik6102Jc1OscJA==",
"dependencies": {
- "@react-types/link": "^3.5.5",
- "@react-types/shared": "^3.23.1"
+ "@react-types/link": "^3.5.7",
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/button": {
- "version": "3.9.4",
- "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.4.tgz",
- "integrity": "sha512-raeQBJUxBp0axNF74TXB8/H50GY8Q3eV6cEKMbZFP1+Dzr09Ngv0tJBeW0ewAxAguNH5DRoMUAUGIXtSXskVdA==",
+ "version": "3.9.6",
+ "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.6.tgz",
+ "integrity": "sha512-8lA+D5JLbNyQikf8M/cPP2cji91aVTcqjrGpDqI7sQnaLFikM8eFR6l1ZWGtZS5MCcbfooko77ha35SYplSQvw==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/calendar": {
- "version": "3.4.6",
- "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.6.tgz",
- "integrity": "sha512-WSntZPwtvsIYWvBQRAPvuCn55UTJBZroTvX0vQvWykJRQnPAI20G1hMQ3dNsnAL+gLZUYxBXn66vphmjUuSYew==",
+ "version": "3.4.9",
+ "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.9.tgz",
+ "integrity": "sha512-O/PS9c21HgO9qzxOyZ7/dTccxabFZdF6tj3UED4DrBw7AN3KZ7JMzwzYbwHinOcO7nUcklGgNoAIHk45UAKR9g==",
"dependencies": {
- "@internationalized/date": "^3.5.4",
- "@react-types/shared": "^3.23.1"
+ "@internationalized/date": "^3.5.5",
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/checkbox": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.1.tgz",
- "integrity": "sha512-5/oVByPw4MbR/8QSdHCaalmyWC71H/QGgd4aduTJSaNi825o+v/hsN2/CH7Fq9atkLKsC8fvKD00Bj2VGaKriQ==",
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.3.tgz",
+ "integrity": "sha512-f4c1mnLEt0iS1NMkyZXgT3q3AgcxzDk7w6MSONOKydcnh0xG5L2oefY14DhVDLkAuQS7jThlUFwiAs+MxiO3MA==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/color": {
- "version": "3.0.0-beta.25",
- "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.0.0-beta.25.tgz",
- "integrity": "sha512-D24ASvLeSWouBwOBi4ftUe4/BhrZj5AiHV7tXwrVeMGOy9Z9jyeK65Xysq+R3ecaSONLXsgai5CQMvj13cOacA==",
+ "version": "3.0.0-rc.1",
+ "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.0.0-rc.1.tgz",
+ "integrity": "sha512-aw6FzrBlZTWKrFaFskM7e3AFICe6JqH10wO0E919goa3LZDDFbyYEwRpatwjIyiZH1elEUkFPgwqpv3ZcPPn8g==",
"dependencies": {
- "@react-types/shared": "^3.23.1",
- "@react-types/slider": "^3.7.3"
+ "@react-types/shared": "^3.24.1",
+ "@react-types/slider": "^3.7.5"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/combobox": {
- "version": "3.11.1",
- "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.11.1.tgz",
- "integrity": "sha512-UNc3OHt5cUt5gCTHqhQIqhaWwKCpaNciD8R7eQazmHiA9fq8ROlV+7l3gdNgdhJbTf5Bu/V5ISnN7Y1xwL3zqQ==",
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.12.1.tgz",
+ "integrity": "sha512-bd5YwHZWtgnJx4jGbplWbYzXj7IbO5w3IY5suNR7r891rx6IktquZ8GQwyYH0pQ/x+X5LdK2xI59i6+QC2PmlA==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/datepicker": {
- "version": "3.7.4",
- "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.7.4.tgz",
- "integrity": "sha512-ZfvgscvNzBJpYyVWg3nstJtA/VlWLwErwSkd1ivZYam859N30w8yH+4qoYLa6FzWLCFlrsRHyvtxlEM7lUAt5A==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.8.2.tgz",
+ "integrity": "sha512-Ih4F0bNVGrEuwCD8XmmBAspuuOBsj/Svn/pDFtC2RyAZjXfWh+sI+n4XLz/sYKjvARh5TUI8GNy9smYS4vYXug==",
"dependencies": {
- "@internationalized/date": "^3.5.4",
- "@react-types/calendar": "^3.4.6",
- "@react-types/overlays": "^3.8.7",
- "@react-types/shared": "^3.23.1"
+ "@internationalized/date": "^3.5.5",
+ "@react-types/calendar": "^3.4.9",
+ "@react-types/overlays": "^3.8.9",
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/dialog": {
- "version": "3.5.10",
- "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.10.tgz",
- "integrity": "sha512-S9ga+edOLNLZw7/zVOnZdT5T40etpzUYBXEKdFPbxyPYnERvRxJAsC1/ASuBU9fQAXMRgLZzADWV+wJoGS/X9g==",
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.12.tgz",
+ "integrity": "sha512-JmpQbSpXltqEyYfEwoqDolABIiojeExkqolHNdQlayIsfFuSxZxNwXZPOpz58Ri/iwv21JP7K3QF0Gb2Ohxl9w==",
"dependencies": {
- "@react-types/overlays": "^3.8.7",
- "@react-types/shared": "^3.23.1"
+ "@react-types/overlays": "^3.8.9",
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/form": {
- "version": "3.7.4",
- "resolved": "https://registry.npmjs.org/@react-types/form/-/form-3.7.4.tgz",
- "integrity": "sha512-HZojAWrb6feYnhDEOy3vBamDVAHDl0l2JQZ7aIDLHmeTAGQC3JNZcm2fLTxqLye46zz8w8l8OHgI+NdD4PHdOw==",
+ "version": "3.7.6",
+ "resolved": "https://registry.npmjs.org/@react-types/form/-/form-3.7.6.tgz",
+ "integrity": "sha512-lhS2y1bVtRnyYjkM+ylJUp2g663ZNbeZxu2o+mFfD5c2wYmVLA58IWR90c7DL8IVUitoANnZ1JPhhXvutiFpQQ==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/grid": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.6.tgz",
- "integrity": "sha512-XfHenL2jEBUYrhKiPdeM24mbLRXUn79wVzzMhrNYh24nBwhsPPpxF+gjFddT3Cy8dt6tRInfT6pMEu9nsXwaHw==",
+ "version": "3.2.8",
+ "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.8.tgz",
+ "integrity": "sha512-6PJrpukwMqlv3IhJSDkJuVbhHM8Oe6hd2supWqd9adMXrlSP7QHt9a8SgFcFblCCTx8JzUaA0PvY5sTudcEtOQ==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/link": {
- "version": "3.5.5",
- "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.5.tgz",
- "integrity": "sha512-G6P5WagHDR87npN7sEuC5IIgL1GsoY4WFWKO4734i2CXRYx24G9P0Su3AX4GA3qpspz8sK1AWkaCzBMmvnunfw==",
+ "version": "3.5.7",
+ "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.7.tgz",
+ "integrity": "sha512-2WyaVmm1qr9UrSG3Dq6iz+2ziuVp+DH8CsYZ9CA6aNNb6U18Hxju3LTPb4a5gM0eC7W0mQGNBmrgGlAdDZEJOw==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/listbox": {
- "version": "3.4.9",
- "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.4.9.tgz",
- "integrity": "sha512-S5G+WmNKUIOPZxZ4svWwWQupP3C6LmVfnf8QQmPDvwYXGzVc0WovkqUWyhhjJirFDswTXRCO9p0yaTHHIlkdwQ==",
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.5.1.tgz",
+ "integrity": "sha512-n5bOgD9lgfK1qaLtag9WPnu151SwXBCNn/OgGY/Br9mWRl+nPUEYtFcPX+2VCld7uThf54kwrTmzlFnaraIlcw==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/menu": {
- "version": "3.9.9",
- "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.9.tgz",
- "integrity": "sha512-FamUaPVs1Fxr4KOMI0YcR2rYZHoN7ypGtgiEiJ11v/tEPjPPGgeKDxii0McCrdOkjheatLN1yd2jmMwYj6hTDg==",
+ "version": "3.9.11",
+ "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.11.tgz",
+ "integrity": "sha512-IguQVF70d7aHXgWB1Rd2a/PiIuLZ2Nt7lyayJshLcy/NLOYmgpTmTyn2WCtlA5lTfQwmQrNFf4EvnWkeljJXdA==",
"dependencies": {
- "@react-types/overlays": "^3.8.7",
- "@react-types/shared": "^3.23.1"
+ "@react-types/overlays": "^3.8.9",
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/meter": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.1.tgz",
- "integrity": "sha512-AIJV4NDFAqKH94s02c5Da4TH2qgJjfrw978zuFM0KUBFD85WRPKh7MvgWpomvUgmzqE6lMCzIdi1KPKqrRabdw==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.3.tgz",
+ "integrity": "sha512-Y2fX5CTAPGRKxVSeepbeyN6/K+wlF9pMRcNxTSU2qDwdoFqNCtTWMcWuCsU/Y2L/zU0jFWu4x0Vo7WkrcsgcMA==",
"dependencies": {
- "@react-types/progress": "^3.5.4"
+ "@react-types/progress": "^3.5.6"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/numberfield": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.3.tgz",
- "integrity": "sha512-z5fGfVj3oh5bmkw9zDvClA1nDBSFL9affOuyk2qZ/M2SRUmykDAPCksbfcMndft0XULWKbF4s2CYbVI+E/yrUA==",
+ "version": "3.8.5",
+ "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.5.tgz",
+ "integrity": "sha512-LVWggkxwd1nyVZomXBPfQA1E4I4/i4PBifjcDs2AfcV7q5RE9D+DVIDXsYucVOBxPlDOxiAq/T9ypobspWSwHw==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/overlays": {
- "version": "3.8.7",
- "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.7.tgz",
- "integrity": "sha512-zCOYvI4at2DkhVpviIClJ7bRrLXYhSg3Z3v9xymuPH3mkiuuP/dm8mUCtkyY4UhVeUTHmrQh1bzaOP00A+SSQA==",
+ "version": "3.8.9",
+ "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.9.tgz",
+ "integrity": "sha512-9ni9upQgXPnR+K9cWmbYWvm3ll9gH8P/XsEZprqIV5zNLMF334jADK48h4jafb1X9RFnj0WbHo6BqcSObzjTig==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/progress": {
- "version": "3.5.4",
- "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.4.tgz",
- "integrity": "sha512-JNc246sTjasPyx5Dp7/s0rp3Bz4qlu4LrZTulZlxWyb53WgBNL7axc26CCi+I20rWL9+c7JjhrRxnLl/1cLN5g==",
+ "version": "3.5.6",
+ "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.6.tgz",
+ "integrity": "sha512-Nh43sjQ5adyN1bTHBPRaIPhXUdBqP0miYeJpeMY3V/KUl4qmouJLwDnccwFG4xLm6gBfYe22lgbbV7nAfNnuTQ==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/radio": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.1.tgz",
- "integrity": "sha512-bK0gio/qj1+0Ldu/3k/s9BaOZvnnRgvFtL3u5ky479+aLG5qf1CmYed3SKz8ErZ70JkpuCSrSwSCFf0t1IHovw==",
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.3.tgz",
+ "integrity": "sha512-fUVJt4Bb6jOReFqnhHVNxWXH7t6c60uSFfoPKuXt/xI9LL1i2jhpur0ggpTfIn3qLIAmNBU6bKBCWAdr4KjeVQ==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/searchfield": {
- "version": "3.5.5",
- "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.5.tgz",
- "integrity": "sha512-T/NHg12+w23TxlXMdetogLDUldk1z5dDavzbnjKrLkajLb221bp8brlR/+O6C1CtFpuJGALqYHgTasU1qkQFSA==",
+ "version": "3.5.8",
+ "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.8.tgz",
+ "integrity": "sha512-EcdqalHNIC6BJoRfmqUhAvXRd3aHkWlV1cFCz57JJKgUEFYyXPNrXd1b73TKLzTXEk+X/D6LKV15ILYpEaxu8w==",
"dependencies": {
- "@react-types/shared": "^3.23.1",
- "@react-types/textfield": "^3.9.3"
+ "@react-types/shared": "^3.24.1",
+ "@react-types/textfield": "^3.9.6"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/select": {
- "version": "3.9.4",
- "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.4.tgz",
- "integrity": "sha512-xI7dnOW2st91fPPcv6hdtrTdcfetYiqZuuVPZ5TRobY7Q10/Zqqe/KqtOw1zFKUj9xqNJe4Ov3xP5GSdcO60Eg==",
+ "version": "3.9.6",
+ "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.6.tgz",
+ "integrity": "sha512-cVSFR0eJLup/ht1Uto+y8uyLmHO89J6wNh65SIHb3jeVz9oLBAedP3YNI2qB+F9qFMUcA8PBSLXIIuT6gXzLgQ==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/shared": {
- "version": "3.23.1",
- "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.23.1.tgz",
- "integrity": "sha512-5d+3HbFDxGZjhbMBeFHRQhexMFt4pUce3okyRtUVKbbedQFUrtXSBg9VszgF2RTeQDKDkMCIQDtz5ccP/Lk1gw==",
+ "version": "3.24.1",
+ "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.24.1.tgz",
+ "integrity": "sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==",
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/slider": {
- "version": "3.7.3",
- "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.3.tgz",
- "integrity": "sha512-F8qFQaD2mqug2D0XeWMmjGBikiwbdERFlhFzdvNGbypPLz3AZICBKp1ZLPWdl0DMuy03G/jy6Gl4mDobl7RT2g==",
+ "version": "3.7.5",
+ "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.5.tgz",
+ "integrity": "sha512-bRitwQRQjQoOcKEdPMljnvm474dwrmsc6pdsVQDh/qynzr+KO9IHuYc3qPW53WVE2hMQJDohlqtCAWQXWQ5Vcg==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/switch": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.3.tgz",
- "integrity": "sha512-Nb6+J5MrPaFa8ZNFKGMzAsen/NNzl5UG/BbC65SLGPy7O0VDa/sUpn7dcu8V2xRpRwwIN/Oso4v63bt2sgdkgA==",
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.5.tgz",
+ "integrity": "sha512-SZx1Bd+COhAOs/RTifbZG+uq/llwba7VAKx7XBeX4LeIz1dtguy5bigOBgFTMQi4qsIVCpybSWEEl+daj4XFPw==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/table": {
- "version": "3.9.5",
- "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.9.5.tgz",
- "integrity": "sha512-fgM2j9F/UR4Anmd28CueghCgBwOZoCVyN8fjaIFPd2MN4gCwUUfANwxLav65gZk4BpwUXGoQdsW+X50L3555mg==",
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.10.1.tgz",
+ "integrity": "sha512-xsNh0Gm4GtNeSknZqkMsfGvc94fycmfhspGO+FzQKim2hB5k4yILwd+lHYQ2UKW6New9GVH/zN2Pd3v67IeZ2g==",
"dependencies": {
- "@react-types/grid": "^3.2.6",
- "@react-types/shared": "^3.23.1"
+ "@react-types/grid": "^3.2.8",
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/tabs": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.7.tgz",
- "integrity": "sha512-ZdLe5xOcFX6+/ni45Dl2jO0jFATpTnoSqj6kLIS/BYv8oh0n817OjJkLf+DS3CLfNjApJWrHqAk34xNh6nRnEg==",
+ "version": "3.3.9",
+ "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.9.tgz",
+ "integrity": "sha512-3Q9kRVvg/qDyeJR/W1+C2z2OyvDWQrSLvOCvAezX5UKzww4rBEAA8OqBlyDwn7q3fiwrh/m64l6p+dbln+RdxQ==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/textfield": {
- "version": "3.9.3",
- "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.3.tgz",
- "integrity": "sha512-DoAY6cYOL0pJhgNGI1Rosni7g72GAt4OVr2ltEx2S9ARmFZ0DBvdhA9lL2nywcnKMf27PEJcKMXzXc10qaHsJw==",
+ "version": "3.9.6",
+ "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.6.tgz",
+ "integrity": "sha512-0uPqjJh4lYp1aL1HL9IlV8Cgp8eT0PcsNfdoCktfkLytvvBPmox2Pfm57W/d0xTtzZu2CjxhYNTob+JtGAOeXA==",
"dependencies": {
- "@react-types/shared": "^3.23.1"
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@react-types/tooltip": {
- "version": "3.4.9",
- "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.9.tgz",
- "integrity": "sha512-wZ+uF1+Zc43qG+cOJzioBmLUNjRa7ApdcT0LI1VvaYvH5GdfjzUJOorLX9V/vAci0XMJ50UZ+qsh79aUlw2yqg==",
+ "version": "3.4.11",
+ "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.11.tgz",
+ "integrity": "sha512-WPikHQxeT5Lb09yJEaW6Ja3ecE0g1YM6ukWYS2v/iZLUPn5YlYrGytspuCYQNSh/u7suCz4zRLEHYCl7OCigjw==",
"dependencies": {
- "@react-types/overlays": "^3.8.7",
- "@react-types/shared": "^3.23.1"
+ "@react-types/overlays": "^3.8.9",
+ "@react-types/shared": "^3.24.1"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@remix-run/router": {
@@ -3512,9 +3521,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
- "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz",
+ "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==",
"cpu": [
"arm"
],
@@ -3525,9 +3534,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
- "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz",
+ "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==",
"cpu": [
"arm64"
],
@@ -3538,9 +3547,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
- "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz",
+ "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==",
"cpu": [
"arm64"
],
@@ -3551,9 +3560,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
- "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz",
+ "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==",
"cpu": [
"x64"
],
@@ -3564,9 +3573,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
- "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz",
+ "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==",
"cpu": [
"arm"
],
@@ -3577,9 +3586,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
- "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz",
+ "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==",
"cpu": [
"arm"
],
@@ -3590,9 +3599,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
- "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz",
+ "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==",
"cpu": [
"arm64"
],
@@ -3603,9 +3612,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
- "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz",
+ "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==",
"cpu": [
"arm64"
],
@@ -3616,9 +3625,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
- "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz",
+ "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==",
"cpu": [
"ppc64"
],
@@ -3629,9 +3638,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
- "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz",
+ "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==",
"cpu": [
"riscv64"
],
@@ -3642,9 +3651,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
- "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz",
+ "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==",
"cpu": [
"s390x"
],
@@ -3655,9 +3664,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
- "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz",
+ "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==",
"cpu": [
"x64"
],
@@ -3668,9 +3677,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
- "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz",
+ "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==",
"cpu": [
"x64"
],
@@ -3681,9 +3690,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
- "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz",
+ "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==",
"cpu": [
"arm64"
],
@@ -3694,9 +3703,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
- "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz",
+ "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==",
"cpu": [
"ia32"
],
@@ -3707,9 +3716,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
- "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz",
+ "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==",
"cpu": [
"x64"
],
@@ -3933,9 +3942,9 @@
}
},
"node_modules/@swc/helpers": {
- "version": "0.5.11",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz",
- "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==",
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz",
+ "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==",
"dependencies": {
"tslib": "^2.4.0"
}
@@ -3995,6 +4004,12 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/lodash": {
+ "version": "4.17.7",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz",
+ "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==",
+ "dev": true
+ },
"node_modules/@types/prop-types": {
"version": "15.7.12",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
@@ -4020,6 +4035,15 @@
"@types/react": "*"
}
},
+ "node_modules/@types/react-window": {
+ "version": "1.8.8",
+ "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
+ "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/trusted-types": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
@@ -4217,19 +4241,20 @@
"dev": true
},
"node_modules/@vanilla-extract/css": {
- "version": "1.15.3",
- "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.15.3.tgz",
- "integrity": "sha512-mxoskDAxdQAspbkmQRxBvolUi1u1jnyy9WZGm+GeH8V2wwhEvndzl1QoK7w8JfA0WFevTxbev5d+i+xACZlPhA==",
+ "version": "1.15.5",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.15.5.tgz",
+ "integrity": "sha512-N1nQebRWnXvlcmu9fXKVUs145EVwmWtMD95bpiEKtvehHDpUhmO1l2bauS7FGYKbi3dU1IurJbGpQhBclTr1ng==",
"peer": true,
"dependencies": {
"@emotion/hash": "^0.9.0",
- "@vanilla-extract/private": "^1.0.5",
+ "@vanilla-extract/private": "^1.0.6",
"css-what": "^6.1.0",
"cssesc": "^3.0.0",
"csstype": "^3.0.7",
"dedent": "^1.5.3",
"deep-object-diff": "^1.1.9",
"deepmerge": "^4.2.2",
+ "lru-cache": "^10.4.3",
"media-query-parser": "^2.0.2",
"modern-ahocorasick": "^1.0.0",
"picocolors": "^1.0.0"
@@ -4244,14 +4269,14 @@
}
},
"node_modules/@vanilla-extract/private": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@vanilla-extract/private/-/private-1.0.5.tgz",
- "integrity": "sha512-6YXeOEKYTA3UV+RC8DeAjFk+/okoNz/h88R+McnzA2zpaVqTR/Ep+vszkWYlGBcMNO7vEkqbq5nT/JMMvhi+tw=="
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/private/-/private-1.0.6.tgz",
+ "integrity": "sha512-ytsG/JLweEjw7DBuZ/0JCN4WAQgM9erfSTdS1NQY778hFQSZ6cfCDEZZ0sgVm4k54uNz6ImKB33AYvSR//fjxw=="
},
"node_modules/@vanilla-extract/recipes": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/@vanilla-extract/recipes/-/recipes-0.5.3.tgz",
- "integrity": "sha512-SPREq1NmaoKuvJeOV0pppOkwy3pWZUoDufsyQ6iHrbkHhAU7XQqG9o0iZSmg5JoVgDLIiOr9djQb0x9wuxig7A==",
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/recipes/-/recipes-0.5.5.tgz",
+ "integrity": "sha512-VadU7+IFUwLNLMgks29AHav/K5h7DOEfTU91RItn5vwdPfzduodNg317YbgWCcpm7FSXkuR3B3X8ZOi95UOozA==",
"peerDependencies": {
"@vanilla-extract/css": "^1.0.0"
}
@@ -4276,9 +4301,9 @@
}
},
"node_modules/acorn": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
- "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -4411,9 +4436,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.23.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
- "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
+ "version": "4.23.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
+ "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
"dev": true,
"funding": [
{
@@ -4430,10 +4455,10 @@
}
],
"dependencies": {
- "caniuse-lite": "^1.0.30001629",
- "electron-to-chromium": "^1.4.796",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.16"
+ "caniuse-lite": "^1.0.30001646",
+ "electron-to-chromium": "^1.5.4",
+ "node-releases": "^2.0.18",
+ "update-browserslist-db": "^1.1.0"
},
"bin": {
"browserslist": "cli.js"
@@ -4464,9 +4489,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001637",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001637.tgz",
- "integrity": "sha512-1x0qRI1mD1o9e+7mBI7XtzFAP4XszbHaVWsMiGbSPLYekKTJF7K+FNk6AsXH4sUpc+qrsI3pVgf1Jdl/uGkuSQ==",
+ "version": "1.0.30001655",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz",
+ "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==",
"dev": true,
"funding": [
{
@@ -4670,9 +4695,9 @@
}
},
"node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dependencies": {
"ms": "2.1.2"
},
@@ -4758,9 +4783,9 @@
}
},
"node_modules/dompurify": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.5.tgz",
- "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA=="
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz",
+ "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ=="
},
"node_modules/dot-case": {
"version": "3.0.4",
@@ -4773,9 +4798,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.812",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz",
- "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==",
+ "version": "1.5.13",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz",
+ "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==",
"dev": true
},
"node_modules/entities": {
@@ -4837,9 +4862,9 @@
}
},
"node_modules/escalade": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
- "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
"engines": {
"node": ">=6"
@@ -5095,9 +5120,9 @@
}
},
"node_modules/esquery": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
- "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
"dependencies": {
"estraverse": "^5.1.0"
@@ -5271,9 +5296,9 @@
}
},
"node_modules/framer-motion": {
- "version": "11.2.4",
- "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.2.4.tgz",
- "integrity": "sha512-D+EXd0lspaZijv3BJhAcSsyGz+gnvoEdnf+QWkPZdhoFzbeX/2skrH9XSVFb0osgUnCajW8x1frjhLuKwa/Reg==",
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.0.tgz",
+ "integrity": "sha512-hjYjMUQaWuqilwRr5kC0CunHZFVMtKWHy/IdL/LPRBD0C491DKTvYwQRJ5qRXEAOT+Rth7Vi4XBe4TA4bFOn3A==",
"dependencies": {
"tslib": "^2.4.0"
},
@@ -5314,6 +5339,11 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+ "node_modules/fuzzysort": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-3.0.2.tgz",
+ "integrity": "sha512-ZyahVgxvckB1Qosn7YGWLDJJp2XlyaQ2WmZeI+d0AzW0AMqVYnz5N89G6KAKa6m/LOtv+kzJn4lhDF/yVg11Cg=="
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -5446,9 +5476,9 @@
}
},
"node_modules/https-proxy-agent": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz",
- "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==",
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
+ "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
"dependencies": {
"agent-base": "^7.0.2",
"debug": "4"
@@ -5469,9 +5499,9 @@
}
},
"node_modules/ignore": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
- "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -5587,13 +5617,13 @@
"dev": true
},
"node_modules/isomorphic-dompurify": {
- "version": "2.12.0",
- "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.12.0.tgz",
- "integrity": "sha512-jJm6VgJ9toBLqNUHuLudn+2Q3NBBaoPbsh5SzzO2dp9Zq9+p6fEg4Ffuq9RZsofb8OnqE6FJVVq3MRDLlmBHpA==",
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.15.0.tgz",
+ "integrity": "sha512-RDHlyeVmwEDAPZuX1VaaBzSn9RrsfvswxH7faEQK9cTHC1dXeNuK6ElUeSr7locFyeLguut8ASfhQWxHB4Ttug==",
"dependencies": {
"@types/dompurify": "^3.0.5",
- "dompurify": "^3.1.5",
- "jsdom": "^24.1.0"
+ "dompurify": "^3.1.6",
+ "jsdom": "^25.0.0"
},
"engines": {
"node": ">=18"
@@ -5617,9 +5647,9 @@
}
},
"node_modules/jsdom": {
- "version": "24.1.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz",
- "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==",
+ "version": "25.0.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz",
+ "integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==",
"dependencies": {
"cssstyle": "^4.0.1",
"data-urls": "^5.0.0",
@@ -5627,11 +5657,11 @@
"form-data": "^4.0.0",
"html-encoding-sniffer": "^4.0.0",
"http-proxy-agent": "^7.0.2",
- "https-proxy-agent": "^7.0.4",
+ "https-proxy-agent": "^7.0.5",
"is-potential-custom-element-name": "^1.0.1",
- "nwsapi": "^2.2.10",
+ "nwsapi": "^2.2.12",
"parse5": "^7.1.2",
- "rrweb-cssom": "^0.7.0",
+ "rrweb-cssom": "^0.7.1",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^4.1.4",
@@ -5640,7 +5670,7 @@
"whatwg-encoding": "^3.1.1",
"whatwg-mimetype": "^4.0.0",
"whatwg-url": "^14.0.0",
- "ws": "^8.17.0",
+ "ws": "^8.18.0",
"xml-name-validator": "^5.0.0"
},
"engines": {
@@ -5781,6 +5811,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -5808,18 +5843,15 @@
}
},
"node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "dependencies": {
- "yallist": "^3.0.2"
- }
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "peer": true
},
"node_modules/marked": {
- "version": "13.0.1",
- "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.1.tgz",
- "integrity": "sha512-7kBohS6GrZKvCsNXZyVVXSW7/hGBHe49ng99YPkDCckSUrrG7MSFLCexsRxptzOmyW2eT5dySh4Md1V6my52fA==",
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-14.1.0.tgz",
+ "integrity": "sha512-P93GikH/Pde0hM5TAXEd8I4JAYi8IB03n8qzW8Bh1BIEFpEyBoYxi/XWZA53LSpTeLBiMQOoSMj0u5E/tiVYTA==",
"bin": {
"marked": "bin/marked.js"
},
@@ -5836,6 +5868,11 @@
"@babel/runtime": "^7.12.5"
}
},
+ "node_modules/memoize-one": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
+ "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -5846,9 +5883,9 @@
}
},
"node_modules/micromatch": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
- "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"dependencies": {
"braces": "^3.0.3",
@@ -5938,15 +5975,15 @@
}
},
"node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
+ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
"dev": true
},
"node_modules/nwsapi": {
- "version": "2.2.10",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz",
- "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ=="
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz",
+ "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w=="
},
"node_modules/once": {
"version": "1.4.0",
@@ -6082,9 +6119,9 @@
}
},
"node_modules/picocolors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
- "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+ "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -6099,9 +6136,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.38",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
- "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "version": "8.4.44",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.44.tgz",
+ "integrity": "sha512-Aweb9unOEpQ3ezu4Q00DPvvM2ZTUitJdNKeP/+uQgr1IBIqu574IaZoURId7BKtWMREwzKa9OgzPzezWGPWFQw==",
"dev": true,
"funding": [
{
@@ -6119,7 +6156,7 @@
],
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
+ "picocolors": "^1.0.1",
"source-map-js": "^1.2.0"
},
"engines": {
@@ -6209,85 +6246,90 @@
}
},
"node_modules/react-aria": {
- "version": "3.33.1",
- "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.33.1.tgz",
- "integrity": "sha512-hFC3K/UA+90Krlx2IgRTgzFbC6FSPi4pUwHT+STperPLK+cTEHkI+3Lu0YYwQSBatkgxnIv9+GtFuVbps2kROw==",
+ "version": "3.34.3",
+ "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.34.3.tgz",
+ "integrity": "sha512-wSprEI5EojDFCm357MxnKAxJZN68OYIt6UH6N0KCo6MEUAVZMbhMSmGYjw/kLK4rI7KrbJDqGqUMQkwc93W9Ng==",
"dependencies": {
"@internationalized/string": "^3.2.3",
- "@react-aria/breadcrumbs": "^3.5.13",
- "@react-aria/button": "^3.9.5",
- "@react-aria/calendar": "^3.5.8",
- "@react-aria/checkbox": "^3.14.3",
- "@react-aria/combobox": "^3.9.1",
- "@react-aria/datepicker": "^3.10.1",
- "@react-aria/dialog": "^3.5.14",
- "@react-aria/dnd": "^3.6.1",
- "@react-aria/focus": "^3.17.1",
- "@react-aria/gridlist": "^3.8.1",
- "@react-aria/i18n": "^3.11.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/label": "^3.7.8",
- "@react-aria/link": "^3.7.1",
- "@react-aria/listbox": "^3.12.1",
- "@react-aria/menu": "^3.14.1",
- "@react-aria/meter": "^3.4.13",
- "@react-aria/numberfield": "^3.11.3",
- "@react-aria/overlays": "^3.22.1",
- "@react-aria/progress": "^3.4.13",
- "@react-aria/radio": "^3.10.4",
- "@react-aria/searchfield": "^3.7.5",
- "@react-aria/select": "^3.14.5",
- "@react-aria/selection": "^3.18.1",
- "@react-aria/separator": "^3.3.13",
- "@react-aria/slider": "^3.7.8",
- "@react-aria/ssr": "^3.9.4",
- "@react-aria/switch": "^3.6.4",
- "@react-aria/table": "^3.14.1",
- "@react-aria/tabs": "^3.9.1",
- "@react-aria/tag": "^3.4.1",
- "@react-aria/textfield": "^3.14.5",
- "@react-aria/tooltip": "^3.7.4",
- "@react-aria/utils": "^3.24.1",
- "@react-aria/visually-hidden": "^3.8.12",
- "@react-types/shared": "^3.23.1"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "@react-aria/breadcrumbs": "^3.5.16",
+ "@react-aria/button": "^3.9.8",
+ "@react-aria/calendar": "^3.5.11",
+ "@react-aria/checkbox": "^3.14.6",
+ "@react-aria/combobox": "^3.10.3",
+ "@react-aria/datepicker": "^3.11.2",
+ "@react-aria/dialog": "^3.5.17",
+ "@react-aria/dnd": "^3.7.2",
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/gridlist": "^3.9.3",
+ "@react-aria/i18n": "^3.12.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/label": "^3.7.11",
+ "@react-aria/link": "^3.7.4",
+ "@react-aria/listbox": "^3.13.3",
+ "@react-aria/menu": "^3.15.3",
+ "@react-aria/meter": "^3.4.16",
+ "@react-aria/numberfield": "^3.11.6",
+ "@react-aria/overlays": "^3.23.2",
+ "@react-aria/progress": "^3.4.16",
+ "@react-aria/radio": "^3.10.7",
+ "@react-aria/searchfield": "^3.7.8",
+ "@react-aria/select": "^3.14.9",
+ "@react-aria/selection": "^3.19.3",
+ "@react-aria/separator": "^3.4.2",
+ "@react-aria/slider": "^3.7.11",
+ "@react-aria/ssr": "^3.9.5",
+ "@react-aria/switch": "^3.6.7",
+ "@react-aria/table": "^3.15.3",
+ "@react-aria/tabs": "^3.9.5",
+ "@react-aria/tag": "^3.4.5",
+ "@react-aria/textfield": "^3.14.8",
+ "@react-aria/tooltip": "^3.7.7",
+ "@react-aria/utils": "^3.25.2",
+ "@react-aria/visually-hidden": "^3.8.15",
+ "@react-types/shared": "^3.24.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-aria-components": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.2.1.tgz",
- "integrity": "sha512-iGIdDjbTyLLn0/tGUyBQxxu+E1bw4/H4AU89d0cRcu8yIdw6MXG29YElmRHn0ugiyrERrk/YQALihstnns5kRQ==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.3.3.tgz",
+ "integrity": "sha512-wNjcoyIFTL14Z07OJ1I5m37CYB+1oH2DW8PIgZQjGt9lLcYKKEBLSgsenHVKu1F1L9tqlpXgYk5TeXCzU/xUKw==",
"dependencies": {
- "@internationalized/date": "^3.5.4",
+ "@internationalized/date": "^3.5.5",
"@internationalized/string": "^3.2.3",
- "@react-aria/color": "3.0.0-beta.33",
- "@react-aria/focus": "^3.17.1",
- "@react-aria/interactions": "^3.21.3",
- "@react-aria/menu": "^3.14.1",
- "@react-aria/toolbar": "3.0.0-beta.5",
- "@react-aria/tree": "3.0.0-alpha.1",
- "@react-aria/utils": "^3.24.1",
- "@react-stately/color": "^3.6.1",
- "@react-stately/menu": "^3.7.1",
- "@react-stately/table": "^3.11.8",
- "@react-stately/utils": "^3.10.1",
- "@react-types/color": "3.0.0-beta.25",
- "@react-types/form": "^3.7.4",
- "@react-types/grid": "^3.2.6",
- "@react-types/shared": "^3.23.1",
- "@react-types/table": "^3.9.5",
+ "@react-aria/collections": "3.0.0-alpha.4",
+ "@react-aria/color": "3.0.0-rc.2",
+ "@react-aria/dnd": "^3.7.2",
+ "@react-aria/focus": "^3.18.2",
+ "@react-aria/interactions": "^3.22.2",
+ "@react-aria/menu": "^3.15.3",
+ "@react-aria/toolbar": "3.0.0-beta.8",
+ "@react-aria/tree": "3.0.0-alpha.5",
+ "@react-aria/utils": "^3.25.2",
+ "@react-aria/virtualizer": "^4.0.2",
+ "@react-stately/color": "^3.7.2",
+ "@react-stately/layout": "^4.0.2",
+ "@react-stately/menu": "^3.8.2",
+ "@react-stately/table": "^3.12.2",
+ "@react-stately/utils": "^3.10.3",
+ "@react-stately/virtualizer": "^4.0.2",
+ "@react-types/color": "3.0.0-rc.1",
+ "@react-types/form": "^3.7.6",
+ "@react-types/grid": "^3.2.8",
+ "@react-types/shared": "^3.24.1",
+ "@react-types/table": "^3.10.1",
"@swc/helpers": "^0.5.0",
"client-only": "^0.0.1",
- "react-aria": "^3.33.1",
- "react-stately": "^3.31.1",
+ "react-aria": "^3.34.3",
+ "react-stately": "^3.32.2",
"use-sync-external-store": "^1.2.0"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-dom": {
@@ -6342,36 +6384,36 @@
}
},
"node_modules/react-stately": {
- "version": "3.31.1",
- "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.31.1.tgz",
- "integrity": "sha512-wuq673NHkYSdoceGryjtMJJvB9iQgyDkQDsnTN0t2v91pXjGDsN/EcOvnUrxXSBtY9eLdIw74R54z9GX5cJNEg==",
- "dependencies": {
- "@react-stately/calendar": "^3.5.1",
- "@react-stately/checkbox": "^3.6.5",
- "@react-stately/collections": "^3.10.7",
- "@react-stately/combobox": "^3.8.4",
- "@react-stately/data": "^3.11.4",
- "@react-stately/datepicker": "^3.9.4",
- "@react-stately/dnd": "^3.3.1",
- "@react-stately/form": "^3.0.3",
- "@react-stately/list": "^3.10.5",
- "@react-stately/menu": "^3.7.1",
- "@react-stately/numberfield": "^3.9.3",
- "@react-stately/overlays": "^3.6.7",
- "@react-stately/radio": "^3.10.4",
- "@react-stately/searchfield": "^3.5.3",
- "@react-stately/select": "^3.6.4",
- "@react-stately/selection": "^3.15.1",
- "@react-stately/slider": "^3.5.4",
- "@react-stately/table": "^3.11.8",
- "@react-stately/tabs": "^3.6.6",
- "@react-stately/toggle": "^3.7.4",
- "@react-stately/tooltip": "^3.4.9",
- "@react-stately/tree": "^3.8.1",
- "@react-types/shared": "^3.23.1"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ "version": "3.32.2",
+ "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.32.2.tgz",
+ "integrity": "sha512-pDSrbCIJtir4HeSa//PTqLSR7Tl7pFC9usmkkBObNKktObQq3Vdgkf46cxeTD1ov7J7GDdR3meIyjXGnZoEzUg==",
+ "dependencies": {
+ "@react-stately/calendar": "^3.5.4",
+ "@react-stately/checkbox": "^3.6.8",
+ "@react-stately/collections": "^3.10.9",
+ "@react-stately/combobox": "^3.9.2",
+ "@react-stately/data": "^3.11.6",
+ "@react-stately/datepicker": "^3.10.2",
+ "@react-stately/dnd": "^3.4.2",
+ "@react-stately/form": "^3.0.5",
+ "@react-stately/list": "^3.10.8",
+ "@react-stately/menu": "^3.8.2",
+ "@react-stately/numberfield": "^3.9.6",
+ "@react-stately/overlays": "^3.6.10",
+ "@react-stately/radio": "^3.10.7",
+ "@react-stately/searchfield": "^3.5.6",
+ "@react-stately/select": "^3.6.7",
+ "@react-stately/selection": "^3.16.2",
+ "@react-stately/slider": "^3.5.7",
+ "@react-stately/table": "^3.12.2",
+ "@react-stately/tabs": "^3.6.9",
+ "@react-stately/toggle": "^3.7.7",
+ "@react-stately/tooltip": "^3.4.12",
+ "@react-stately/tree": "^3.8.4",
+ "@react-types/shared": "^3.24.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-virtual": {
@@ -6388,6 +6430,22 @@
"react": "^16.6.3 || ^17.0.0"
}
},
+ "node_modules/react-window": {
+ "version": "1.8.10",
+ "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz",
+ "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==",
+ "dependencies": {
+ "@babel/runtime": "^7.0.0",
+ "memoize-one": ">=3.1.1 <6"
+ },
+ "engines": {
+ "node": ">8.0.0"
+ },
+ "peerDependencies": {
+ "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
@@ -6434,9 +6492,9 @@
}
},
"node_modules/rollup": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
- "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz",
+ "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==",
"dev": true,
"dependencies": {
"@types/estree": "1.0.5"
@@ -6449,22 +6507,22 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.18.0",
- "@rollup/rollup-android-arm64": "4.18.0",
- "@rollup/rollup-darwin-arm64": "4.18.0",
- "@rollup/rollup-darwin-x64": "4.18.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
- "@rollup/rollup-linux-arm64-gnu": "4.18.0",
- "@rollup/rollup-linux-arm64-musl": "4.18.0",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
- "@rollup/rollup-linux-s390x-gnu": "4.18.0",
- "@rollup/rollup-linux-x64-gnu": "4.18.0",
- "@rollup/rollup-linux-x64-musl": "4.18.0",
- "@rollup/rollup-win32-arm64-msvc": "4.18.0",
- "@rollup/rollup-win32-ia32-msvc": "4.18.0",
- "@rollup/rollup-win32-x64-msvc": "4.18.0",
+ "@rollup/rollup-android-arm-eabi": "4.21.2",
+ "@rollup/rollup-android-arm64": "4.21.2",
+ "@rollup/rollup-darwin-arm64": "4.21.2",
+ "@rollup/rollup-darwin-x64": "4.21.2",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.21.2",
+ "@rollup/rollup-linux-arm-musleabihf": "4.21.2",
+ "@rollup/rollup-linux-arm64-gnu": "4.21.2",
+ "@rollup/rollup-linux-arm64-musl": "4.21.2",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2",
+ "@rollup/rollup-linux-riscv64-gnu": "4.21.2",
+ "@rollup/rollup-linux-s390x-gnu": "4.21.2",
+ "@rollup/rollup-linux-x64-gnu": "4.21.2",
+ "@rollup/rollup-linux-x64-musl": "4.21.2",
+ "@rollup/rollup-win32-arm64-msvc": "4.21.2",
+ "@rollup/rollup-win32-ia32-msvc": "4.21.2",
+ "@rollup/rollup-win32-x64-msvc": "4.21.2",
"fsevents": "~2.3.2"
}
},
@@ -6521,9 +6579,9 @@
}
},
"node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -6693,9 +6751,9 @@
}
},
"node_modules/tslib": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
- "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
+ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -6743,9 +6801,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
- "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
+ "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
"dev": true,
"funding": [
{
@@ -6972,9 +7030,9 @@
"dev": true
},
"node_modules/ws": {
- "version": "8.17.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
- "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
+ "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"engines": {
"node": ">=10.0.0"
},
diff --git a/internal/dev_server/ui/package.json b/internal/dev_server/ui/package.json
index dac36ec8..b6f415f0 100644
--- a/internal/dev_server/ui/package.json
+++ b/internal/dev_server/ui/package.json
@@ -11,17 +11,22 @@
"preview": "vite preview"
},
"dependencies": {
- "@launchpad-ui/components": "0.2.12",
+ "@launchpad-ui/components": "0.4.4",
"@launchpad-ui/core": "0.49.22",
- "@launchpad-ui/icons": "0.18.4",
- "@launchpad-ui/tokens": "0.9.12",
+ "@launchpad-ui/icons": "0.18.13",
+ "@launchpad-ui/tokens": "0.11.3",
+ "fuzzysort": "3.0.2",
"launchdarkly-js-client-sdk": "3.4.0",
+ "lodash": "4.17.21",
"react": "18.3.1",
- "react-dom": "18.3.1"
+ "react-dom": "18.3.1",
+ "react-window": "1.8.10"
},
"devDependencies": {
+ "@types/lodash": "4.17.7",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
+ "@types/react-window": "1.8.8",
"@typescript-eslint/eslint-plugin": "7.13.1",
"@typescript-eslint/parser": "7.13.1",
"@vitejs/plugin-react": "4.3.1",
diff --git a/internal/dev_server/ui/src/App.css b/internal/dev_server/ui/src/App.css
index 586121ca..3c27364b 100644
--- a/internal/dev_server/ui/src/App.css
+++ b/internal/dev_server/ui/src/App.css
@@ -3,50 +3,23 @@
@import url('../node_modules/@launchpad-ui/tokens/dist/themes.css');
@font-face {
- font-family: inter;
- font-style: normal;
- font-weight: 300 800;
- font-display: swap;
- src: url('https://fonts.gstatic.com/s/inter/v7/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7.woff2')
- format('woff2');
-}
-
-@font-face {
- font-family: 'Audimat 3000 Regulier';
- font-style: normal;
- font-weight: 400;
- font-display: swap;
- src: url('Audimat3000-Regulier.var-subset.woff2') format('woff2');
+ font-family: inter;
+ src: url('https://fonts.gstatic.com/s/inter/v7/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7.woff2')
+ format('woff2');
+ font-display: swap;
+ font-weight: 300 700;
}
html,
body,
#root {
- height: 100%;
- width: 100%;
box-sizing: border-box;
-}
-#root {
- padding: 2rem;
-}
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-family: 'Audimat 3000 Regulier', sans-serif;
-}
-
-span {
- font-family: 'Inter', sans-serif;
-}
+ font-family: var(--lp-font-family-base);
+ font-size: var(--lp-font-size-300);
+ line-height: var(--lp-line-height-300);
-.container {
- max-width: 40rem;
- margin: 0 auto;
+ background-color: var(--lp-color-bg-ui-primary);
}
.only-show-overrides-label {
@@ -76,6 +49,7 @@ ul.flags-list li .flag-value {
flex-direction: row;
align-items: center;
flex-shrink: 1;
+ padding-right: 1rem;
}
code {
diff --git a/internal/dev_server/ui/src/App.tsx b/internal/dev_server/ui/src/App.tsx
index 1657ca05..fb901a89 100644
--- a/internal/dev_server/ui/src/App.tsx
+++ b/internal/dev_server/ui/src/App.tsx
@@ -1,42 +1,90 @@
import './App.css';
-import { useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import Flags from './Flags.tsx';
import ProjectSelector from './ProjectSelector.tsx';
-import { Box, Alert, CopyToClipboard } from '@launchpad-ui/core';
+import { Box, Alert, CopyToClipboard, Inline } from '@launchpad-ui/core';
import SyncButton from './Sync.tsx';
-import { LDFlagSet } from 'launchdarkly-js-client-sdk';
-import { Heading, Text } from '@launchpad-ui/components';
+import { LDFlagSet, LDFlagValue } from 'launchdarkly-js-client-sdk';
+import {
+ Heading,
+ Text,
+ Tooltip,
+ TooltipTrigger,
+ Pressable,
+} from '@launchpad-ui/components';
+import { Icon } from '@launchpad-ui/icons';
+import { FlagVariation } from './api.ts';
+import { apiRoute, sortFlags } from './util.ts';
function App() {
const [selectedProject, setSelectedProject] = useState(null);
+ const [sourceEnvironmentKey, setSourceEnvironmentKey] = useState<
+ string | null
+ >(null);
+ const [overrides, setOverrides] = useState<
+ Record
+ >({});
+ const [availableVariations, setAvailableVariations] = useState<
+ Record
+ >({});
const [flags, setFlags] = useState(null);
const [showBanner, setShowBanner] = useState(false);
+ const fetchDevFlags = useCallback(async () => {
+ if (!selectedProject) {
+ return;
+ }
+ const res = await fetch(
+ apiRoute(
+ `/dev/projects/${selectedProject}?expand=overrides&expand=availableVariations`,
+ ),
+ );
+ const json = await res.json();
+ if (!res.ok) {
+ throw new Error(`Got ${res.status}, ${res.statusText} from flag fetch`);
+ }
+
+ const {
+ flagsState: flags,
+ overrides,
+ sourceEnvironmentKey,
+ availableVariations,
+ } = json;
+
+ setFlags(sortFlags(flags));
+ setOverrides(overrides);
+ setSourceEnvironmentKey(sourceEnvironmentKey);
+ setAvailableVariations(availableVariations);
+ }, [selectedProject, setFlags, setSourceEnvironmentKey]);
+
+ // Fetch flags / overrides on mount
+ useEffect(() => {
+ Promise.all([fetchDevFlags()]).catch(
+ console.error.bind(console, 'error when fetching flags'),
+ );
+ }, [fetchDevFlags]);
return (
-
-
+
{showBanner && (
-
+
No projects.
Add one via
@@ -63,23 +111,36 @@ function App() {
setSelectedProject={setSelectedProject}
setShowBanner={setShowBanner}
/>
+
+
+
+
+ {sourceEnvironmentKey}
+
+
+
+ Source Environment Key
+
)}
{selectedProject && (
)}
-
+
);
}
diff --git a/internal/dev_server/ui/src/Flag.tsx b/internal/dev_server/ui/src/Flag.tsx
new file mode 100644
index 00000000..51c4da00
--- /dev/null
+++ b/internal/dev_server/ui/src/Flag.tsx
@@ -0,0 +1,202 @@
+import {
+ Button,
+ ButtonGroup,
+ Dialog,
+ DialogTrigger,
+ FieldError,
+ Form,
+ IconButton,
+ Label,
+ ListBox,
+ ListBoxItem,
+ Modal,
+ ModalOverlay,
+ Popover,
+ Select,
+ SelectValue,
+ Switch,
+ Text,
+ TextArea,
+ TextField,
+ Tooltip,
+ TooltipTrigger,
+} from '@launchpad-ui/components';
+import { FormEvent, Fragment } from 'react';
+import { Icon } from '@launchpad-ui/icons';
+import { LDFlagValue } from 'launchdarkly-js-client-sdk';
+import { FlagVariation } from './api.ts';
+import { Box, Inline } from '@launchpad-ui/core';
+import { isEqual } from 'lodash';
+
+type VariationValuesProps = {
+ availableVariations: FlagVariation[];
+ currentValue: LDFlagValue;
+ flagValue: LDFlagValue;
+ flagKey: string;
+ updateOverride: (flagKey: string, overrideValue: LDFlagValue) => void;
+};
+const VariationValues = ({
+ availableVariations,
+ currentValue,
+ flagKey,
+ flagValue,
+ updateOverride,
+}: VariationValuesProps) => {
+ switch (typeof flagValue) {
+ case 'boolean':
+ return (
+ {
+ updateOverride(flagKey, newValue);
+ }}
+ />
+ );
+ default:
+ let variations = availableVariations;
+ let selectedVariationIndex = variations.findIndex((variation) =>
+ isEqual(variation.value, currentValue),
+ );
+ if (selectedVariationIndex === -1) {
+ variations = [
+ { _id: 'OVERRIDE', name: 'Local Override', value: currentValue },
+ ...variations,
+ ];
+ selectedVariationIndex = 0;
+ }
+ let onSubmit = (close: () => void) => (e: FormEvent) => {
+ // Prevent default browser page refresh.
+ e.preventDefault();
+ let data = Object.fromEntries(new FormData(e.currentTarget));
+ updateOverride(flagKey, JSON.parse(data.value as string));
+ close();
+ };
+
+ //TODO:
+ // Grow the text area when editing local override
+ return (
+
+
+
+
+
+
+ Edit the served variation value as JSON
+
+
+
+
+
+
+
+
+
+ );
+ }
+};
+
+export default VariationValues;
diff --git a/internal/dev_server/ui/src/Flags.tsx b/internal/dev_server/ui/src/Flags.tsx
index b549fadf..ff49a9b0 100644
--- a/internal/dev_server/ui/src/Flags.tsx
+++ b/internal/dev_server/ui/src/Flags.tsx
@@ -4,335 +4,328 @@ import {
Checkbox,
IconButton,
Label,
- Switch,
- Modal,
- ModalOverlay,
- DialogTrigger,
- Dialog,
- TextArea,
+ Input,
+ SearchField,
+ Group,
} from '@launchpad-ui/components';
import {
Box,
CopyToClipboard,
- InlineEdit,
- TextField,
+ Inline,
+ Pagination,
+ Stack,
} from '@launchpad-ui/core';
import Theme from '@launchpad-ui/tokens';
-import { useEffect, useRef, useState } from 'react';
+import { useState, useCallback, useMemo } from 'react';
import { Icon } from '@launchpad-ui/icons';
-import { apiRoute, sortFlags } from './util.ts';
+import { apiRoute } from './util.ts';
+import { FlagVariation } from './api.ts';
+import VariationValues from './Flag.tsx';
+import fuzzysort from 'fuzzysort';
type FlagProps = {
+ availableVariations: Record;
selectedProject: string;
flags: LDFlagSet | null;
- setFlags: (flags: LDFlagSet) => void;
+ overrides: Record;
+ setOverrides: (overrides: Record) => void;
};
-function Flags({ selectedProject, flags, setFlags }: FlagProps) {
- const [overrides, setOverrides] = useState | null>(null);
+function Flags({
+ availableVariations,
+ selectedProject,
+ flags,
+ overrides,
+ setOverrides,
+}: FlagProps) {
const [onlyShowOverrides, setOnlyShowOverrides] = useState(false);
- const overridesPresent = overrides && Object.keys(overrides).length > 0;
- const textAreaRef = useRef(null);
+ const [searchTerm, setSearchTerm] = useState('');
+ const [currentPage, setCurrentPage] = useState(0); // Change initial page to 0
+ const flagsPerPage = 20;
- const updateOverride = (flagKey: string, overrideValue: LDFlagValue) => {
- fetch(apiRoute(`/dev/projects/${selectedProject}/overrides/${flagKey}`), {
- method: 'PUT',
- body: JSON.stringify(overrideValue),
- })
- .then(async (res) => {
- if (!res.ok) {
- throw new Error(`got ${res.status} ${res.statusText}. ${await res.text()}`)
- }
+ const overridesPresent = useMemo(
+ () => overrides && Object.keys(overrides).length > 0,
+ [overrides],
+ );
- const updatedOverrides = {
- ...overrides,
- ...{
- [flagKey]: {
- value: overrideValue,
- },
- },
- };
+ const filteredFlags = useMemo(() => {
+ if (!flags) return [];
+ const flagEntries = Object.entries(flags);
+ const search = searchTerm.toLowerCase();
+ const filtered = fuzzysort
+ .go(search, flagEntries, { all: true, key: '0', threshold: 0.7 })
+ .map((result) => result.obj);
+ return filtered;
+ }, [flags, searchTerm]);
- setOverrides(updatedOverrides);
- })
- .catch( console.error.bind(console, "unable to update override"));
- };
-
- const removeOverride = (flagKey: string, updateState: boolean = true) => {
- return fetch(
- apiRoute(`/dev/projects/${selectedProject}/overrides/${flagKey}`),
- {
- method: 'DELETE',
- },
- )
- .then((res) => {
- // In the remove-all-override case, we need to fan out and make the
- // request for every override, so we don't want to be interleaving
- // local state updates. Expect the consumer to update the local state
- // when all requests are done
- if (res.ok && updateState) {
- const updatedOverrides = { ...overrides };
- delete updatedOverrides[flagKey];
+ const paginatedFlags = useMemo(() => {
+ const startIndex = currentPage * flagsPerPage; // Adjust startIndex calculation
+ const endIndex = startIndex + flagsPerPage;
+ return filteredFlags.slice(startIndex, endIndex);
+ }, [filteredFlags, currentPage]);
- setOverrides(updatedOverrides);
+ const updateOverride = useCallback(
+ (flagKey: string, overrideValue: LDFlagValue) => {
+ const updatedOverrides = {
+ ...overrides,
+ ...{
+ [flagKey]: {
+ value: overrideValue,
+ },
+ },
+ };
- if (Object.keys(updatedOverrides).length === 0)
- setOnlyShowOverrides(false);
- }
+ setOverrides(updatedOverrides);
+ fetch(apiRoute(`/dev/projects/${selectedProject}/overrides/${flagKey}`), {
+ method: 'PUT',
+ body: JSON.stringify(overrideValue),
})
- .catch( console.error.bind("unable to remove override") );
- };
+ .then(async (res) => {
+ if (!res.ok) {
+ throw new Error(
+ `got ${res.status} ${res.statusText}. ${await res.text()}`,
+ );
+ }
+ })
+ .catch((err) => {
+ setOverrides(overrides);
+ console.error('unable to update override', err);
+ });
+ },
+ [overrides, selectedProject],
+ );
- const fetchFlags = async () => {
- const res = await fetch(
- apiRoute(`/dev/projects/${selectedProject}?expand=overrides`),
- );
- const json = await res.json();
- if (!res.ok) {
- throw new Error(`Got ${res.status}, ${res.statusText} from flag fetch`);
- }
+ const removeOverride = useCallback(
+ async (flagKey: string) => {
+ const updatedOverrides = { ...overrides };
+ delete updatedOverrides[flagKey];
- const { flagsState: flags, overrides } = json;
+ setOverrides(updatedOverrides);
- setFlags(sortFlags(flags));
- setOverrides(overrides);
- };
-
- // Fetch flags / overrides on mount
- useEffect(() => {
- fetchFlags().catch(
- console.error.bind(console, 'error when fetching flags'),
- );
- }, [selectedProject]);
+ try {
+ const res = await fetch(
+ apiRoute(`/dev/projects/${selectedProject}/overrides/${flagKey}`),
+ {
+ method: 'DELETE',
+ },
+ );
+ if (!res.ok) {
+ throw new Error(
+ `got ${res.status} ${res.statusText}. ${await res.text()}`,
+ );
+ }
+ } catch (err) {
+ console.error('unable to remove override', err);
+ setOverrides(overrides);
+ }
+ },
+ [overrides, selectedProject],
+ );
if (!flags) {
return null;
}
+ const totalPages = Math.ceil(filteredFlags.length / flagsPerPage);
+
+ const handlePageChange = (direction: string) => {
+ switch (direction) {
+ case 'next':
+ setCurrentPage(
+ (prevPage) => Math.min(prevPage + 1, totalPages - 1), // Adjust page increment
+ );
+ break;
+ case 'prev':
+ setCurrentPage((prevPage) => Math.max(prevPage - 1, 0)); // Adjust page decrement
+ break;
+ case 'first':
+ setCurrentPage(0); // Adjust first page
+ break;
+ case 'last':
+ setCurrentPage(totalPages - 1); // Adjust last page
+ break;
+ default:
+ console.error('invalid page change direction.');
+ }
+ };
+
return (
<>
-
-
+
+
-
+ setOverrides(updatedOverrides);
+ setOnlyShowOverrides(false);
+ }}
+ >
+
+ Remove all overrides
+
+
+
+
+
+
+
+ {
+ setSearchTerm(e.target.value);
+ setCurrentPage(0); // Reset pagination
+ }}
+ />
+
+
+
+
- {Object.entries(flags).map(
- ([flagKey, { value: flagValue }], index) => {
- const overrideValue = overrides?.[flagKey]?.value;
- const hasOverride = overrideValue !== undefined;
- let valueNode;
-
- if (onlyShowOverrides && !hasOverride) {
- return null;
- }
-
- switch (typeof flagValue) {
- case 'boolean':
- valueNode = (
- {
- updateOverride(flagKey, newValue);
- }}
- />
- );
- break;
- case 'number':
- valueNode = (
- {
- updateOverride(flagKey, Number(e.target.value));
- }}
- />
- );
- break;
- case 'string':
- valueNode = (
- {
- updateOverride(flagKey, newValue);
- }}
- renderInput={
-
- }
- >
- {hasOverride ? overrideValue : flagValue}
-
- );
- break;
- default:
- valueNode = (
-
-
-
-
-
-
-
-
- );
- }
+ if (onlyShowOverrides && !hasOverride) {
+ return null;
+ }
- return (
- -
-
+ return (
+
-
+
+
{flagKey}
-
- {valueNode}
-
+
{hasOverride && (
- {
removeOverride(flagKey);
}}
variant="destructive"
- />
+ >
+
+
+ Remove override
+
+
)}
-
-
- );
- },
- )}
+
+
+
+
+
+
+ );
+ })}
+
+
+
handlePageChange(e as string)}
+ pageSize={flagsPerPage}
+ resourceName="flags"
+ totalCount={filteredFlags.length}
+ />
>
);
diff --git a/internal/dev_server/ui/src/Sync.tsx b/internal/dev_server/ui/src/Sync.tsx
index 3daf160d..b6b3ea0d 100644
--- a/internal/dev_server/ui/src/Sync.tsx
+++ b/internal/dev_server/ui/src/Sync.tsx
@@ -9,11 +9,17 @@ import { LDFlagSet } from 'launchdarkly-js-client-sdk';
import { useState } from 'react';
import { Icon } from '@launchpad-ui/icons';
import { Inline } from '@launchpad-ui/core';
+import { FlagVariation } from './api.ts';
const syncProject = async (selectedProject: string) => {
- const res = await fetch(apiRoute(`/dev/projects/${selectedProject}/sync`), {
- method: 'PATCH',
- });
+ const res = await fetch(
+ apiRoute(
+ `/dev/projects/${selectedProject}/sync?expand=availableVariations`,
+ ),
+ {
+ method: 'PATCH',
+ },
+ );
const json = await res.json();
if (!res.ok) {
@@ -22,19 +28,26 @@ const syncProject = async (selectedProject: string) => {
return json;
};
+type Props = {
+ selectedProject: string | null;
+ setFlags: (flags: LDFlagSet) => void;
+ setAvailableVariations: (
+ availableVariations: Record
,
+ ) => void;
+};
+
const SyncButton = ({
selectedProject,
setFlags,
-}: {
- selectedProject: string | null;
- setFlags: (flags: LDFlagSet) => void;
-}) => {
+ setAvailableVariations,
+}: Props) => {
const [isLoading, setIsLoading] = useState(false);
const handleClick = async () => {
setIsLoading(true);
try {
const result = await syncProject(selectedProject!);
+ setAvailableVariations(result.availableVariations);
setFlags(sortFlags(result.flagsState));
} catch (error) {
console.error('Sync failed:', error);
diff --git a/internal/dev_server/ui/src/api.ts b/internal/dev_server/ui/src/api.ts
new file mode 100644
index 00000000..1a0ce274
--- /dev/null
+++ b/internal/dev_server/ui/src/api.ts
@@ -0,0 +1,20 @@
+export type FlagVariation = {
+ _id: string;
+ value: object | string | number | boolean;
+ description?: string;
+ name?: string;
+};
+
+export type ApiFlag = {
+ key: string;
+ variations: FlagVariation[];
+};
+
+type Links = {
+ next?: { href: string };
+};
+
+export type FlagsApiResponse = {
+ items: ApiFlag[];
+ _links: Links;
+};
diff --git a/internal/dev_server/ui/src/main.tsx b/internal/dev_server/ui/src/main.tsx
index d719fff9..269dccc5 100644
--- a/internal/dev_server/ui/src/main.tsx
+++ b/internal/dev_server/ui/src/main.tsx
@@ -1,12 +1,36 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import { IconProvider } from './IconProvider.tsx';
-ReactDOM.createRoot(document.getElementById('root')!).render(
-
-
-
-
- ,
-);
+const Root = () => {
+ useEffect(() => {
+ const darkModeMediaQuery = window.matchMedia(
+ '(prefers-color-scheme: dark)',
+ );
+ const handleChange = (e: MediaQueryListEvent) => {
+ document.documentElement.setAttribute(
+ 'data-theme',
+ e.matches ? 'dark' : 'default',
+ );
+ };
+
+ // Idk why but typescript is not happy with the type of darkModeMediaQuery
+ handleChange(darkModeMediaQuery as unknown as MediaQueryListEvent);
+ darkModeMediaQuery.addEventListener('change', handleChange);
+
+ return () => {
+ darkModeMediaQuery.removeEventListener('change', handleChange);
+ };
+ }, []);
+
+ return (
+
+
+
+
+
+ );
+};
+
+ReactDOM.createRoot(document.getElementById('root')!).render();
diff --git a/internal/dev_server/ui/src/util.ts b/internal/dev_server/ui/src/util.ts
index 464b430a..227d8ff5 100644
--- a/internal/dev_server/ui/src/util.ts
+++ b/internal/dev_server/ui/src/util.ts
@@ -1,12 +1,13 @@
-import { LDFlagValue } from "launchdarkly-js-client-sdk";
+import { LDFlagValue } from 'launchdarkly-js-client-sdk';
const API_BASE = import.meta.env.PROD ? '' : '/api';
export const apiRoute = (pathname: string) => `${API_BASE}${pathname}`;
-export const sortFlags = (flags: Record) => Object.keys(flags)
- .sort((a, b) => a.localeCompare(b))
- .reduce>((accum, flagKey) => {
- accum[flagKey] = flags[flagKey];
+export const sortFlags = (flags: Record) =>
+ Object.keys(flags)
+ .sort((a, b) => a.localeCompare(b))
+ .reduce>((accum, flagKey) => {
+ accum[flagKey] = flags[flagKey];
- return accum;
- }, {});
+ return accum;
+ }, {});
diff --git a/internal/dev_server/ui/vite.config.ts b/internal/dev_server/ui/vite.config.ts
index 46d0d735..bd66c299 100644
--- a/internal/dev_server/ui/vite.config.ts
+++ b/internal/dev_server/ui/vite.config.ts
@@ -20,6 +20,11 @@ export default defineConfig(({ command }) => {
changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/api/, ''),
},
+ '/proxy': {
+ target: 'http://localhost:8765',
+ changeOrigin: true,
+ //rewrite: (path: string) => path.replace(/^\/api/, ''),
+ },
},
},
};
diff --git a/vendor/github.com/samber/lo/.gitignore b/vendor/github.com/samber/lo/.gitignore
new file mode 100644
index 00000000..e5ecc5c4
--- /dev/null
+++ b/vendor/github.com/samber/lo/.gitignore
@@ -0,0 +1,38 @@
+
+# Created by https://www.toptal.com/developers/gitignore/api/go
+# Edit at https://www.toptal.com/developers/gitignore?templates=go
+
+### Go ###
+# If you prefer the allow list template instead of the deny list, see community template:
+# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
+#
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+
+# Go workspace file
+go.work
+
+### Go Patch ###
+/vendor/
+/Godeps/
+
+# End of https://www.toptal.com/developers/gitignore/api/go
+
+cover.out
+cover.html
+.vscode
+
+.idea/
diff --git a/vendor/github.com/samber/lo/.travis.yml b/vendor/github.com/samber/lo/.travis.yml
new file mode 100644
index 00000000..f0de7f51
--- /dev/null
+++ b/vendor/github.com/samber/lo/.travis.yml
@@ -0,0 +1,7 @@
+language: go
+before_install:
+ - go mod download
+ - make tools
+go:
+ - "1.18"
+script: make test
diff --git a/vendor/github.com/samber/lo/CHANGELOG.md b/vendor/github.com/samber/lo/CHANGELOG.md
new file mode 100644
index 00000000..8b9e4e11
--- /dev/null
+++ b/vendor/github.com/samber/lo/CHANGELOG.md
@@ -0,0 +1,434 @@
+# Changelog
+
+@samber: I sometimes forget to update this file. Ping me on [Twitter](https://twitter.com/samuelberthe) or open an issue in case of error. We need to keep a clear changelog for easier lib upgrade.
+
+## 1.39.0 (2023-12-01)
+
+Improvement:
+- Adding IsNil
+
+## 1.38.1 (2023-03-20)
+
+Improvement:
+- Async and AsyncX: now returns `<-chan T` instead of `chan T`
+
+## 1.38.0 (2023-03-20)
+
+Adding:
+- lo.ValueOr
+- lo.DebounceBy
+- lo.EmptyableToPtr
+
+Improvement:
+- Substring: add support for non-English chars
+
+Fix:
+- Async: Fix goroutine leak
+
+## 1.37.0 (2022-12-15)
+
+Adding:
+- lo.PartialX
+- lo.Transaction
+
+Improvement:
+- lo.Associate / lo.SliceToMap: faster memory allocation
+
+Chore:
+- Remove *_test.go files from releases, in order to cleanup dev dependencies
+
+## 1.36.0 (2022-11-28)
+
+Adding:
+- lo.AttemptWhile
+- lo.AttemptWhileWithDelay
+
+## 1.35.0 (2022-11-15)
+
+Adding:
+- lo.RandomString
+- lo.BufferWithTimeout (alias to lo.BatchWithTimeout)
+- lo.Buffer (alias to lo.Batch)
+
+Change:
+- lo.Slice: avoid panic caused by out-of-bounds
+
+Deprecation:
+- lo.BatchWithTimeout
+- lo.Batch
+
+## 1.34.0 (2022-11-12)
+
+Improving:
+- lo.Union: faster and can receive more than 2 lists
+
+Adding:
+- lo.FanIn (alias to lo.ChannelMerge)
+- lo.FanOut
+
+Deprecation:
+- lo.ChannelMerge
+
+## 1.33.0 (2022-10-14)
+
+Adding:
+- lo.ChannelMerge
+
+Improving:
+- helpers with callbacks/predicates/iteratee now have named arguments, for easier autocompletion
+
+## 1.32.0 (2022-10-10)
+
+Adding:
+
+- lo.ChannelToSlice
+- lo.CountValues
+- lo.CountValuesBy
+- lo.MapEntries
+- lo.Sum
+- lo.Interleave
+- TupleX.Unpack()
+
+## 1.31.0 (2022-10-06)
+
+Adding:
+
+- lo.SliceToChannel
+- lo.Generator
+- lo.Batch
+- lo.BatchWithTimeout
+
+## 1.30.1 (2022-10-06)
+
+Fix:
+
+- lo.Try1: remove generic type
+- lo.Validate: format error properly
+
+## 1.30.0 (2022-10-04)
+
+Adding:
+
+- lo.TernaryF
+- lo.Validate
+
+## 1.29.0 (2022-10-02)
+
+Adding:
+
+- lo.ErrorAs
+- lo.TryOr
+- lo.TryOrX
+
+## 1.28.0 (2022-09-05)
+
+Adding:
+
+- lo.ChannelDispatcher with 6 dispatching strategies:
+ - lo.DispatchingStrategyRoundRobin
+ - lo.DispatchingStrategyRandom
+ - lo.DispatchingStrategyWeightedRandom
+ - lo.DispatchingStrategyFirst
+ - lo.DispatchingStrategyLeast
+ - lo.DispatchingStrategyMost
+
+## 1.27.1 (2022-08-15)
+
+Bugfix:
+
+- Removed comparable constraint for lo.FindKeyBy
+
+## 1.27.0 (2022-07-29)
+
+Breaking:
+
+- Change of MapToSlice prototype: `MapToSlice[K comparable, V any, R any](in map[K]V, iteratee func(V, K) R) []R` -> `MapToSlice[K comparable, V any, R any](in map[K]V, iteratee func(K, V) R) []R`
+
+Added:
+
+- lo.ChunkString
+- lo.SliceToMap (alias to lo.Associate)
+
+## 1.26.0 (2022-07-24)
+
+Adding:
+
+- lo.Associate
+- lo.ReduceRight
+- lo.FromPtrOr
+- lo.MapToSlice
+- lo.IsSorted
+- lo.IsSortedByKey
+
+## 1.25.0 (2022-07-04)
+
+Adding:
+
+- lo.FindUniques
+- lo.FindUniquesBy
+- lo.FindDuplicates
+- lo.FindDuplicatesBy
+- lo.IsNotEmpty
+
+## 1.24.0 (2022-07-04)
+
+Adding:
+
+- lo.Without
+- lo.WithoutEmpty
+
+## 1.23.0 (2022-07-04)
+
+Adding:
+
+- lo.FindKey
+- lo.FindKeyBy
+
+## 1.22.0 (2022-07-04)
+
+Adding:
+
+- lo.Slice
+- lo.FromPtr
+- lo.IsEmpty
+- lo.Compact
+- lo.ToPairs: alias to lo.Entries
+- lo.FromPairs: alias to lo.FromEntries
+- lo.Partial
+
+Change:
+
+- lo.Must + lo.MustX: add context to panic message
+
+Fix:
+
+- lo.Nth: out of bound exception (#137)
+
+## 1.21.0 (2022-05-10)
+
+Adding:
+
+- lo.ToAnySlice
+- lo.FromAnySlice
+
+## 1.20.0 (2022-05-02)
+
+Adding:
+
+- lo.Synchronize
+- lo.SumBy
+
+Change:
+- Removed generic type definition for lo.Try0: `lo.Try0[T]()` -> `lo.Try0()`
+
+## 1.19.0 (2022-04-30)
+
+Adding:
+
+- lo.RepeatBy
+- lo.Subset
+- lo.Replace
+- lo.ReplaceAll
+- lo.Substring
+- lo.RuneLength
+
+## 1.18.0 (2022-04-28)
+
+Adding:
+
+- lo.SomeBy
+- lo.EveryBy
+- lo.None
+- lo.NoneBy
+
+## 1.17.0 (2022-04-27)
+
+Adding:
+
+- lo.Unpack2 -> lo.Unpack3
+- lo.Async0 -> lo.Async6
+
+## 1.16.0 (2022-04-26)
+
+Adding:
+
+- lo.AttemptWithDelay
+
+## 1.15.0 (2022-04-22)
+
+Improvement:
+
+- lo.Must: error or boolean value
+
+## 1.14.0 (2022-04-21)
+
+Adding:
+
+- lo.Coalesce
+
+## 1.13.0 (2022-04-14)
+
+Adding:
+
+- PickBy
+- PickByKeys
+- PickByValues
+- OmitBy
+- OmitByKeys
+- OmitByValues
+- Clamp
+- MapKeys
+- Invert
+- IfF + ElseIfF + ElseF
+- T0() + T1() + T2() + T3() + ...
+
+## 1.12.0 (2022-04-12)
+
+Adding:
+
+- Must
+- Must{0-6}
+- FindOrElse
+- Async
+- MinBy
+- MaxBy
+- Count
+- CountBy
+- FindIndexOf
+- FindLastIndexOf
+- FilterMap
+
+## 1.11.0 (2022-03-11)
+
+Adding:
+
+- Try
+- Try{0-6}
+- TryWitchValue
+- TryCatch
+- TryCatchWitchValue
+- Debounce
+- Reject
+
+## 1.10.0 (2022-03-11)
+
+Adding:
+
+- Range
+- RangeFrom
+- RangeWithSteps
+
+## 1.9.0 (2022-03-10)
+
+Added
+
+- Drop
+- DropRight
+- DropWhile
+- DropRightWhile
+
+## 1.8.0 (2022-03-10)
+
+Adding Union.
+
+## 1.7.0 (2022-03-09)
+
+Adding ContainBy
+
+Adding MapValues
+
+Adding FlatMap
+
+## 1.6.0 (2022-03-07)
+
+Fixed PartitionBy.
+
+Adding Sample
+
+Adding Samples
+
+## 1.5.0 (2022-03-07)
+
+Adding Times
+
+Adding Attempt
+
+Adding Repeat
+
+## 1.4.0 (2022-03-07)
+
+- adding tuple types (2->9)
+- adding Zip + Unzip
+- adding lo.PartitionBy + lop.PartitionBy
+- adding lop.GroupBy
+- fixing Nth
+
+## 1.3.0 (2022-03-03)
+
+Last and Nth return errors
+
+## 1.2.0 (2022-03-03)
+
+Adding `lop.Map` and `lop.ForEach`.
+
+## 1.1.0 (2022-03-03)
+
+Adding `i int` param to `lo.Map()`, `lo.Filter()`, `lo.ForEach()` and `lo.Reduce()` predicates.
+
+## 1.0.0 (2022-03-02)
+
+*Initial release*
+
+Supported helpers for slices:
+
+- Filter
+- Map
+- Reduce
+- ForEach
+- Uniq
+- UniqBy
+- GroupBy
+- Chunk
+- Flatten
+- Shuffle
+- Reverse
+- Fill
+- ToMap
+
+Supported helpers for maps:
+
+- Keys
+- Values
+- Entries
+- FromEntries
+- Assign (maps merge)
+
+Supported intersection helpers:
+
+- Contains
+- Every
+- Some
+- Intersect
+- Difference
+
+Supported search helpers:
+
+- IndexOf
+- LastIndexOf
+- Find
+- Min
+- Max
+- Last
+- Nth
+
+Other functional programming helpers:
+
+- Ternary (1 line if/else statement)
+- If / ElseIf / Else
+- Switch / Case / Default
+- ToPtr
+- ToSlicePtr
+
+Constraints:
+
+- Clonable
diff --git a/vendor/github.com/samber/lo/Dockerfile b/vendor/github.com/samber/lo/Dockerfile
new file mode 100644
index 00000000..5eab431a
--- /dev/null
+++ b/vendor/github.com/samber/lo/Dockerfile
@@ -0,0 +1,8 @@
+
+FROM golang:1.21.12
+
+WORKDIR /go/src/github.com/samber/lo
+
+COPY Makefile go.* ./
+
+RUN make tools
diff --git a/vendor/github.com/samber/lo/LICENSE b/vendor/github.com/samber/lo/LICENSE
new file mode 100644
index 00000000..c3dc72d9
--- /dev/null
+++ b/vendor/github.com/samber/lo/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Samuel Berthe
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/samber/lo/Makefile b/vendor/github.com/samber/lo/Makefile
new file mode 100644
index 00000000..f97ded85
--- /dev/null
+++ b/vendor/github.com/samber/lo/Makefile
@@ -0,0 +1,42 @@
+
+build:
+ go build -v ./...
+
+test:
+ go test -race -v ./...
+watch-test:
+ reflex -t 50ms -s -- sh -c 'gotest -race -v ./...'
+
+bench:
+ go test -benchmem -count 3 -bench ./...
+watch-bench:
+ reflex -t 50ms -s -- sh -c 'go test -benchmem -count 3 -bench ./...'
+
+coverage:
+ go test -v -coverprofile=cover.out -covermode=atomic ./...
+ go tool cover -html=cover.out -o cover.html
+
+# tools
+tools:
+ go install github.com/cespare/reflex@latest
+ go install github.com/rakyll/gotest@latest
+ go install github.com/psampaz/go-mod-outdated@latest
+ go install github.com/jondot/goweight@latest
+ go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
+ go get -t -u golang.org/x/tools/cmd/cover
+ go install github.com/sonatype-nexus-community/nancy@latest
+ go mod tidy
+
+lint:
+ golangci-lint run --timeout 60s --max-same-issues 50 ./...
+lint-fix:
+ golangci-lint run --timeout 60s --max-same-issues 50 --fix ./...
+
+audit: tools
+ go list -json -m all | nancy sleuth
+
+outdated: tools
+ go list -u -m -json all | go-mod-outdated -update -direct
+
+weight: tools
+ goweight
diff --git a/vendor/github.com/samber/lo/README.md b/vendor/github.com/samber/lo/README.md
new file mode 100644
index 00000000..3f73cc8e
--- /dev/null
+++ b/vendor/github.com/samber/lo/README.md
@@ -0,0 +1,3570 @@
+# lo - Iterate over slices, maps, channels...
+
+[![tag](https://img.shields.io/github/tag/samber/lo.svg)](https://github.com/samber/lo/releases)
+![Go Version](https://img.shields.io/badge/Go-%3E%3D%201.18-%23007d9c)
+[![GoDoc](https://godoc.org/github.com/samber/lo?status.svg)](https://pkg.go.dev/github.com/samber/lo)
+![Build Status](https://github.com/samber/lo/actions/workflows/test.yml/badge.svg)
+[![Go report](https://goreportcard.com/badge/github.com/samber/lo)](https://goreportcard.com/report/github.com/samber/lo)
+[![Coverage](https://img.shields.io/codecov/c/github/samber/lo)](https://codecov.io/gh/samber/lo)
+[![Contributors](https://img.shields.io/github/contributors/samber/lo)](https://github.com/samber/lo/graphs/contributors)
+[![License](https://img.shields.io/github/license/samber/lo)](./LICENSE)
+
+✨ **`samber/lo` is a Lodash-style Go library based on Go 1.18+ Generics.**
+
+This project started as an experiment with the new generics implementation. It may look like [Lodash](https://github.com/lodash/lodash) in some aspects. I used to code with the fantastic ["go-funk"](https://github.com/thoas/go-funk) package, but "go-funk" uses reflection and therefore is not typesafe.
+
+As expected, benchmarks demonstrate that generics are much faster than implementations based on the "reflect" package. Benchmarks also show similar performance gains compared to pure `for` loops. [See below](#-benchmark).
+
+In the future, 5 to 10 helpers will overlap with those coming into the Go standard library (under package names `slices` and `maps`). I feel this library is legitimate and offers many more valuable abstractions.
+
+**See also:**
+
+- [samber/do](https://github.com/samber/do): A dependency injection toolkit based on Go 1.18+ Generics
+- [samber/mo](https://github.com/samber/mo): Monads based on Go 1.18+ Generics (Option, Result, Either...)
+
+**Why this name?**
+
+I wanted a **short name**, similar to "Lodash" and no Go package uses this name.
+
+![lo](img/logo-full.png)
+
+## 🚀 Install
+
+```sh
+go get github.com/samber/lo@v1
+```
+
+This library is v1 and follows SemVer strictly.
+
+No breaking changes will be made to exported APIs before v2.0.0.
+
+This library has no dependencies outside the Go standard library.
+
+## 💡 Usage
+
+You can import `lo` using:
+
+```go
+import (
+ "github.com/samber/lo"
+ lop "github.com/samber/lo/parallel"
+)
+```
+
+Then use one of the helpers below:
+
+```go
+names := lo.Uniq([]string{"Samuel", "John", "Samuel"})
+// []string{"Samuel", "John"}
+```
+
+Most of the time, the compiler will be able to infer the type so that you can call: `lo.Uniq([]string{...})`.
+
+### Tips for lazy developers
+
+I cannot recommend it, but in case you are too lazy for repeating `lo.` everywhere, you can import the entire library into the namespace.
+
+```go
+import (
+ . "github.com/samber/lo"
+)
+```
+
+I take no responsibility on this junk. 😁 💩
+
+## 🤠 Spec
+
+GoDoc: [https://godoc.org/github.com/samber/lo](https://godoc.org/github.com/samber/lo)
+
+Supported helpers for slices:
+
+- [Filter](#filter)
+- [Map](#map)
+- [FilterMap](#filtermap)
+- [FlatMap](#flatmap)
+- [Reduce](#reduce)
+- [ReduceRight](#reduceright)
+- [ForEach](#foreach)
+- [ForEachWhile](#foreachwhile)
+- [Times](#times)
+- [Uniq](#uniq)
+- [UniqBy](#uniqby)
+- [GroupBy](#groupby)
+- [Chunk](#chunk)
+- [PartitionBy](#partitionby)
+- [Flatten](#flatten)
+- [Interleave](#interleave)
+- [Shuffle](#shuffle)
+- [Reverse](#reverse)
+- [Fill](#fill)
+- [Repeat](#repeat)
+- [RepeatBy](#repeatby)
+- [KeyBy](#keyby)
+- [Associate / SliceToMap](#associate-alias-slicetomap)
+- [Drop](#drop)
+- [DropRight](#dropright)
+- [DropWhile](#dropwhile)
+- [DropRightWhile](#droprightwhile)
+- [DropByIndex](#DropByIndex)
+- [Reject](#reject)
+- [RejectMap](#rejectmap)
+- [FilterReject](#filterreject)
+- [Count](#count)
+- [CountBy](#countby)
+- [CountValues](#countvalues)
+- [CountValuesBy](#countvaluesby)
+- [Subset](#subset)
+- [Slice](#slice)
+- [Replace](#replace)
+- [ReplaceAll](#replaceall)
+- [Compact](#compact)
+- [IsSorted](#issorted)
+- [IsSortedByKey](#issortedbykey)
+- [Splice](#Splice)
+
+Supported helpers for maps:
+
+- [Keys](#keys)
+- [UniqKeys](#uniqkeys)
+- [HasKey](#haskey)
+- [ValueOr](#valueor)
+- [Values](#values)
+- [UniqValues](#uniqvalues)
+- [PickBy](#pickby)
+- [PickByKeys](#pickbykeys)
+- [PickByValues](#pickbyvalues)
+- [OmitBy](#omitby)
+- [OmitByKeys](#omitbykeys)
+- [OmitByValues](#omitbyvalues)
+- [Entries / ToPairs](#entries-alias-topairs)
+- [FromEntries / FromPairs](#fromentries-alias-frompairs)
+- [Invert](#invert)
+- [Assign (merge of maps)](#assign)
+- [MapKeys](#mapkeys)
+- [MapValues](#mapvalues)
+- [MapEntries](#mapentries)
+- [MapToSlice](#maptoslice)
+
+Supported math helpers:
+
+- [Range / RangeFrom / RangeWithSteps](#range--rangefrom--rangewithsteps)
+- [Clamp](#clamp)
+- [Sum](#sum)
+- [SumBy](#sumby)
+- [Mean](#mean)
+- [MeanBy](#meanby)
+
+Supported helpers for strings:
+
+- [RandomString](#randomstring)
+- [Substring](#substring)
+- [ChunkString](#chunkstring)
+- [RuneLength](#runelength)
+- [PascalCase](#pascalcase)
+- [CamelCase](#camelcase)
+- [KebabCase](#kebabcase)
+- [SnakeCase](#snakecase)
+- [Words](#words)
+- [Capitalize](#capitalize)
+- [Elipse](#elipse)
+
+Supported helpers for tuples:
+
+- [T2 -> T9](#t2---t9)
+- [Unpack2 -> Unpack9](#unpack2---unpack9)
+- [Zip2 -> Zip9](#zip2---zip9)
+- [ZipBy2 -> ZipBy9](#zipby2---zipby9)
+- [Unzip2 -> Unzip9](#unzip2---unzip9)
+- [UnzipBy2 -> UnzipBy9](#unzipby2---unzipby9)
+
+Supported helpers for time and duration:
+
+- [Duration](#duration)
+- [Duration0 -> Duration10](#duration0-duration10)
+
+Supported helpers for channels:
+
+- [ChannelDispatcher](#channeldispatcher)
+- [SliceToChannel](#slicetochannel)
+- [Generator](#generator)
+- [Buffer](#buffer)
+- [BufferWithTimeout](#bufferwithtimeout)
+- [FanIn](#fanin)
+- [FanOut](#fanout)
+
+Supported intersection helpers:
+
+- [Contains](#contains)
+- [ContainsBy](#containsby)
+- [Every](#every)
+- [EveryBy](#everyby)
+- [Some](#some)
+- [SomeBy](#someby)
+- [None](#none)
+- [NoneBy](#noneby)
+- [Intersect](#intersect)
+- [Difference](#difference)
+- [Union](#union)
+- [Without](#without)
+- [WithoutEmpty](#withoutempty)
+
+Supported search helpers:
+
+- [IndexOf](#indexof)
+- [LastIndexOf](#lastindexof)
+- [Find](#find)
+- [FindIndexOf](#findindexof)
+- [FindLastIndexOf](#findlastindexof)
+- [FindOrElse](#findorelse)
+- [FindKey](#findkey)
+- [FindKeyBy](#findkeyby)
+- [FindUniques](#finduniques)
+- [FindUniquesBy](#finduniquesby)
+- [FindDuplicates](#findduplicates)
+- [FindDuplicatesBy](#findduplicatesby)
+- [Min](#min)
+- [MinBy](#minby)
+- [Earliest](#earliest)
+- [EarliestBy](#earliestby)
+- [Max](#max)
+- [MaxBy](#maxby)
+- [Latest](#latest)
+- [LatestBy](#latestby)
+- [First](#first)
+- [FirstOrEmpty](#FirstOrEmpty)
+- [FirstOr](#FirstOr)
+- [Last](#last)
+- [LastOrEmpty](#LastOrEmpty)
+- [LastOr](#LastOr)
+- [Nth](#nth)
+- [Sample](#sample)
+- [Samples](#samples)
+
+Conditional helpers:
+
+- [Ternary](#ternary)
+- [TernaryF](#ternaryf)
+- [If / ElseIf / Else](#if--elseif--else)
+- [Switch / Case / Default](#switch--case--default)
+
+Type manipulation helpers:
+
+- [IsNil](#isnil)
+- [ToPtr](#toptr)
+- [Nil](#nil)
+- [EmptyableToPtr](#emptyabletoptr)
+- [FromPtr](#fromptr)
+- [FromPtrOr](#fromptror)
+- [ToSlicePtr](#tosliceptr)
+- [FromSlicePtr](#fromsliceptr)
+- [FromSlicePtrOr](#fromsliceptror)
+- [ToAnySlice](#toanyslice)
+- [FromAnySlice](#fromanyslice)
+- [Empty](#empty)
+- [IsEmpty](#isempty)
+- [IsNotEmpty](#isnotempty)
+- [Coalesce](#coalesce)
+- [CoalesceOrEmpty](#coalesceorempty)
+
+Function helpers:
+
+- [Partial](#partial)
+- [Partial2 -> Partial5](#partial2---partial5)
+
+Concurrency helpers:
+
+- [Attempt](#attempt)
+- [AttemptWhile](#attemptwhile)
+- [AttemptWithDelay](#attemptwithdelay)
+- [AttemptWhileWithDelay](#attemptwhilewithdelay)
+- [Debounce](#debounce)
+- [DebounceBy](#debounceby)
+- [Synchronize](#synchronize)
+- [Async](#async)
+- [Transaction](#transaction)
+- [WaitFor](#waitfor)
+- [WaitForWithContext](#waitforwithcontext)
+
+Error handling:
+
+- [Validate](#validate)
+- [Must](#must)
+- [Try](#try)
+- [Try1 -> Try6](#try0-6)
+- [TryOr](#tryor)
+- [TryOr1 -> TryOr6](#tryor0-6)
+- [TryCatch](#trycatch)
+- [TryWithErrorValue](#trywitherrorvalue)
+- [TryCatchWithErrorValue](#trycatchwitherrorvalue)
+- [ErrorsAs](#errorsas)
+
+Constraints:
+
+- Clonable
+
+### Filter
+
+Iterates over a collection and returns an array of all the elements the predicate function returns `true` for.
+
+```go
+even := lo.Filter([]int{1, 2, 3, 4}, func(x int, index int) bool {
+ return x%2 == 0
+})
+// []int{2, 4}
+```
+
+[[play](https://go.dev/play/p/Apjg3WeSi7K)]
+
+### Map
+
+Manipulates a slice of one type and transforms it into a slice of another type:
+
+```go
+import "github.com/samber/lo"
+
+lo.Map([]int64{1, 2, 3, 4}, func(x int64, index int) string {
+ return strconv.FormatInt(x, 10)
+})
+// []string{"1", "2", "3", "4"}
+```
+
+[[play](https://go.dev/play/p/OkPcYAhBo0D)]
+
+Parallel processing: like `lo.Map()`, but the mapper function is called in a goroutine. Results are returned in the same order.
+
+```go
+import lop "github.com/samber/lo/parallel"
+
+lop.Map([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
+ return strconv.FormatInt(x, 10)
+})
+// []string{"1", "2", "3", "4"}
+```
+
+### FilterMap
+
+Returns a slice which obtained after both filtering and mapping using the given callback function.
+
+The callback function should return two values: the result of the mapping operation and whether the result element should be included or not.
+
+```go
+matching := lo.FilterMap([]string{"cpu", "gpu", "mouse", "keyboard"}, func(x string, _ int) (string, bool) {
+ if strings.HasSuffix(x, "pu") {
+ return "xpu", true
+ }
+ return "", false
+})
+// []string{"xpu", "xpu"}
+```
+
+[[play](https://go.dev/play/p/-AuYXfy7opz)]
+
+### FlatMap
+
+Manipulates a slice and transforms and flattens it to a slice of another type. The transform function can either return a slice or a `nil`, and in the `nil` case no value is added to the final slice.
+
+```go
+lo.FlatMap([]int64{0, 1, 2}, func(x int64, _ int) []string {
+ return []string{
+ strconv.FormatInt(x, 10),
+ strconv.FormatInt(x, 10),
+ }
+})
+// []string{"0", "0", "1", "1", "2", "2"}
+```
+
+[[play](https://go.dev/play/p/YSoYmQTA8-U)]
+
+### Reduce
+
+Reduces a collection to a single value. The value is calculated by accumulating the result of running each element in the collection through an accumulator function. Each successive invocation is supplied with the return value returned by the previous call.
+
+```go
+sum := lo.Reduce([]int{1, 2, 3, 4}, func(agg int, item int, _ int) int {
+ return agg + item
+}, 0)
+// 10
+```
+
+[[play](https://go.dev/play/p/R4UHXZNaaUG)]
+
+### ReduceRight
+
+Like `lo.Reduce` except that it iterates over elements of collection from right to left.
+
+```go
+result := lo.ReduceRight([][]int{{0, 1}, {2, 3}, {4, 5}}, func(agg []int, item []int, _ int) []int {
+ return append(agg, item...)
+}, []int{})
+// []int{4, 5, 2, 3, 0, 1}
+```
+
+[[play](https://go.dev/play/p/Fq3W70l7wXF)]
+
+### ForEach
+
+Iterates over elements of a collection and invokes the function over each element.
+
+```go
+import "github.com/samber/lo"
+
+lo.ForEach([]string{"hello", "world"}, func(x string, _ int) {
+ println(x)
+})
+// prints "hello\nworld\n"
+```
+
+[[play](https://go.dev/play/p/oofyiUPRf8t)]
+
+Parallel processing: like `lo.ForEach()`, but the callback is called as a goroutine.
+
+```go
+import lop "github.com/samber/lo/parallel"
+
+lop.ForEach([]string{"hello", "world"}, func(x string, _ int) {
+ println(x)
+})
+// prints "hello\nworld\n" or "world\nhello\n"
+```
+
+### ForEachWhile
+
+Iterates over collection elements and invokes iteratee for each element collection return value decide to continue or break, like do while().
+
+```go
+list := []int64{1, 2, -42, 4}
+
+lo.ForEachWhile(list, func(x int64, _ int) bool {
+ if x < 0 {
+ return false
+ }
+ fmt.Println(x)
+ return true
+})
+// 1
+// 2
+```
+
+[[play](https://go.dev/play/p/QnLGt35tnow)]
+
+### Times
+
+Times invokes the iteratee n times, returning an array of the results of each invocation. The iteratee is invoked with index as argument.
+
+```go
+import "github.com/samber/lo"
+
+lo.Times(3, func(i int) string {
+ return strconv.FormatInt(int64(i), 10)
+})
+// []string{"0", "1", "2"}
+```
+
+[[play](https://go.dev/play/p/vgQj3Glr6lT)]
+
+Parallel processing: like `lo.Times()`, but callback is called in goroutine.
+
+```go
+import lop "github.com/samber/lo/parallel"
+
+lop.Times(3, func(i int) string {
+ return strconv.FormatInt(int64(i), 10)
+})
+// []string{"0", "1", "2"}
+```
+
+### Uniq
+
+Returns a duplicate-free version of an array, in which only the first occurrence of each element is kept. The order of result values is determined by the order they occur in the array.
+
+```go
+uniqValues := lo.Uniq([]int{1, 2, 2, 1})
+// []int{1, 2}
+```
+
+[[play](https://go.dev/play/p/DTzbeXZ6iEN)]
+
+### UniqBy
+
+Returns a duplicate-free version of an array, in which only the first occurrence of each element is kept. The order of result values is determined by the order they occur in the array. It accepts `iteratee` which is invoked for each element in array to generate the criterion by which uniqueness is computed.
+
+```go
+uniqValues := lo.UniqBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
+ return i%3
+})
+// []int{0, 1, 2}
+```
+
+[[play](https://go.dev/play/p/g42Z3QSb53u)]
+
+### GroupBy
+
+Returns an object composed of keys generated from the results of running each element of collection through iteratee.
+
+```go
+import lo "github.com/samber/lo"
+
+groups := lo.GroupBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
+ return i%3
+})
+// map[int][]int{0: []int{0, 3}, 1: []int{1, 4}, 2: []int{2, 5}}
+```
+
+[[play](https://go.dev/play/p/XnQBd_v6brd)]
+
+Parallel processing: like `lo.GroupBy()`, but callback is called in goroutine.
+
+```go
+import lop "github.com/samber/lo/parallel"
+
+lop.GroupBy([]int{0, 1, 2, 3, 4, 5}, func(i int) int {
+ return i%3
+})
+// map[int][]int{0: []int{0, 3}, 1: []int{1, 4}, 2: []int{2, 5}}
+```
+
+### Chunk
+
+Returns an array of elements split into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.
+
+```go
+lo.Chunk([]int{0, 1, 2, 3, 4, 5}, 2)
+// [][]int{{0, 1}, {2, 3}, {4, 5}}
+
+lo.Chunk([]int{0, 1, 2, 3, 4, 5, 6}, 2)
+// [][]int{{0, 1}, {2, 3}, {4, 5}, {6}}
+
+lo.Chunk([]int{}, 2)
+// [][]int{}
+
+lo.Chunk([]int{0}, 2)
+// [][]int{{0}}
+```
+
+[[play](https://go.dev/play/p/EeKl0AuTehH)]
+
+### PartitionBy
+
+Returns an array of elements split into groups. The order of grouped values is determined by the order they occur in collection. The grouping is generated from the results of running each element of collection through iteratee.
+
+```go
+import lo "github.com/samber/lo"
+
+partitions := lo.PartitionBy([]int{-2, -1, 0, 1, 2, 3, 4, 5}, func(x int) string {
+ if x < 0 {
+ return "negative"
+ } else if x%2 == 0 {
+ return "even"
+ }
+ return "odd"
+})
+// [][]int{{-2, -1}, {0, 2, 4}, {1, 3, 5}}
+```
+
+[[play](https://go.dev/play/p/NfQ_nGjkgXW)]
+
+Parallel processing: like `lo.PartitionBy()`, but callback is called in goroutine. Results are returned in the same order.
+
+```go
+import lop "github.com/samber/lo/parallel"
+
+partitions := lop.PartitionBy([]int{-2, -1, 0, 1, 2, 3, 4, 5}, func(x int) string {
+ if x < 0 {
+ return "negative"
+ } else if x%2 == 0 {
+ return "even"
+ }
+ return "odd"
+})
+// [][]int{{-2, -1}, {0, 2, 4}, {1, 3, 5}}
+```
+
+### Flatten
+
+Returns an array a single level deep.
+
+```go
+flat := lo.Flatten([][]int{{0, 1}, {2, 3, 4, 5}})
+// []int{0, 1, 2, 3, 4, 5}
+```
+
+[[play](https://go.dev/play/p/rbp9ORaMpjw)]
+
+### Interleave
+
+Round-robin alternating input slices and sequentially appending value at index into result.
+
+```go
+interleaved := lo.Interleave([]int{1, 4, 7}, []int{2, 5, 8}, []int{3, 6, 9})
+// []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
+
+interleaved := lo.Interleave([]int{1}, []int{2, 5, 8}, []int{3, 6}, []int{4, 7, 9, 10})
+// []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+```
+
+[[play](https://go.dev/play/p/-RJkTLQEDVt)]
+
+### Shuffle
+
+Returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm.
+
+```go
+randomOrder := lo.Shuffle([]int{0, 1, 2, 3, 4, 5})
+// []int{1, 4, 0, 3, 5, 2}
+```
+
+[[play](https://go.dev/play/p/Qp73bnTDnc7)]
+
+### Reverse
+
+Reverses array so that the first element becomes the last, the second element becomes the second to last, and so on.
+
+⚠️ This helper is **mutable**. This behavior might change in `v2.0.0`. See [#160](https://github.com/samber/lo/issues/160).
+
+```go
+reverseOrder := lo.Reverse([]int{0, 1, 2, 3, 4, 5})
+// []int{5, 4, 3, 2, 1, 0}
+```
+
+[[play](https://go.dev/play/p/fhUMLvZ7vS6)]
+
+### Fill
+
+Fills elements of array with `initial` value.
+
+```go
+type foo struct {
+ bar string
+}
+
+func (f foo) Clone() foo {
+ return foo{f.bar}
+}
+
+initializedSlice := lo.Fill([]foo{foo{"a"}, foo{"a"}}, foo{"b"})
+// []foo{foo{"b"}, foo{"b"}}
+```
+
+[[play](https://go.dev/play/p/VwR34GzqEub)]
+
+### Repeat
+
+Builds a slice with N copies of initial value.
+
+```go
+type foo struct {
+ bar string
+}
+
+func (f foo) Clone() foo {
+ return foo{f.bar}
+}
+
+slice := lo.Repeat(2, foo{"a"})
+// []foo{foo{"a"}, foo{"a"}}
+```
+
+[[play](https://go.dev/play/p/g3uHXbmc3b6)]
+
+### RepeatBy
+
+Builds a slice with values returned by N calls of callback.
+
+```go
+slice := lo.RepeatBy(0, func (i int) string {
+ return strconv.FormatInt(int64(math.Pow(float64(i), 2)), 10)
+})
+// []string{}
+
+slice := lo.RepeatBy(5, func(i int) string {
+ return strconv.FormatInt(int64(math.Pow(float64(i), 2)), 10)
+})
+// []string{"0", "1", "4", "9", "16"}
+```
+
+[[play](https://go.dev/play/p/ozZLCtX_hNU)]
+
+### KeyBy
+
+Transforms a slice or an array of structs to a map based on a pivot callback.
+
+```go
+m := lo.KeyBy([]string{"a", "aa", "aaa"}, func(str string) int {
+ return len(str)
+})
+// map[int]string{1: "a", 2: "aa", 3: "aaa"}
+
+type Character struct {
+ dir string
+ code int
+}
+characters := []Character{
+ {dir: "left", code: 97},
+ {dir: "right", code: 100},
+}
+result := lo.KeyBy(characters, func(char Character) string {
+ return string(rune(char.code))
+})
+//map[a:{dir:left code:97} d:{dir:right code:100}]
+```
+
+[[play](https://go.dev/play/p/mdaClUAT-zZ)]
+
+### Associate (alias: SliceToMap)
+
+Returns a map containing key-value pairs provided by transform function applied to elements of the given slice.
+If any of two pairs would have the same key the last one gets added to the map.
+
+The order of keys in returned map is not specified and is not guaranteed to be the same from the original array.
+
+```go
+in := []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}}
+
+aMap := lo.Associate(in, func (f *foo) (string, int) {
+ return f.baz, f.bar
+})
+// map[string][int]{ "apple":1, "banana":2 }
+```
+
+[[play](https://go.dev/play/p/WHa2CfMO3Lr)]
+
+### Drop
+
+Drops n elements from the beginning of a slice or array.
+
+```go
+l := lo.Drop([]int{0, 1, 2, 3, 4, 5}, 2)
+// []int{2, 3, 4, 5}
+```
+
+[[play](https://go.dev/play/p/JswS7vXRJP2)]
+
+### DropRight
+
+Drops n elements from the end of a slice or array.
+
+```go
+l := lo.DropRight([]int{0, 1, 2, 3, 4, 5}, 2)
+// []int{0, 1, 2, 3}
+```
+
+[[play](https://go.dev/play/p/GG0nXkSJJa3)]
+
+### DropWhile
+
+Drop elements from the beginning of a slice or array while the predicate returns true.
+
+```go
+l := lo.DropWhile([]string{"a", "aa", "aaa", "aa", "aa"}, func(val string) bool {
+ return len(val) <= 2
+})
+// []string{"aaa", "aa", "aa"}
+```
+
+[[play](https://go.dev/play/p/7gBPYw2IK16)]
+
+### DropRightWhile
+
+Drop elements from the end of a slice or array while the predicate returns true.
+
+```go
+l := lo.DropRightWhile([]string{"a", "aa", "aaa", "aa", "aa"}, func(val string) bool {
+ return len(val) <= 2
+})
+// []string{"a", "aa", "aaa"}
+```
+
+[[play](https://go.dev/play/p/3-n71oEC0Hz)]
+
+### DropByIndex
+
+Drops elements from a slice or array by the index. A negative index will drop elements from the end of the slice.
+
+```go
+l := lo.DropByIndex([]int{0, 1, 2, 3, 4, 5}, 2, 4, -1)
+// []int{0, 1, 3}
+```
+
+[[play](https://go.dev/play/p/JswS7vXRJP2)]
+
+
+### Reject
+
+The opposite of Filter, this method returns the elements of collection that predicate does not return truthy for.
+
+```go
+odd := lo.Reject([]int{1, 2, 3, 4}, func(x int, _ int) bool {
+ return x%2 == 0
+})
+// []int{1, 3}
+```
+
+[[play](https://go.dev/play/p/YkLMODy1WEL)]
+
+### RejectMap
+
+The opposite of FilterMap, this method returns a slice which obtained after both filtering and mapping using the given callback function.
+
+The callback function should return two values:
+- the result of the mapping operation and
+- whether the result element should be included or not.
+
+```go
+items := lo.RejectMap([]int{1, 2, 3, 4}, func(x int, _ int) (int, bool) {
+ return x*10, x%2 == 0
+})
+// []int{10, 30}
+```
+
+### FilterReject
+
+Mixes Filter and Reject, this method returns two slices, one for the elements of collection that predicate returns truthy for and one for the elements that predicate does not return truthy for.
+
+```go
+kept, rejected := lo.FilterReject([]int{1, 2, 3, 4}, func(x int, _ int) bool {
+ return x%2 == 0
+})
+// []int{2, 4}
+// []int{1, 3}
+```
+
+### Count
+
+Counts the number of elements in the collection that compare equal to value.
+
+```go
+count := lo.Count([]int{1, 5, 1}, 1)
+// 2
+```
+
+[[play](https://go.dev/play/p/Y3FlK54yveC)]
+
+### CountBy
+
+Counts the number of elements in the collection for which predicate is true.
+
+```go
+count := lo.CountBy([]int{1, 5, 1}, func(i int) bool {
+ return i < 4
+})
+// 2
+```
+
+[[play](https://go.dev/play/p/ByQbNYQQi4X)]
+
+### CountValues
+
+Counts the number of each element in the collection.
+
+```go
+lo.CountValues([]int{})
+// map[int]int{}
+
+lo.CountValues([]int{1, 2})
+// map[int]int{1: 1, 2: 1}
+
+lo.CountValues([]int{1, 2, 2})
+// map[int]int{1: 1, 2: 2}
+
+lo.CountValues([]string{"foo", "bar", ""})
+// map[string]int{"": 1, "foo": 1, "bar": 1}
+
+lo.CountValues([]string{"foo", "bar", "bar"})
+// map[string]int{"foo": 1, "bar": 2}
+```
+
+[[play](https://go.dev/play/p/-p-PyLT4dfy)]
+
+### CountValuesBy
+
+Counts the number of each element in the collection. It ss equivalent to chaining lo.Map and lo.CountValues.
+
+```go
+isEven := func(v int) bool {
+ return v%2==0
+}
+
+lo.CountValuesBy([]int{}, isEven)
+// map[bool]int{}
+
+lo.CountValuesBy([]int{1, 2}, isEven)
+// map[bool]int{false: 1, true: 1}
+
+lo.CountValuesBy([]int{1, 2, 2}, isEven)
+// map[bool]int{false: 1, true: 2}
+
+length := func(v string) int {
+ return len(v)
+}
+
+lo.CountValuesBy([]string{"foo", "bar", ""}, length)
+// map[int]int{0: 1, 3: 2}
+
+lo.CountValuesBy([]string{"foo", "bar", "bar"}, length)
+// map[int]int{3: 3}
+```
+
+[[play](https://go.dev/play/p/2U0dG1SnOmS)]
+
+### Subset
+
+Returns a copy of a slice from `offset` up to `length` elements. Like `slice[start:start+length]`, but does not panic on overflow.
+
+```go
+in := []int{0, 1, 2, 3, 4}
+
+sub := lo.Subset(in, 2, 3)
+// []int{2, 3, 4}
+
+sub := lo.Subset(in, -4, 3)
+// []int{1, 2, 3}
+
+sub := lo.Subset(in, -2, math.MaxUint)
+// []int{3, 4}
+```
+
+[[play](https://go.dev/play/p/tOQu1GhFcog)]
+
+### Slice
+
+Returns a copy of a slice from `start` up to, but not including `end`. Like `slice[start:end]`, but does not panic on overflow.
+
+```go
+in := []int{0, 1, 2, 3, 4}
+
+slice := lo.Slice(in, 0, 5)
+// []int{0, 1, 2, 3, 4}
+
+slice := lo.Slice(in, 2, 3)
+// []int{2}
+
+slice := lo.Slice(in, 2, 6)
+// []int{2, 3, 4}
+
+slice := lo.Slice(in, 4, 3)
+// []int{}
+```
+
+[[play](https://go.dev/play/p/8XWYhfMMA1h)]
+
+### Replace
+
+Returns a copy of the slice with the first n non-overlapping instances of old replaced by new.
+
+```go
+in := []int{0, 1, 0, 1, 2, 3, 0}
+
+slice := lo.Replace(in, 0, 42, 1)
+// []int{42, 1, 0, 1, 2, 3, 0}
+
+slice := lo.Replace(in, -1, 42, 1)
+// []int{0, 1, 0, 1, 2, 3, 0}
+
+slice := lo.Replace(in, 0, 42, 2)
+// []int{42, 1, 42, 1, 2, 3, 0}
+
+slice := lo.Replace(in, 0, 42, -1)
+// []int{42, 1, 42, 1, 2, 3, 42}
+```
+
+[[play](https://go.dev/play/p/XfPzmf9gql6)]
+
+### ReplaceAll
+
+Returns a copy of the slice with all non-overlapping instances of old replaced by new.
+
+```go
+in := []int{0, 1, 0, 1, 2, 3, 0}
+
+slice := lo.ReplaceAll(in, 0, 42)
+// []int{42, 1, 42, 1, 2, 3, 42}
+
+slice := lo.ReplaceAll(in, -1, 42)
+// []int{0, 1, 0, 1, 2, 3, 0}
+```
+
+[[play](https://go.dev/play/p/a9xZFUHfYcV)]
+
+### Compact
+
+Returns a slice of all non-zero elements.
+
+```go
+in := []string{"", "foo", "", "bar", ""}
+
+slice := lo.Compact(in)
+// []string{"foo", "bar"}
+```
+
+[[play](https://go.dev/play/p/tXiy-iK6PAc)]
+
+### IsSorted
+
+Checks if a slice is sorted.
+
+```go
+slice := lo.IsSorted([]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
+// true
+```
+
+[[play](https://go.dev/play/p/mc3qR-t4mcx)]
+
+### IsSortedByKey
+
+Checks if a slice is sorted by iteratee.
+
+```go
+slice := lo.IsSortedByKey([]string{"a", "bb", "ccc"}, func(s string) int {
+ return len(s)
+})
+// true
+```
+
+[[play](https://go.dev/play/p/wiG6XyBBu49)]
+
+### Splice
+
+Splice inserts multiple elements at index i. A negative index counts back from the end of the slice. The helper is protected against overflow errors.
+
+```go
+result := lo.Splice([]string{"a", "b"}, 1, "1", "2")
+// []string{"a", "1", "2", "b"}
+
+// negative
+result = lo.Splice([]string{"a", "b"}, -1, "1", "2")
+// []string{"a", "1", "2", "b"}
+
+// overflow
+result = lo.Splice([]string{"a", "b"}, 42, "1", "2")
+// []string{"a", "b", "1", "2"}
+```
+
+[[play](https://go.dev/play/p/G5_GhkeSUBA)]
+
+### Keys
+
+Creates a slice of the map keys.
+
+Use the UniqKeys variant to deduplicate common keys.
+
+```go
+keys := lo.Keys(map[string]int{"foo": 1, "bar": 2})
+// []string{"foo", "bar"}
+
+keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
+// []string{"foo", "bar", "baz"}
+
+keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3})
+// []string{"foo", "bar", "bar"}
+```
+
+[[play](https://go.dev/play/p/Uu11fHASqrU)]
+
+### UniqKeys
+
+Creates an array of unique map keys.
+
+```go
+keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
+// []string{"foo", "bar", "baz"}
+
+keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3})
+// []string{"foo", "bar"}
+```
+
+[[play](https://go.dev/play/p/TPKAb6ILdHk)]
+
+### HasKey
+
+Returns whether the given key exists.
+
+```go
+exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "foo")
+// true
+
+exists := lo.HasKey(map[string]int{"foo": 1, "bar": 2}, "baz")
+// false
+```
+
+[[play](https://go.dev/play/p/aVwubIvECqS)]
+
+### Values
+
+Creates an array of the map values.
+
+Use the UniqValues variant to deduplicate common values.
+
+```go
+values := lo.Values(map[string]int{"foo": 1, "bar": 2})
+// []int{1, 2}
+
+values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
+// []int{1, 2, 3}
+
+values := lo.Values(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2})
+// []int{1, 2, 2}
+```
+
+[[play](https://go.dev/play/p/nnRTQkzQfF6)]
+
+### UniqValues
+
+Creates an array of unique map values.
+
+```go
+values := lo.UniqValues(map[string]int{"foo": 1, "bar": 2})
+// []int{1, 2}
+
+values := lo.UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
+// []int{1, 2, 3}
+
+values := lo.UniqValues(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 2})
+// []int{1, 2}
+```
+
+[[play](https://go.dev/play/p/nf6bXMh7rM3)]
+
+### ValueOr
+
+Returns the value of the given key or the fallback value if the key is not present.
+
+```go
+value := lo.ValueOr(map[string]int{"foo": 1, "bar": 2}, "foo", 42)
+// 1
+
+value := lo.ValueOr(map[string]int{"foo": 1, "bar": 2}, "baz", 42)
+// 42
+```
+
+[[play](https://go.dev/play/p/bAq9mHErB4V)]
+
+### PickBy
+
+Returns same map type filtered by given predicate.
+
+```go
+m := lo.PickBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(key string, value int) bool {
+ return value%2 == 1
+})
+// map[string]int{"foo": 1, "baz": 3}
+```
+
+[[play](https://go.dev/play/p/kdg8GR_QMmf)]
+
+### PickByKeys
+
+Returns same map type filtered by given keys.
+
+```go
+m := lo.PickByKeys(map[string]int{"foo": 1, "bar": 2, "baz": 3}, []string{"foo", "baz"})
+// map[string]int{"foo": 1, "baz": 3}
+```
+
+[[play](https://go.dev/play/p/R1imbuci9qU)]
+
+### PickByValues
+
+Returns same map type filtered by given values.
+
+```go
+m := lo.PickByValues(map[string]int{"foo": 1, "bar": 2, "baz": 3}, []int{1, 3})
+// map[string]int{"foo": 1, "baz": 3}
+```
+
+[[play](https://go.dev/play/p/1zdzSvbfsJc)]
+
+### OmitBy
+
+Returns same map type filtered by given predicate.
+
+```go
+m := lo.OmitBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(key string, value int) bool {
+ return value%2 == 1
+})
+// map[string]int{"bar": 2}
+```
+
+[[play](https://go.dev/play/p/EtBsR43bdsd)]
+
+### OmitByKeys
+
+Returns same map type filtered by given keys.
+
+```go
+m := lo.OmitByKeys(map[string]int{"foo": 1, "bar": 2, "baz": 3}, []string{"foo", "baz"})
+// map[string]int{"bar": 2}
+```
+
+[[play](https://go.dev/play/p/t1QjCrs-ysk)]
+
+### OmitByValues
+
+Returns same map type filtered by given values.
+
+```go
+m := lo.OmitByValues(map[string]int{"foo": 1, "bar": 2, "baz": 3}, []int{1, 3})
+// map[string]int{"bar": 2}
+```
+
+[[play](https://go.dev/play/p/9UYZi-hrs8j)]
+
+### Entries (alias: ToPairs)
+
+Transforms a map into array of key/value pairs.
+
+```go
+entries := lo.Entries(map[string]int{"foo": 1, "bar": 2})
+// []lo.Entry[string, int]{
+// {
+// Key: "foo",
+// Value: 1,
+// },
+// {
+// Key: "bar",
+// Value: 2,
+// },
+// }
+```
+
+[[play](https://go.dev/play/p/3Dhgx46gawJ)]
+
+### FromEntries (alias: FromPairs)
+
+Transforms an array of key/value pairs into a map.
+
+```go
+m := lo.FromEntries([]lo.Entry[string, int]{
+ {
+ Key: "foo",
+ Value: 1,
+ },
+ {
+ Key: "bar",
+ Value: 2,
+ },
+})
+// map[string]int{"foo": 1, "bar": 2}
+```
+
+[[play](https://go.dev/play/p/oIr5KHFGCEN)]
+
+### Invert
+
+Creates a map composed of the inverted keys and values. If map contains duplicate values, subsequent values overwrite property assignments of previous values.
+
+```go
+m1 := lo.Invert(map[string]int{"a": 1, "b": 2})
+// map[int]string{1: "a", 2: "b"}
+
+m2 := lo.Invert(map[string]int{"a": 1, "b": 2, "c": 1})
+// map[int]string{1: "c", 2: "b"}
+```
+
+[[play](https://go.dev/play/p/rFQ4rak6iA1)]
+
+### Assign
+
+Merges multiple maps from left to right.
+
+```go
+mergedMaps := lo.Assign(
+ map[string]int{"a": 1, "b": 2},
+ map[string]int{"b": 3, "c": 4},
+)
+// map[string]int{"a": 1, "b": 3, "c": 4}
+```
+
+[[play](https://go.dev/play/p/VhwfJOyxf5o)]
+
+### MapKeys
+
+Manipulates a map keys and transforms it to a map of another type.
+
+```go
+m2 := lo.MapKeys(map[int]int{1: 1, 2: 2, 3: 3, 4: 4}, func(_ int, v int) string {
+ return strconv.FormatInt(int64(v), 10)
+})
+// map[string]int{"1": 1, "2": 2, "3": 3, "4": 4}
+```
+
+[[play](https://go.dev/play/p/9_4WPIqOetJ)]
+
+### MapValues
+
+Manipulates a map values and transforms it to a map of another type.
+
+```go
+m1 := map[int]int64{1: 1, 2: 2, 3: 3}
+
+m2 := lo.MapValues(m1, func(x int64, _ int) string {
+ return strconv.FormatInt(x, 10)
+})
+// map[int]string{1: "1", 2: "2", 3: "3"}
+```
+
+[[play](https://go.dev/play/p/T_8xAfvcf0W)]
+
+### MapEntries
+
+Manipulates a map entries and transforms it to a map of another type.
+
+```go
+in := map[string]int{"foo": 1, "bar": 2}
+
+out := lo.MapEntries(in, func(k string, v int) (int, string) {
+ return v,k
+})
+// map[int]string{1: "foo", 2: "bar"}
+```
+
+[[play](https://go.dev/play/p/VuvNQzxKimT)]
+
+### MapToSlice
+
+Transforms a map into a slice based on specific iteratee.
+
+```go
+m := map[int]int64{1: 4, 2: 5, 3: 6}
+
+s := lo.MapToSlice(m, func(k int, v int64) string {
+ return fmt.Sprintf("%d_%d", k, v)
+})
+// []string{"1_4", "2_5", "3_6"}
+```
+
+[[play](https://go.dev/play/p/ZuiCZpDt6LD)]
+
+### Range / RangeFrom / RangeWithSteps
+
+Creates an array of numbers (positive and/or negative) progressing from start up to, but not including end.
+
+```go
+result := lo.Range(4)
+// [0, 1, 2, 3]
+
+result := lo.Range(-4)
+// [0, -1, -2, -3]
+
+result := lo.RangeFrom(1, 5)
+// [1, 2, 3, 4, 5]
+
+result := lo.RangeFrom[float64](1.0, 5)
+// [1.0, 2.0, 3.0, 4.0, 5.0]
+
+result := lo.RangeWithSteps(0, 20, 5)
+// [0, 5, 10, 15]
+
+result := lo.RangeWithSteps[float32](-1.0, -4.0, -1.0)
+// [-1.0, -2.0, -3.0]
+
+result := lo.RangeWithSteps(1, 4, -1)
+// []
+
+result := lo.Range(0)
+// []
+```
+
+[[play](https://go.dev/play/p/0r6VimXAi9H)]
+
+### Clamp
+
+Clamps number within the inclusive lower and upper bounds.
+
+```go
+r1 := lo.Clamp(0, -10, 10)
+// 0
+
+r2 := lo.Clamp(-42, -10, 10)
+// -10
+
+r3 := lo.Clamp(42, -10, 10)
+// 10
+```
+
+[[play](https://go.dev/play/p/RU4lJNC2hlI)]
+
+### Sum
+
+Sums the values in a collection.
+
+If collection is empty 0 is returned.
+
+```go
+list := []int{1, 2, 3, 4, 5}
+sum := lo.Sum(list)
+// 15
+```
+
+[[play](https://go.dev/play/p/upfeJVqs4Bt)]
+
+### SumBy
+
+Summarizes the values in a collection using the given return value from the iteration function.
+
+If collection is empty 0 is returned.
+
+```go
+strings := []string{"foo", "bar"}
+sum := lo.SumBy(strings, func(item string) int {
+ return len(item)
+})
+// 6
+```
+
+[[play](https://go.dev/play/p/Dz_a_7jN_ca)]
+
+### Mean
+
+Calculates the mean of a collection of numbers.
+
+If collection is empty 0 is returned.
+
+```go
+mean := lo.Mean([]int{2, 3, 4, 5})
+// 3
+
+mean := lo.Mean([]float64{2, 3, 4, 5})
+// 3.5
+
+mean := lo.Mean([]float64{})
+// 0
+```
+
+### MeanBy
+
+Calculates the mean of a collection of numbers using the given return value from the iteration function.
+
+If collection is empty 0 is returned.
+
+```go
+list := []string{"aa", "bbb", "cccc", "ddddd"}
+mapper := func(item string) float64 {
+ return float64(len(item))
+}
+
+mean := lo.MeanBy(list, mapper)
+// 3.5
+
+mean := lo.MeanBy([]float64{}, mapper)
+// 0
+```
+
+### RandomString
+
+Returns a random string of the specified length and made of the specified charset.
+
+```go
+str := lo.RandomString(5, lo.LettersCharset)
+// example: "eIGbt"
+```
+
+[[play](https://go.dev/play/p/rRseOQVVum4)]
+
+### Substring
+
+Return part of a string.
+
+```go
+sub := lo.Substring("hello", 2, 3)
+// "llo"
+
+sub := lo.Substring("hello", -4, 3)
+// "ell"
+
+sub := lo.Substring("hello", -2, math.MaxUint)
+// "lo"
+```
+
+[[play](https://go.dev/play/p/TQlxQi82Lu1)]
+
+### ChunkString
+
+Returns an array of strings split into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.
+
+```go
+lo.ChunkString("123456", 2)
+// []string{"12", "34", "56"}
+
+lo.ChunkString("1234567", 2)
+// []string{"12", "34", "56", "7"}
+
+lo.ChunkString("", 2)
+// []string{""}
+
+lo.ChunkString("1", 2)
+// []string{"1"}
+```
+
+[[play](https://go.dev/play/p/__FLTuJVz54)]
+
+### RuneLength
+
+An alias to utf8.RuneCountInString which returns the number of runes in string.
+
+```go
+sub := lo.RuneLength("hellô")
+// 5
+
+sub := len("hellô")
+// 6
+```
+
+[[play](https://go.dev/play/p/tuhgW_lWY8l)]
+
+### PascalCase
+
+Converts string to pascal case.
+
+```go
+str := lo.PascalCase("hello_world")
+// HelloWorld
+```
+
+[[play](https://go.dev/play/p/iZkdeLP9oiB)]
+
+### CamelCase
+
+Converts string to camel case.
+
+```go
+str := lo.CamelCase("hello_world")
+// helloWorld
+```
+
+[[play](https://go.dev/play/p/dtyFB58MBRp)]
+
+### KebabCase
+
+Converts string to kebab case.
+
+```go
+str := lo.KebabCase("helloWorld")
+// hello-world
+```
+
+[[play](https://go.dev/play/p/2YTuPafwECA)]
+
+### SnakeCase
+
+Converts string to snake case.
+
+```go
+str := lo.SnakeCase("HelloWorld")
+// hello_world
+```
+
+[[play](https://go.dev/play/p/QVKJG9nOnDg)]
+
+### Words
+
+Splits string into an array of its words.
+
+```go
+str := lo.Words("helloWorld")
+// []string{"hello", "world"}
+```
+
+[[play](https://go.dev/play/p/2P4zhqqq61g)]
+
+### Capitalize
+
+Converts the first character of string to upper case and the remaining to lower case.
+
+```go
+str := lo.Capitalize("heLLO")
+// Hello
+```
+
+### Elipse
+
+Truncates a string to a specified length and appends an ellipsis if truncated.
+
+```go
+str := lo.Elipse("Lorem Ipsum", 5)
+// Lo...
+
+str := lo.Elipse("Lorem Ipsum", 100)
+// Lorem Ipsum
+
+str := lo.Elipse("Lorem Ipsum", 3)
+// ...
+```
+
+### T2 -> T9
+
+Creates a tuple from a list of values.
+
+```go
+tuple1 := lo.T2("x", 1)
+// Tuple2[string, int]{A: "x", B: 1}
+
+func example() (string, int) { return "y", 2 }
+tuple2 := lo.T2(example())
+// Tuple2[string, int]{A: "y", B: 2}
+```
+
+[[play](https://go.dev/play/p/IllL3ZO4BQm)]
+
+### Unpack2 -> Unpack9
+
+Returns values contained in tuple.
+
+```go
+r1, r2 := lo.Unpack2(lo.Tuple2[string, int]{"a", 1})
+// "a", 1
+```
+
+Unpack is also available as a method of TupleX.
+
+```go
+tuple2 := lo.T2("a", 1)
+a, b := tuple2.Unpack()
+// "a", 1
+```
+
+[[play](https://go.dev/play/p/xVP_k0kJ96W)]
+
+### Zip2 -> Zip9
+
+Zip creates a slice of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+
+When collections have different size, the Tuple attributes are filled with zero value.
+
+```go
+tuples := lo.Zip2([]string{"a", "b"}, []int{1, 2})
+// []Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}}
+```
+
+[[play](https://go.dev/play/p/jujaA6GaJTp)]
+
+### ZipBy2 -> ZipBy9
+
+ZipBy creates a slice of transformed elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+
+When collections have different size, the Tuple attributes are filled with zero value.
+
+```go
+items := lo.ZipBy2([]string{"a", "b"}, []int{1, 2}, func(a string, b int) string {
+ return fmt.Sprintf("%s-%d", a, b)
+})
+// []string{"a-1", "b-2"}
+```
+
+### Unzip2 -> Unzip9
+
+Unzip accepts an array of grouped elements and creates an array regrouping the elements to their pre-zip configuration.
+
+```go
+a, b := lo.Unzip2([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}})
+// []string{"a", "b"}
+// []int{1, 2}
+```
+
+[[play](https://go.dev/play/p/ciHugugvaAW)]
+
+### UnzipBy2 -> UnzipBy9
+
+UnzipBy2 iterates over a collection and creates an array regrouping the elements to their pre-zip configuration.
+
+```go
+a, b := lo.UnzipBy2([]string{"hello", "john", "doe"}, func(str string) (string, int) {
+ return str, len(str)
+})
+// []string{"hello", "john", "doe"}
+// []int{5, 4, 3}
+```
+
+### Duration
+
+Returns the time taken to execute a function.
+
+```go
+duration := lo.Duration(func() {
+ // very long job
+})
+// 3s
+```
+
+### Duration0 -> Duration10
+
+Returns the time taken to execute a function.
+
+```go
+duration := lo.Duration0(func() {
+ // very long job
+})
+// 3s
+
+err, duration := lo.Duration1(func() error {
+ // very long job
+ return fmt.Errorf("an error")
+})
+// an error
+// 3s
+
+str, nbr, err, duration := lo.Duration3(func() (string, int, error) {
+ // very long job
+ return "hello", 42, nil
+})
+// hello
+// 42
+// nil
+// 3s
+```
+
+### ChannelDispatcher
+
+Distributes messages from input channels into N child channels. Close events are propagated to children.
+
+Underlying channels can have a fixed buffer capacity or be unbuffered when cap is 0.
+
+```go
+ch := make(chan int, 42)
+for i := 0; i <= 10; i++ {
+ ch <- i
+}
+
+children := lo.ChannelDispatcher(ch, 5, 10, DispatchingStrategyRoundRobin[int])
+// []<-chan int{...}
+
+consumer := func(c <-chan int) {
+ for {
+ msg, ok := <-c
+ if !ok {
+ println("closed")
+
+ break
+ }
+
+ println(msg)
+ }
+}
+
+for i := range children {
+ go consumer(children[i])
+}
+```
+
+Many distributions strategies are available:
+
+- [lo.DispatchingStrategyRoundRobin](./channel.go): Distributes messages in a rotating sequential manner.
+- [lo.DispatchingStrategyRandom](./channel.go): Distributes messages in a random manner.
+- [lo.DispatchingStrategyWeightedRandom](./channel.go): Distributes messages in a weighted manner.
+- [lo.DispatchingStrategyFirst](./channel.go): Distributes messages in the first non-full channel.
+- [lo.DispatchingStrategyLeast](./channel.go): Distributes messages in the emptiest channel.
+- [lo.DispatchingStrategyMost](./channel.go): Distributes to the fullest channel.
+
+Some strategies bring fallback, in order to favor non-blocking behaviors. See implementations.
+
+For custom strategies, just implement the `lo.DispatchingStrategy` prototype:
+
+```go
+type DispatchingStrategy[T any] func(message T, messageIndex uint64, channels []<-chan T) int
+```
+
+Eg:
+
+```go
+type Message struct {
+ TenantID uuid.UUID
+}
+
+func hash(id uuid.UUID) int {
+ h := fnv.New32a()
+ h.Write([]byte(id.String()))
+ return int(h.Sum32())
+}
+
+// Routes messages per TenantID.
+customStrategy := func(message string, messageIndex uint64, channels []<-chan string) int {
+ destination := hash(message) % len(channels)
+
+ // check if channel is full
+ if len(channels[destination]) < cap(channels[destination]) {
+ return destination
+ }
+
+ // fallback when child channel is full
+ return utils.DispatchingStrategyRoundRobin(message, uint64(destination), channels)
+}
+
+children := lo.ChannelDispatcher(ch, 5, 10, customStrategy)
+...
+```
+
+### SliceToChannel
+
+Returns a read-only channels of collection elements. Channel is closed after last element. Channel capacity can be customized.
+
+```go
+list := []int{1, 2, 3, 4, 5}
+
+for v := range lo.SliceToChannel(2, list) {
+ println(v)
+}
+// prints 1, then 2, then 3, then 4, then 5
+```
+
+### ChannelToSlice
+
+Returns a slice built from channels items. Blocks until channel closes.
+
+```go
+list := []int{1, 2, 3, 4, 5}
+ch := lo.SliceToChannel(2, list)
+
+items := ChannelToSlice(ch)
+// []int{1, 2, 3, 4, 5}
+```
+
+### Generator
+
+Implements the generator design pattern. Channel is closed after last element. Channel capacity can be customized.
+
+```go
+generator := func(yield func(int)) {
+ yield(1)
+ yield(2)
+ yield(3)
+}
+
+for v := range lo.Generator(2, generator) {
+ println(v)
+}
+// prints 1, then 2, then 3
+```
+
+### Buffer
+
+Creates a slice of n elements from a channel. Returns the slice, the slice length, the read time and the channel status (opened/closed).
+
+```go
+ch := lo.SliceToChannel(2, []int{1, 2, 3, 4, 5})
+
+items1, length1, duration1, ok1 := lo.Buffer(ch, 3)
+// []int{1, 2, 3}, 3, 0s, true
+items2, length2, duration2, ok2 := lo.Buffer(ch, 3)
+// []int{4, 5}, 2, 0s, false
+```
+
+Example: RabbitMQ consumer 👇
+
+```go
+ch := readFromQueue()
+
+for {
+ // read 1k items
+ items, length, _, ok := lo.Buffer(ch, 1000)
+
+ // do batching stuff
+
+ if !ok {
+ break
+ }
+}
+```
+
+### BufferWithTimeout
+
+Creates a slice of n elements from a channel, with timeout. Returns the slice, the slice length, the read time and the channel status (opened/closed).
+
+```go
+generator := func(yield func(int)) {
+ for i := 0; i < 5; i++ {
+ yield(i)
+ time.Sleep(35*time.Millisecond)
+ }
+}
+
+ch := lo.Generator(0, generator)
+
+items1, length1, duration1, ok1 := lo.BufferWithTimeout(ch, 3, 100*time.Millisecond)
+// []int{1, 2}, 2, 100ms, true
+items2, length2, duration2, ok2 := lo.BufferWithTimeout(ch, 3, 100*time.Millisecond)
+// []int{3, 4, 5}, 3, 75ms, true
+items3, length3, duration2, ok3 := lo.BufferWithTimeout(ch, 3, 100*time.Millisecond)
+// []int{}, 0, 10ms, false
+```
+
+Example: RabbitMQ consumer 👇
+
+```go
+ch := readFromQueue()
+
+for {
+ // read 1k items
+ // wait up to 1 second
+ items, length, _, ok := lo.BufferWithTimeout(ch, 1000, 1*time.Second)
+
+ // do batching stuff
+
+ if !ok {
+ break
+ }
+}
+```
+
+Example: Multithreaded RabbitMQ consumer 👇
+
+```go
+ch := readFromQueue()
+
+// 5 workers
+// prefetch 1k messages per worker
+children := lo.ChannelDispatcher(ch, 5, 1000, lo.DispatchingStrategyFirst[int])
+
+consumer := func(c <-chan int) {
+ for {
+ // read 1k items
+ // wait up to 1 second
+ items, length, _, ok := lo.BufferWithTimeout(ch, 1000, 1*time.Second)
+
+ // do batching stuff
+
+ if !ok {
+ break
+ }
+ }
+}
+
+for i := range children {
+ go consumer(children[i])
+}
+```
+
+### FanIn
+
+Merge messages from multiple input channels into a single buffered channel. Output messages has no priority. When all upstream channels reach EOF, downstream channel closes.
+
+```go
+stream1 := make(chan int, 42)
+stream2 := make(chan int, 42)
+stream3 := make(chan int, 42)
+
+all := lo.FanIn(100, stream1, stream2, stream3)
+// <-chan int
+```
+
+### FanOut
+
+Broadcasts all the upstream messages to multiple downstream channels. When upstream channel reach EOF, downstream channels close. If any downstream channels is full, broadcasting is paused.
+
+```go
+stream := make(chan int, 42)
+
+all := lo.FanOut(5, 100, stream)
+// [5]<-chan int
+```
+
+### Contains
+
+Returns true if an element is present in a collection.
+
+```go
+present := lo.Contains([]int{0, 1, 2, 3, 4, 5}, 5)
+// true
+```
+
+### ContainsBy
+
+Returns true if the predicate function returns `true`.
+
+```go
+present := lo.ContainsBy([]int{0, 1, 2, 3, 4, 5}, func(x int) bool {
+ return x == 3
+})
+// true
+```
+
+### Every
+
+Returns true if all elements of a subset are contained into a collection or if the subset is empty.
+
+```go
+ok := lo.Every([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
+// true
+
+ok := lo.Every([]int{0, 1, 2, 3, 4, 5}, []int{0, 6})
+// false
+```
+
+### EveryBy
+
+Returns true if the predicate returns true for all of the elements in the collection or if the collection is empty.
+
+```go
+b := EveryBy([]int{1, 2, 3, 4}, func(x int) bool {
+ return x < 5
+})
+// true
+```
+
+### Some
+
+Returns true if at least 1 element of a subset is contained into a collection.
+If the subset is empty Some returns false.
+
+```go
+ok := lo.Some([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
+// true
+
+ok := lo.Some([]int{0, 1, 2, 3, 4, 5}, []int{-1, 6})
+// false
+```
+
+### SomeBy
+
+Returns true if the predicate returns true for any of the elements in the collection.
+If the collection is empty SomeBy returns false.
+
+```go
+b := SomeBy([]int{1, 2, 3, 4}, func(x int) bool {
+ return x < 3
+})
+// true
+```
+
+### None
+
+Returns true if no element of a subset are contained into a collection or if the subset is empty.
+
+```go
+b := None([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
+// false
+b := None([]int{0, 1, 2, 3, 4, 5}, []int{-1, 6})
+// true
+```
+
+### NoneBy
+
+Returns true if the predicate returns true for none of the elements in the collection or if the collection is empty.
+
+```go
+b := NoneBy([]int{1, 2, 3, 4}, func(x int) bool {
+ return x < 0
+})
+// true
+```
+
+### Intersect
+
+Returns the intersection between two collections.
+
+```go
+result1 := lo.Intersect([]int{0, 1, 2, 3, 4, 5}, []int{0, 2})
+// []int{0, 2}
+
+result2 := lo.Intersect([]int{0, 1, 2, 3, 4, 5}, []int{0, 6})
+// []int{0}
+
+result3 := lo.Intersect([]int{0, 1, 2, 3, 4, 5}, []int{-1, 6})
+// []int{}
+```
+
+### Difference
+
+Returns the difference between two collections.
+
+- The first value is the collection of element absent of list2.
+- The second value is the collection of element absent of list1.
+
+```go
+left, right := lo.Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 2, 6})
+// []int{1, 3, 4, 5}, []int{6}
+
+left, right := lo.Difference([]int{0, 1, 2, 3, 4, 5}, []int{0, 1, 2, 3, 4, 5})
+// []int{}, []int{}
+```
+
+### Union
+
+Returns all distinct elements from given collections. Result will not change the order of elements relatively.
+
+```go
+union := lo.Union([]int{0, 1, 2, 3, 4, 5}, []int{0, 2}, []int{0, 10})
+// []int{0, 1, 2, 3, 4, 5, 10}
+```
+
+### Without
+
+Returns slice excluding all given values.
+
+```go
+subset := lo.Without([]int{0, 2, 10}, 2)
+// []int{0, 10}
+
+subset := lo.Without([]int{0, 2, 10}, 0, 1, 2, 3, 4, 5)
+// []int{10}
+```
+
+### WithoutEmpty
+
+Returns slice excluding empty values.
+
+```go
+subset := lo.WithoutEmpty([]int{0, 2, 10})
+// []int{2, 10}
+```
+
+### IndexOf
+
+Returns the index at which the first occurrence of a value is found in an array or return -1 if the value cannot be found.
+
+```go
+found := lo.IndexOf([]int{0, 1, 2, 1, 2, 3}, 2)
+// 2
+
+notFound := lo.IndexOf([]int{0, 1, 2, 1, 2, 3}, 6)
+// -1
+```
+
+### LastIndexOf
+
+Returns the index at which the last occurrence of a value is found in an array or return -1 if the value cannot be found.
+
+```go
+found := lo.LastIndexOf([]int{0, 1, 2, 1, 2, 3}, 2)
+// 4
+
+notFound := lo.LastIndexOf([]int{0, 1, 2, 1, 2, 3}, 6)
+// -1
+```
+
+### Find
+
+Search an element in a slice based on a predicate. It returns element and true if element was found.
+
+```go
+str, ok := lo.Find([]string{"a", "b", "c", "d"}, func(i string) bool {
+ return i == "b"
+})
+// "b", true
+
+str, ok := lo.Find([]string{"foobar"}, func(i string) bool {
+ return i == "b"
+})
+// "", false
+```
+
+### FindIndexOf
+
+FindIndexOf searches an element in a slice based on a predicate and returns the index and true. It returns -1 and false if the element is not found.
+
+```go
+str, index, ok := lo.FindIndexOf([]string{"a", "b", "a", "b"}, func(i string) bool {
+ return i == "b"
+})
+// "b", 1, true
+
+str, index, ok := lo.FindIndexOf([]string{"foobar"}, func(i string) bool {
+ return i == "b"
+})
+// "", -1, false
+```
+
+### FindLastIndexOf
+
+FindLastIndexOf searches an element in a slice based on a predicate and returns the index and true. It returns -1 and false if the element is not found.
+
+```go
+str, index, ok := lo.FindLastIndexOf([]string{"a", "b", "a", "b"}, func(i string) bool {
+ return i == "b"
+})
+// "b", 4, true
+
+str, index, ok := lo.FindLastIndexOf([]string{"foobar"}, func(i string) bool {
+ return i == "b"
+})
+// "", -1, false
+```
+
+### FindOrElse
+
+Search an element in a slice based on a predicate. It returns the element if found or a given fallback value otherwise.
+
+```go
+str := lo.FindOrElse([]string{"a", "b", "c", "d"}, "x", func(i string) bool {
+ return i == "b"
+})
+// "b"
+
+str := lo.FindOrElse([]string{"foobar"}, "x", func(i string) bool {
+ return i == "b"
+})
+// "x"
+```
+
+### FindKey
+
+Returns the key of the first value matching.
+
+```go
+result1, ok1 := lo.FindKey(map[string]int{"foo": 1, "bar": 2, "baz": 3}, 2)
+// "bar", true
+
+result2, ok2 := lo.FindKey(map[string]int{"foo": 1, "bar": 2, "baz": 3}, 42)
+// "", false
+
+type test struct {
+ foobar string
+}
+result3, ok3 := lo.FindKey(map[string]test{"foo": test{"foo"}, "bar": test{"bar"}, "baz": test{"baz"}}, test{"foo"})
+// "foo", true
+```
+
+### FindKeyBy
+
+Returns the key of the first element predicate returns truthy for.
+
+```go
+result1, ok1 := lo.FindKeyBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
+ return k == "foo"
+})
+// "foo", true
+
+result2, ok2 := lo.FindKeyBy(map[string]int{"foo": 1, "bar": 2, "baz": 3}, func(k string, v int) bool {
+ return false
+})
+// "", false
+```
+
+### FindUniques
+
+Returns a slice with all the unique elements of the collection. The order of result values is determined by the order they occur in the array.
+
+```go
+uniqueValues := lo.FindUniques([]int{1, 2, 2, 1, 2, 3})
+// []int{3}
+```
+
+### FindUniquesBy
+
+Returns a slice with all the unique elements of the collection. The order of result values is determined by the order they occur in the array. It accepts `iteratee` which is invoked for each element in array to generate the criterion by which uniqueness is computed.
+
+```go
+uniqueValues := lo.FindUniquesBy([]int{3, 4, 5, 6, 7}, func(i int) int {
+ return i%3
+})
+// []int{5}
+```
+
+### FindDuplicates
+
+Returns a slice with the first occurrence of each duplicated elements of the collection. The order of result values is determined by the order they occur in the array.
+
+```go
+duplicatedValues := lo.FindDuplicates([]int{1, 2, 2, 1, 2, 3})
+// []int{1, 2}
+```
+
+### FindDuplicatesBy
+
+Returns a slice with the first occurrence of each duplicated elements of the collection. The order of result values is determined by the order they occur in the array. It accepts `iteratee` which is invoked for each element in array to generate the criterion by which uniqueness is computed.
+
+```go
+duplicatedValues := lo.FindDuplicatesBy([]int{3, 4, 5, 6, 7}, func(i int) int {
+ return i%3
+})
+// []int{3, 4}
+```
+
+### Min
+
+Search the minimum value of a collection.
+
+Returns zero value when the collection is empty.
+
+```go
+min := lo.Min([]int{1, 2, 3})
+// 1
+
+min := lo.Min([]int{})
+// 0
+
+min := lo.Min([]time.Duration{time.Second, time.Hour})
+// 1s
+```
+
+### MinBy
+
+Search the minimum value of a collection using the given comparison function.
+
+If several values of the collection are equal to the smallest value, returns the first such value.
+
+Returns zero value when the collection is empty.
+
+```go
+min := lo.MinBy([]string{"s1", "string2", "s3"}, func(item string, min string) bool {
+ return len(item) < len(min)
+})
+// "s1"
+
+min := lo.MinBy([]string{}, func(item string, min string) bool {
+ return len(item) < len(min)
+})
+// ""
+```
+
+### Earliest
+
+Search the minimum time.Time of a collection.
+
+Returns zero value when the collection is empty.
+
+```go
+earliest := lo.Earliest(time.Now(), time.Time{})
+// 0001-01-01 00:00:00 +0000 UTC
+```
+
+### EarliestBy
+
+Search the minimum time.Time of a collection using the given iteratee function.
+
+Returns zero value when the collection is empty.
+
+```go
+type foo struct {
+ bar time.Time
+}
+
+earliest := lo.EarliestBy([]foo{{time.Now()}, {}}, func(i foo) time.Time {
+ return i.bar
+})
+// {bar:{2023-04-01 01:02:03 +0000 UTC}}
+```
+
+### Max
+
+Search the maximum value of a collection.
+
+Returns zero value when the collection is empty.
+
+```go
+max := lo.Max([]int{1, 2, 3})
+// 3
+
+max := lo.Max([]int{})
+// 0
+
+max := lo.Max([]time.Duration{time.Second, time.Hour})
+// 1h
+```
+
+### MaxBy
+
+Search the maximum value of a collection using the given comparison function.
+
+If several values of the collection are equal to the greatest value, returns the first such value.
+
+Returns zero value when the collection is empty.
+
+```go
+max := lo.MaxBy([]string{"string1", "s2", "string3"}, func(item string, max string) bool {
+ return len(item) > len(max)
+})
+// "string1"
+
+max := lo.MaxBy([]string{}, func(item string, max string) bool {
+ return len(item) > len(max)
+})
+// ""
+```
+
+### Latest
+
+Search the maximum time.Time of a collection.
+
+Returns zero value when the collection is empty.
+
+```go
+latest := lo.Latest([]time.Time{time.Now(), time.Time{}})
+// 2023-04-01 01:02:03 +0000 UTC
+```
+
+### LatestBy
+
+Search the maximum time.Time of a collection using the given iteratee function.
+
+Returns zero value when the collection is empty.
+
+```go
+type foo struct {
+ bar time.Time
+}
+
+latest := lo.LatestBy([]foo{{time.Now()}, {}}, func(i foo) time.Time {
+ return i.bar
+})
+// {bar:{2023-04-01 01:02:03 +0000 UTC}}
+```
+
+### First
+
+Returns the first element of a collection and check for availability of the first element.
+
+```go
+first, ok := lo.First([]int{1, 2, 3})
+// 1, true
+
+first, ok := lo.First([]int{})
+// 0, false
+```
+
+### FirstOrEmpty
+
+Returns the first element of a collection or zero value if empty.
+
+```go
+first := lo.FirstOrEmpty([]int{1, 2, 3})
+// 1
+
+first := lo.FirstOrEmpty([]int{})
+// 0
+```
+### FirstOr
+
+Returns the first element of a collection or the fallback value if empty.
+
+```go
+first := lo.FirstOr([]int{1, 2, 3}, 245)
+// 1
+
+first := lo.FirstOr([]int{}, 31)
+// 31
+```
+
+### Last
+
+Returns the last element of a collection or error if empty.
+
+```go
+last, ok := lo.Last([]int{1, 2, 3})
+// 3
+// true
+
+last, ok := lo.Last([]int{})
+// 0
+// false
+```
+
+### LastOrEmpty
+
+Returns the first element of a collection or zero value if empty.
+
+```go
+last := lo.LastOrEmpty([]int{1, 2, 3})
+// 3
+
+last := lo.LastOrEmpty([]int{})
+// 0
+```
+### LastOr
+
+Returns the first element of a collection or the fallback value if empty.
+
+```go
+last := lo.LastOr([]int{1, 2, 3}, 245)
+// 3
+
+last := lo.LastOr([]int{}, 31)
+// 31
+```
+
+### Nth
+
+Returns the element at index `nth` of collection. If `nth` is negative, the nth element from the end is returned. An error is returned when nth is out of slice bounds.
+
+```go
+nth, err := lo.Nth([]int{0, 1, 2, 3}, 2)
+// 2
+
+nth, err := lo.Nth([]int{0, 1, 2, 3}, -2)
+// 2
+```
+
+### Sample
+
+Returns a random item from collection.
+
+```go
+lo.Sample([]string{"a", "b", "c"})
+// a random string from []string{"a", "b", "c"}
+
+lo.Sample([]string{})
+// ""
+```
+
+### Samples
+
+Returns N random unique items from collection.
+
+```go
+lo.Samples([]string{"a", "b", "c"}, 3)
+// []string{"a", "b", "c"} in random order
+```
+
+### Ternary
+
+A 1 line if/else statement.
+
+```go
+result := lo.Ternary(true, "a", "b")
+// "a"
+
+result := lo.Ternary(false, "a", "b")
+// "b"
+```
+
+[[play](https://go.dev/play/p/t-D7WBL44h2)]
+
+### TernaryF
+
+A 1 line if/else statement whose options are functions.
+
+```go
+result := lo.TernaryF(true, func() string { return "a" }, func() string { return "b" })
+// "a"
+
+result := lo.TernaryF(false, func() string { return "a" }, func() string { return "b" })
+// "b"
+```
+
+Useful to avoid nil-pointer dereferencing in initializations, or avoid running unnecessary code
+
+```go
+var s *string
+
+someStr := TernaryF(s == nil, func() string { return uuid.New().String() }, func() string { return *s })
+// ef782193-c30c-4e2e-a7ae-f8ab5e125e02
+```
+
+[[play](https://go.dev/play/p/AO4VW20JoqM)]
+
+### If / ElseIf / Else
+
+```go
+result := lo.If(true, 1).
+ ElseIf(false, 2).
+ Else(3)
+// 1
+
+result := lo.If(false, 1).
+ ElseIf(true, 2).
+ Else(3)
+// 2
+
+result := lo.If(false, 1).
+ ElseIf(false, 2).
+ Else(3)
+// 3
+```
+
+Using callbacks:
+
+```go
+result := lo.IfF(true, func () int {
+ return 1
+ }).
+ ElseIfF(false, func () int {
+ return 2
+ }).
+ ElseF(func () int {
+ return 3
+ })
+// 1
+```
+
+Mixed:
+
+```go
+result := lo.IfF(true, func () int {
+ return 1
+ }).
+ Else(42)
+// 1
+```
+
+[[play](https://go.dev/play/p/WSw3ApMxhyW)]
+
+### Switch / Case / Default
+
+```go
+result := lo.Switch(1).
+ Case(1, "1").
+ Case(2, "2").
+ Default("3")
+// "1"
+
+result := lo.Switch(2).
+ Case(1, "1").
+ Case(2, "2").
+ Default("3")
+// "2"
+
+result := lo.Switch(42).
+ Case(1, "1").
+ Case(2, "2").
+ Default("3")
+// "3"
+```
+
+Using callbacks:
+
+```go
+result := lo.Switch(1).
+ CaseF(1, func() string {
+ return "1"
+ }).
+ CaseF(2, func() string {
+ return "2"
+ }).
+ DefaultF(func() string {
+ return "3"
+ })
+// "1"
+```
+
+Mixed:
+
+```go
+result := lo.Switch(1).
+ CaseF(1, func() string {
+ return "1"
+ }).
+ Default("42")
+// "1"
+```
+
+[[play](https://go.dev/play/p/TGbKUMAeRUd)]
+
+### IsNil
+
+Checks if a value is nil or if it's a reference type with a nil underlying value.
+
+```go
+var x int
+IsNil(x))
+// false
+
+var k struct{}
+IsNil(k)
+// false
+
+var i *int
+IsNil(i)
+// true
+
+var ifaceWithNilValue any = (*string)(nil)
+IsNil(ifaceWithNilValue)
+// true
+ifaceWithNilValue == nil
+// false
+```
+
+### ToPtr
+
+Returns a pointer copy of the value.
+
+```go
+ptr := lo.ToPtr("hello world")
+// *string{"hello world"}
+```
+
+### Nil
+
+Returns a nil pointer of type.
+
+```go
+ptr := lo.Nil[float64]()
+// nil
+```
+
+### EmptyableToPtr
+
+Returns a pointer copy of value if it's nonzero.
+Otherwise, returns nil pointer.
+
+```go
+ptr := lo.EmptyableToPtr(nil)
+// nil
+
+ptr := lo.EmptyableToPtr("")
+// nil
+
+ptr := lo.EmptyableToPtr([]int{})
+// *[]int{}
+
+ptr := lo.EmptyableToPtr("hello world")
+// *string{"hello world"}
+```
+
+### FromPtr
+
+Returns the pointer value or empty.
+
+```go
+str := "hello world"
+value := lo.FromPtr(&str)
+// "hello world"
+
+value := lo.FromPtr(nil)
+// ""
+```
+
+### FromPtrOr
+
+Returns the pointer value or the fallback value.
+
+```go
+str := "hello world"
+value := lo.FromPtrOr(&str, "empty")
+// "hello world"
+
+value := lo.FromPtrOr(nil, "empty")
+// "empty"
+```
+
+### ToSlicePtr
+
+Returns a slice of pointer copy of value.
+
+```go
+ptr := lo.ToSlicePtr([]string{"hello", "world"})
+// []*string{"hello", "world"}
+```
+
+### FromSlicePtr
+
+Returns a slice with the pointer values.
+Returns a zero value in case of a nil pointer element.
+
+```go
+str1 := "hello"
+str2 := "world"
+
+ptr := lo.FromSlicePtr[string]([]*string{&str1, &str2, nil})
+// []string{"hello", "world", ""}
+
+ptr := lo.Compact(
+ lo.FromSlicePtr[string]([]*string{&str1, &str2, nil}),
+)
+// []string{"hello", "world"}
+```
+
+### FromSlicePtrOr
+
+Returns a slice with the pointer values or the fallback value.
+
+```go
+str1 := "hello"
+str2 := "world"
+
+ptr := lo.FromSlicePtrOr[string]([]*string{&str1, &str2, "fallback value"})
+// []string{"hello", "world", "fallback value"}
+```
+
+### ToAnySlice
+
+Returns a slice with all elements mapped to `any` type.
+
+```go
+elements := lo.ToAnySlice([]int{1, 5, 1})
+// []any{1, 5, 1}
+```
+
+### FromAnySlice
+
+Returns an `any` slice with all elements mapped to a type. Returns false in case of type conversion failure.
+
+```go
+elements, ok := lo.FromAnySlice([]any{"foobar", 42})
+// []string{}, false
+
+elements, ok := lo.FromAnySlice([]any{"foobar", "42"})
+// []string{"foobar", "42"}, true
+```
+
+### Empty
+
+Returns an empty value.
+
+```go
+lo.Empty[int]()
+// 0
+lo.Empty[string]()
+// ""
+lo.Empty[bool]()
+// false
+```
+
+### IsEmpty
+
+Returns true if argument is a zero value.
+
+```go
+lo.IsEmpty(0)
+// true
+lo.IsEmpty(42)
+// false
+
+lo.IsEmpty("")
+// true
+lo.IsEmpty("foobar")
+// false
+
+type test struct {
+ foobar string
+}
+
+lo.IsEmpty(test{foobar: ""})
+// true
+lo.IsEmpty(test{foobar: "foobar"})
+// false
+```
+
+### IsNotEmpty
+
+Returns true if argument is a zero value.
+
+```go
+lo.IsNotEmpty(0)
+// false
+lo.IsNotEmpty(42)
+// true
+
+lo.IsNotEmpty("")
+// false
+lo.IsNotEmpty("foobar")
+// true
+
+type test struct {
+ foobar string
+}
+
+lo.IsNotEmpty(test{foobar: ""})
+// false
+lo.IsNotEmpty(test{foobar: "foobar"})
+// true
+```
+
+### Coalesce
+
+Returns the first non-empty arguments. Arguments must be comparable.
+
+```go
+result, ok := lo.Coalesce(0, 1, 2, 3)
+// 1 true
+
+result, ok := lo.Coalesce("")
+// "" false
+
+var nilStr *string
+str := "foobar"
+result, ok := lo.Coalesce(nil, nilStr, &str)
+// &"foobar" true
+```
+
+### CoalesceOrEmpty
+
+Returns the first non-empty arguments. Arguments must be comparable.
+
+```go
+result := lo.CoalesceOrEmpty(0, 1, 2, 3)
+// 1
+
+result := lo.CoalesceOrEmpty("")
+// ""
+
+var nilStr *string
+str := "foobar"
+result := lo.CoalesceOrEmpty(nil, nilStr, &str)
+// &"foobar"
+```
+
+### Partial
+
+Returns new function that, when called, has its first argument set to the provided value.
+
+```go
+add := func(x, y int) int { return x + y }
+f := lo.Partial(add, 5)
+
+f(10)
+// 15
+
+f(42)
+// 47
+```
+
+### Partial2 -> Partial5
+
+Returns new function that, when called, has its first argument set to the provided value.
+
+```go
+add := func(x, y, z int) int { return x + y + z }
+f := lo.Partial2(add, 42)
+
+f(10, 5)
+// 57
+
+f(42, -4)
+// 80
+```
+
+### Attempt
+
+Invokes a function N times until it returns valid output. Returning either the caught error or nil. When first argument is less than `1`, the function runs until a successful response is returned.
+
+```go
+iter, err := lo.Attempt(42, func(i int) error {
+ if i == 5 {
+ return nil
+ }
+
+ return fmt.Errorf("failed")
+})
+// 6
+// nil
+
+iter, err := lo.Attempt(2, func(i int) error {
+ if i == 5 {
+ return nil
+ }
+
+ return fmt.Errorf("failed")
+})
+// 2
+// error "failed"
+
+iter, err := lo.Attempt(0, func(i int) error {
+ if i < 42 {
+ return fmt.Errorf("failed")
+ }
+
+ return nil
+})
+// 43
+// nil
+```
+
+For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff).
+
+[[play](https://go.dev/play/p/3ggJZ2ZKcMj)]
+
+### AttemptWithDelay
+
+Invokes a function N times until it returns valid output, with a pause between each call. Returning either the caught error or nil.
+
+When first argument is less than `1`, the function runs until a successful response is returned.
+
+```go
+iter, duration, err := lo.AttemptWithDelay(5, 2*time.Second, func(i int, duration time.Duration) error {
+ if i == 2 {
+ return nil
+ }
+
+ return fmt.Errorf("failed")
+})
+// 3
+// ~ 4 seconds
+// nil
+```
+
+For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff).
+
+[[play](https://go.dev/play/p/tVs6CygC7m1)]
+
+### AttemptWhile
+
+Invokes a function N times until it returns valid output. Returning either the caught error or nil, and along with a bool value to identifying whether it needs invoke function continuously. It will terminate the invoke immediately if second bool value is returned with falsy value.
+
+When first argument is less than `1`, the function runs until a successful response is returned.
+
+```go
+count1, err1 := lo.AttemptWhile(5, func(i int) (error, bool) {
+ err := doMockedHTTPRequest(i)
+ if err != nil {
+ if errors.Is(err, ErrBadRequest) { // lets assume ErrBadRequest is a critical error that needs to terminate the invoke
+ return err, false // flag the second return value as false to terminate the invoke
+ }
+
+ return err, true
+ }
+
+ return nil, false
+})
+```
+
+For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff).
+
+[[play](https://go.dev/play/p/M2wVq24PaZM)]
+
+### AttemptWhileWithDelay
+
+Invokes a function N times until it returns valid output, with a pause between each call. Returning either the caught error or nil, and along with a bool value to identifying whether it needs to invoke function continuously. It will terminate the invoke immediately if second bool value is returned with falsy value.
+
+When first argument is less than `1`, the function runs until a successful response is returned.
+
+```go
+count1, time1, err1 := lo.AttemptWhileWithDelay(5, time.Millisecond, func(i int, d time.Duration) (error, bool) {
+ err := doMockedHTTPRequest(i)
+ if err != nil {
+ if errors.Is(err, ErrBadRequest) { // lets assume ErrBadRequest is a critical error that needs to terminate the invoke
+ return err, false // flag the second return value as false to terminate the invoke
+ }
+
+ return err, true
+ }
+
+ return nil, false
+})
+```
+
+For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff).
+
+[[play](https://go.dev/play/p/cfcmhvLO-nv)]
+
+### Debounce
+
+`NewDebounce` creates a debounced instance that delays invoking functions given until after wait milliseconds have elapsed, until `cancel` is called.
+
+```go
+f := func() {
+ println("Called once after 100ms when debounce stopped invoking!")
+}
+
+debounce, cancel := lo.NewDebounce(100 * time.Millisecond, f)
+for j := 0; j < 10; j++ {
+ debounce()
+}
+
+time.Sleep(1 * time.Second)
+cancel()
+```
+
+[[play](https://go.dev/play/p/mz32VMK2nqe)]
+
+### DebounceBy
+
+`NewDebounceBy` creates a debounced instance for each distinct key, that delays invoking functions given until after wait milliseconds have elapsed, until `cancel` is called.
+
+```go
+f := func(key string, count int) {
+ println(key + ": Called once after 100ms when debounce stopped invoking!")
+}
+
+debounce, cancel := lo.NewDebounceBy(100 * time.Millisecond, f)
+for j := 0; j < 10; j++ {
+ debounce("first key")
+ debounce("second key")
+}
+
+time.Sleep(1 * time.Second)
+cancel("first key")
+cancel("second key")
+```
+
+[[play](https://go.dev/play/p/d3Vpt6pxhY8)]
+
+### Synchronize
+
+Wraps the underlying callback in a mutex. It receives an optional mutex.
+
+```go
+s := lo.Synchronize()
+
+for i := 0; i < 10; i++ {
+ go s.Do(func () {
+ println("will be called sequentially")
+ })
+}
+```
+
+It is equivalent to:
+
+```go
+mu := sync.Mutex{}
+
+func foobar() {
+ mu.Lock()
+ defer mu.Unlock()
+
+ // ...
+}
+```
+
+### Async
+
+Executes a function in a goroutine and returns the result in a channel.
+
+```go
+ch := lo.Async(func() error { time.Sleep(10 * time.Second); return nil })
+// chan error (nil)
+```
+
+### Async{0->6}
+
+Executes a function in a goroutine and returns the result in a channel.
+For function with multiple return values, the results will be returned as a tuple inside the channel.
+For function without return, struct{} will be returned in the channel.
+
+```go
+ch := lo.Async0(func() { time.Sleep(10 * time.Second) })
+// chan struct{}
+
+ch := lo.Async1(func() int {
+ time.Sleep(10 * time.Second);
+ return 42
+})
+// chan int (42)
+
+ch := lo.Async2(func() (int, string) {
+ time.Sleep(10 * time.Second);
+ return 42, "Hello"
+})
+// chan lo.Tuple2[int, string] ({42, "Hello"})
+```
+
+### Transaction
+
+Implements a Saga pattern.
+
+```go
+transaction := NewTransaction().
+ Then(
+ func(state int) (int, error) {
+ fmt.Println("step 1")
+ return state + 10, nil
+ },
+ func(state int) int {
+ fmt.Println("rollback 1")
+ return state - 10
+ },
+ ).
+ Then(
+ func(state int) (int, error) {
+ fmt.Println("step 2")
+ return state + 15, nil
+ },
+ func(state int) int {
+ fmt.Println("rollback 2")
+ return state - 15
+ },
+ ).
+ Then(
+ func(state int) (int, error) {
+ fmt.Println("step 3")
+
+ if true {
+ return state, fmt.Errorf("error")
+ }
+
+ return state + 42, nil
+ },
+ func(state int) int {
+ fmt.Println("rollback 3")
+ return state - 42
+ },
+ )
+
+_, _ = transaction.Process(-5)
+
+// Output:
+// step 1
+// step 2
+// step 3
+// rollback 2
+// rollback 1
+```
+
+### WaitFor
+
+Runs periodically until a condition is validated.
+
+```go
+alwaysTrue := func(i int) bool { return true }
+alwaysFalse := func(i int) bool { return false }
+laterTrue := func(i int) bool {
+ return i > 5
+}
+
+iterations, duration, ok := lo.WaitFor(alwaysTrue, 10*time.Millisecond, 2 * time.Millisecond)
+// 1
+// 1ms
+// true
+
+iterations, duration, ok := lo.WaitFor(alwaysFalse, 10*time.Millisecond, time.Millisecond)
+// 10
+// 10ms
+// false
+
+iterations, duration, ok := lo.WaitFor(laterTrue, 10*time.Millisecond, time.Millisecond)
+// 7
+// 7ms
+// true
+
+iterations, duration, ok := lo.WaitFor(laterTrue, 10*time.Millisecond, 5*time.Millisecond)
+// 2
+// 10ms
+// false
+```
+
+
+### WaitForWithContext
+
+Runs periodically until a condition is validated or context is invalid.
+
+The condition receives also the context, so it can invalidate the process in the condition checker
+
+```go
+ctx := context.Background()
+
+alwaysTrue := func(_ context.Context, i int) bool { return true }
+alwaysFalse := func(_ context.Context, i int) bool { return false }
+laterTrue := func(_ context.Context, i int) bool {
+ return i >= 5
+}
+
+iterations, duration, ok := lo.WaitForWithContext(ctx, alwaysTrue, 10*time.Millisecond, 2 * time.Millisecond)
+// 1
+// 1ms
+// true
+
+iterations, duration, ok := lo.WaitForWithContext(ctx, alwaysFalse, 10*time.Millisecond, time.Millisecond)
+// 10
+// 10ms
+// false
+
+iterations, duration, ok := lo.WaitForWithContext(ctx, laterTrue, 10*time.Millisecond, time.Millisecond)
+// 5
+// 5ms
+// true
+
+iterations, duration, ok := lo.WaitForWithContext(ctx, laterTrue, 10*time.Millisecond, 5*time.Millisecond)
+// 2
+// 10ms
+// false
+
+expiringCtx, cancel := context.WithTimeout(ctx, 5*time.Millisecond)
+iterations, duration, ok := lo.WaitForWithContext(expiringCtx, alwaysFalse, 100*time.Millisecond, time.Millisecond)
+// 5
+// 5.1ms
+// false
+```
+
+### Validate
+
+Helper function that creates an error when a condition is not met.
+
+```go
+slice := []string{"a"}
+val := lo.Validate(len(slice) == 0, "Slice should be empty but contains %v", slice)
+// error("Slice should be empty but contains [a]")
+
+slice := []string{}
+val := lo.Validate(len(slice) == 0, "Slice should be empty but contains %v", slice)
+// nil
+```
+
+[[play](https://go.dev/play/p/vPyh51XpCBt)]
+
+### Must
+
+Wraps a function call to panics if second argument is `error` or `false`, returns the value otherwise.
+
+```go
+val := lo.Must(time.Parse("2006-01-02", "2022-01-15"))
+// 2022-01-15
+
+val := lo.Must(time.Parse("2006-01-02", "bad-value"))
+// panics
+```
+
+[[play](https://go.dev/play/p/TMoWrRp3DyC)]
+
+### Must{0->6}
+
+Must\* has the same behavior as Must, but returns multiple values.
+
+```go
+func example0() (error)
+func example1() (int, error)
+func example2() (int, string, error)
+func example3() (int, string, time.Date, error)
+func example4() (int, string, time.Date, bool, error)
+func example5() (int, string, time.Date, bool, float64, error)
+func example6() (int, string, time.Date, bool, float64, byte, error)
+
+lo.Must0(example0())
+val1 := lo.Must1(example1()) // alias to Must
+val1, val2 := lo.Must2(example2())
+val1, val2, val3 := lo.Must3(example3())
+val1, val2, val3, val4 := lo.Must4(example4())
+val1, val2, val3, val4, val5 := lo.Must5(example5())
+val1, val2, val3, val4, val5, val6 := lo.Must6(example6())
+```
+
+You can wrap functions like `func (...) (..., ok bool)`.
+
+```go
+// math.Signbit(float64) bool
+lo.Must0(math.Signbit(v))
+
+// bytes.Cut([]byte,[]byte) ([]byte, []byte, bool)
+before, after := lo.Must2(bytes.Cut(s, sep))
+```
+
+You can give context to the panic message by adding some printf-like arguments.
+
+```go
+val, ok := lo.Find(myString, func(i string) bool {
+ return i == requiredChar
+})
+lo.Must0(ok, "'%s' must always contain '%s'", myString, requiredChar)
+
+list := []int{0, 1, 2}
+item := 5
+lo.Must0(lo.Contains(list, item), "'%s' must always contain '%s'", list, item)
+...
+```
+
+[[play](https://go.dev/play/p/TMoWrRp3DyC)]
+
+### Try
+
+Calls the function and returns false in case of error and panic.
+
+```go
+ok := lo.Try(func() error {
+ panic("error")
+ return nil
+})
+// false
+
+ok := lo.Try(func() error {
+ return nil
+})
+// true
+
+ok := lo.Try(func() error {
+ return fmt.Errorf("error")
+})
+// false
+```
+
+[[play](https://go.dev/play/p/mTyyWUvn9u4)]
+
+### Try{0->6}
+
+The same behavior as `Try`, but the callback returns 2 variables.
+
+```go
+ok := lo.Try2(func() (string, error) {
+ panic("error")
+ return "", nil
+})
+// false
+```
+
+[[play](https://go.dev/play/p/mTyyWUvn9u4)]
+
+### TryOr
+
+Calls the function and return a default value in case of error and on panic.
+
+```go
+str, ok := lo.TryOr(func() (string, error) {
+ panic("error")
+ return "hello", nil
+}, "world")
+// world
+// false
+
+str, ok := lo.TryOr(func() error {
+ return "hello", nil
+}, "world")
+// hello
+// true
+
+str, ok := lo.TryOr(func() error {
+ return "hello", fmt.Errorf("error")
+}, "world")
+// world
+// false
+```
+
+[[play](https://go.dev/play/p/B4F7Wg2Zh9X)]
+
+### TryOr{0->6}
+
+The same behavior as `TryOr`, but the callback returns `X` variables.
+
+```go
+str, nbr, ok := lo.TryOr2(func() (string, int, error) {
+ panic("error")
+ return "hello", 42, nil
+}, "world", 21)
+// world
+// 21
+// false
+```
+
+[[play](https://go.dev/play/p/B4F7Wg2Zh9X)]
+
+### TryWithErrorValue
+
+The same behavior as `Try`, but also returns the value passed to panic.
+
+```go
+err, ok := lo.TryWithErrorValue(func() error {
+ panic("error")
+ return nil
+})
+// "error", false
+```
+
+[[play](https://go.dev/play/p/Kc7afQIT2Fs)]
+
+### TryCatch
+
+The same behavior as `Try`, but calls the catch function in case of error.
+
+```go
+caught := false
+
+ok := lo.TryCatch(func() error {
+ panic("error")
+ return nil
+}, func() {
+ caught = true
+})
+// false
+// caught == true
+```
+
+[[play](https://go.dev/play/p/PnOON-EqBiU)]
+
+### TryCatchWithErrorValue
+
+The same behavior as `TryWithErrorValue`, but calls the catch function in case of error.
+
+```go
+caught := false
+
+ok := lo.TryCatchWithErrorValue(func() error {
+ panic("error")
+ return nil
+}, func(val any) {
+ caught = val == "error"
+})
+// false
+// caught == true
+```
+
+[[play](https://go.dev/play/p/8Pc9gwX_GZO)]
+
+### ErrorsAs
+
+A shortcut for:
+
+```go
+err := doSomething()
+
+var rateLimitErr *RateLimitError
+if ok := errors.As(err, &rateLimitErr); ok {
+ // retry later
+}
+```
+
+1 line `lo` helper:
+
+```go
+err := doSomething()
+
+if rateLimitErr, ok := lo.ErrorsAs[*RateLimitError](err); ok {
+ // retry later
+}
+```
+
+[[play](https://go.dev/play/p/8wk5rH8UfrE)]
+
+## 🛩 Benchmark
+
+We executed a simple benchmark with a dead-simple `lo.Map` loop:
+
+See the full implementation [here](./benchmark_test.go).
+
+```go
+_ = lo.Map[int64](arr, func(x int64, i int) string {
+ return strconv.FormatInt(x, 10)
+})
+```
+
+**Result:**
+
+Here is a comparison between `lo.Map`, `lop.Map`, `go-funk` library and a simple Go `for` loop.
+
+```shell
+$ go test -benchmem -bench ./...
+goos: linux
+goarch: amd64
+pkg: github.com/samber/lo
+cpu: Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
+cpu: Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
+BenchmarkMap/lo.Map-8 8 132728237 ns/op 39998945 B/op 1000002 allocs/op
+BenchmarkMap/lop.Map-8 2 503947830 ns/op 119999956 B/op 3000007 allocs/op
+BenchmarkMap/reflect-8 2 826400560 ns/op 170326512 B/op 4000042 allocs/op
+BenchmarkMap/for-8 9 126252954 ns/op 39998674 B/op 1000001 allocs/op
+PASS
+ok github.com/samber/lo 6.657s
+```
+
+- `lo.Map` is way faster (x7) than `go-funk`, a reflection-based Map implementation.
+- `lo.Map` have the same allocation profile than `for`.
+- `lo.Map` is 4% slower than `for`.
+- `lop.Map` is slower than `lo.Map` because it implies more memory allocation and locks. `lop.Map` will be useful for long-running callbacks, such as i/o bound processing.
+- `for` beats other implementations for memory and CPU.
+
+## 🤝 Contributing
+
+- Ping me on Twitter [@samuelberthe](https://twitter.com/samuelberthe) (DMs, mentions, whatever :))
+- Fork the [project](https://github.com/samber/lo)
+- Fix [open issues](https://github.com/samber/lo/issues) or request new features
+
+Don't hesitate ;)
+
+Helper naming: helpers must be self-explanatory and respect standards (other languages, libraries...). Feel free to suggest many names in your contributions.
+
+### With Docker
+
+```bash
+docker-compose run --rm dev
+```
+
+### Without Docker
+
+```bash
+# Install some dev dependencies
+make tools
+
+# Run tests
+make test
+# or
+make watch-test
+```
+
+## 👤 Contributors
+
+![Contributors](https://contrib.rocks/image?repo=samber/lo)
+
+## 💫 Show your support
+
+Give a ⭐️ if this project helped you!
+
+[![GitHub Sponsors](https://img.shields.io/github/sponsors/samber?style=for-the-badge)](https://github.com/sponsors/samber)
+
+## 📝 License
+
+Copyright © 2022 [Samuel Berthe](https://github.com/samber).
+
+This project is under [MIT](./LICENSE) license.
diff --git a/vendor/github.com/samber/lo/channel.go b/vendor/github.com/samber/lo/channel.go
new file mode 100644
index 00000000..228705ae
--- /dev/null
+++ b/vendor/github.com/samber/lo/channel.go
@@ -0,0 +1,310 @@
+package lo
+
+import (
+ "sync"
+ "time"
+
+ "github.com/samber/lo/internal/rand"
+)
+
+type DispatchingStrategy[T any] func(msg T, index uint64, channels []<-chan T) int
+
+// ChannelDispatcher distributes messages from input channels into N child channels.
+// Close events are propagated to children.
+// Underlying channels can have a fixed buffer capacity or be unbuffered when cap is 0.
+func ChannelDispatcher[T any](stream <-chan T, count int, channelBufferCap int, strategy DispatchingStrategy[T]) []<-chan T {
+ children := createChannels[T](count, channelBufferCap)
+
+ roChildren := channelsToReadOnly(children)
+
+ go func() {
+ // propagate channel closing to children
+ defer closeChannels(children)
+
+ var i uint64 = 0
+
+ for {
+ msg, ok := <-stream
+ if !ok {
+ return
+ }
+
+ destination := strategy(msg, i, roChildren) % count
+ children[destination] <- msg
+
+ i++
+ }
+ }()
+
+ return roChildren
+}
+
+func createChannels[T any](count int, channelBufferCap int) []chan T {
+ children := make([]chan T, 0, count)
+
+ for i := 0; i < count; i++ {
+ children = append(children, make(chan T, channelBufferCap))
+ }
+
+ return children
+}
+
+func channelsToReadOnly[T any](children []chan T) []<-chan T {
+ roChildren := make([]<-chan T, 0, len(children))
+
+ for i := range children {
+ roChildren = append(roChildren, children[i])
+ }
+
+ return roChildren
+}
+
+func closeChannels[T any](children []chan T) {
+ for i := 0; i < len(children); i++ {
+ close(children[i])
+ }
+}
+
+func channelIsNotFull[T any](ch <-chan T) bool {
+ return cap(ch) == 0 || len(ch) < cap(ch)
+}
+
+// DispatchingStrategyRoundRobin distributes messages in a rotating sequential manner.
+// If the channel capacity is exceeded, the next channel will be selected and so on.
+func DispatchingStrategyRoundRobin[T any](msg T, index uint64, channels []<-chan T) int {
+ for {
+ i := int(index % uint64(len(channels)))
+ if channelIsNotFull(channels[i]) {
+ return i
+ }
+
+ index++
+ time.Sleep(10 * time.Microsecond) // prevent CPU from burning 🔥
+ }
+}
+
+// DispatchingStrategyRandom distributes messages in a random manner.
+// If the channel capacity is exceeded, another random channel will be selected and so on.
+func DispatchingStrategyRandom[T any](msg T, index uint64, channels []<-chan T) int {
+ for {
+ i := rand.IntN(len(channels))
+ if channelIsNotFull(channels[i]) {
+ return i
+ }
+
+ time.Sleep(10 * time.Microsecond) // prevent CPU from burning 🔥
+ }
+}
+
+// DispatchingStrategyWeightedRandom distributes messages in a weighted manner.
+// If the channel capacity is exceeded, another random channel will be selected and so on.
+func DispatchingStrategyWeightedRandom[T any](weights []int) DispatchingStrategy[T] {
+ seq := []int{}
+
+ for i := 0; i < len(weights); i++ {
+ for j := 0; j < weights[i]; j++ {
+ seq = append(seq, i)
+ }
+ }
+
+ return func(msg T, index uint64, channels []<-chan T) int {
+ for {
+ i := seq[rand.IntN(len(seq))]
+ if channelIsNotFull(channels[i]) {
+ return i
+ }
+
+ time.Sleep(10 * time.Microsecond) // prevent CPU from burning 🔥
+ }
+ }
+}
+
+// DispatchingStrategyFirst distributes messages in the first non-full channel.
+// If the capacity of the first channel is exceeded, the second channel will be selected and so on.
+func DispatchingStrategyFirst[T any](msg T, index uint64, channels []<-chan T) int {
+ for {
+ for i := range channels {
+ if channelIsNotFull(channels[i]) {
+ return i
+ }
+ }
+
+ time.Sleep(10 * time.Microsecond) // prevent CPU from burning 🔥
+ }
+}
+
+// DispatchingStrategyLeast distributes messages in the emptiest channel.
+func DispatchingStrategyLeast[T any](msg T, index uint64, channels []<-chan T) int {
+ seq := Range(len(channels))
+
+ return MinBy(seq, func(item int, min int) bool {
+ return len(channels[item]) < len(channels[min])
+ })
+}
+
+// DispatchingStrategyMost distributes messages in the fullest channel.
+// If the channel capacity is exceeded, the next channel will be selected and so on.
+func DispatchingStrategyMost[T any](msg T, index uint64, channels []<-chan T) int {
+ seq := Range(len(channels))
+
+ return MaxBy(seq, func(item int, max int) bool {
+ return len(channels[item]) > len(channels[max]) && channelIsNotFull(channels[item])
+ })
+}
+
+// SliceToChannel returns a read-only channels of collection elements.
+func SliceToChannel[T any](bufferSize int, collection []T) <-chan T {
+ ch := make(chan T, bufferSize)
+
+ go func() {
+ for i := range collection {
+ ch <- collection[i]
+ }
+
+ close(ch)
+ }()
+
+ return ch
+}
+
+// ChannelToSlice returns a slice built from channels items. Blocks until channel closes.
+func ChannelToSlice[T any](ch <-chan T) []T {
+ collection := []T{}
+
+ for item := range ch {
+ collection = append(collection, item)
+ }
+
+ return collection
+}
+
+// Generator implements the generator design pattern.
+func Generator[T any](bufferSize int, generator func(yield func(T))) <-chan T {
+ ch := make(chan T, bufferSize)
+
+ go func() {
+ // WARNING: infinite loop
+ generator(func(t T) {
+ ch <- t
+ })
+
+ close(ch)
+ }()
+
+ return ch
+}
+
+// Buffer creates a slice of n elements from a channel. Returns the slice and the slice length.
+// @TODO: we should probably provide an helper that reuse the same buffer.
+func Buffer[T any](ch <-chan T, size int) (collection []T, length int, readTime time.Duration, ok bool) {
+ buffer := make([]T, 0, size)
+ index := 0
+ now := time.Now()
+
+ for ; index < size; index++ {
+ item, ok := <-ch
+ if !ok {
+ return buffer, index, time.Since(now), false
+ }
+
+ buffer = append(buffer, item)
+ }
+
+ return buffer, index, time.Since(now), true
+}
+
+// Batch creates a slice of n elements from a channel. Returns the slice and the slice length.
+//
+// Deprecated: Use [Buffer] instead.
+func Batch[T any](ch <-chan T, size int) (collection []T, length int, readTime time.Duration, ok bool) {
+ return Buffer(ch, size)
+}
+
+// BufferWithTimeout creates a slice of n elements from a channel, with timeout. Returns the slice and the slice length.
+// @TODO: we should probably provide an helper that reuse the same buffer.
+func BufferWithTimeout[T any](ch <-chan T, size int, timeout time.Duration) (collection []T, length int, readTime time.Duration, ok bool) {
+ expire := time.NewTimer(timeout)
+ defer expire.Stop()
+
+ buffer := make([]T, 0, size)
+ index := 0
+ now := time.Now()
+
+ for ; index < size; index++ {
+ select {
+ case item, ok := <-ch:
+ if !ok {
+ return buffer, index, time.Since(now), false
+ }
+
+ buffer = append(buffer, item)
+
+ case <-expire.C:
+ return buffer, index, time.Since(now), true
+ }
+ }
+
+ return buffer, index, time.Since(now), true
+}
+
+// BatchWithTimeout creates a slice of n elements from a channel, with timeout. Returns the slice and the slice length.
+//
+// Deprecated: Use [BufferWithTimeout] instead.
+func BatchWithTimeout[T any](ch <-chan T, size int, timeout time.Duration) (collection []T, length int, readTime time.Duration, ok bool) {
+ return BufferWithTimeout(ch, size, timeout)
+}
+
+// FanIn collects messages from multiple input channels into a single buffered channel.
+// Output messages has no priority. When all upstream channels reach EOF, downstream channel closes.
+func FanIn[T any](channelBufferCap int, upstreams ...<-chan T) <-chan T {
+ out := make(chan T, channelBufferCap)
+ var wg sync.WaitGroup
+
+ // Start an output goroutine for each input channel in upstreams.
+ wg.Add(len(upstreams))
+ for i := range upstreams {
+ go func(index int) {
+ for n := range upstreams[index] {
+ out <- n
+ }
+ wg.Done()
+ }(i)
+ }
+
+ // Start a goroutine to close out once all the output goroutines are done.
+ go func() {
+ wg.Wait()
+ close(out)
+ }()
+ return out
+}
+
+// ChannelMerge collects messages from multiple input channels into a single buffered channel.
+// Output messages has no priority. When all upstream channels reach EOF, downstream channel closes.
+//
+// Deprecated: Use [FanIn] instead.
+func ChannelMerge[T any](channelBufferCap int, upstreams ...<-chan T) <-chan T {
+ return FanIn(channelBufferCap, upstreams...)
+}
+
+// FanOut broadcasts all the upstream messages to multiple downstream channels.
+// When upstream channel reach EOF, downstream channels close. If any downstream
+// channels is full, broadcasting is paused.
+func FanOut[T any](count int, channelsBufferCap int, upstream <-chan T) []<-chan T {
+ downstreams := createChannels[T](count, channelsBufferCap)
+
+ go func() {
+ for msg := range upstream {
+ for i := range downstreams {
+ downstreams[i] <- msg
+ }
+ }
+
+ // Close out once all the output goroutines are done.
+ for i := range downstreams {
+ close(downstreams[i])
+ }
+ }()
+
+ return channelsToReadOnly(downstreams)
+}
diff --git a/vendor/github.com/samber/lo/concurrency.go b/vendor/github.com/samber/lo/concurrency.go
new file mode 100644
index 00000000..a2ebbce2
--- /dev/null
+++ b/vendor/github.com/samber/lo/concurrency.go
@@ -0,0 +1,136 @@
+package lo
+
+import (
+ "context"
+ "sync"
+ "time"
+)
+
+type synchronize struct {
+ locker sync.Locker
+}
+
+func (s *synchronize) Do(cb func()) {
+ s.locker.Lock()
+ Try0(cb)
+ s.locker.Unlock()
+}
+
+// Synchronize wraps the underlying callback in a mutex. It receives an optional mutex.
+func Synchronize(opt ...sync.Locker) *synchronize {
+ if len(opt) > 1 {
+ panic("unexpected arguments")
+ } else if len(opt) == 0 {
+ opt = append(opt, &sync.Mutex{})
+ }
+
+ return &synchronize{
+ locker: opt[0],
+ }
+}
+
+// Async executes a function in a goroutine and returns the result in a channel.
+func Async[A any](f func() A) <-chan A {
+ ch := make(chan A, 1)
+ go func() {
+ ch <- f()
+ }()
+ return ch
+}
+
+// Async0 executes a function in a goroutine and returns a channel set once the function finishes.
+func Async0(f func()) <-chan struct{} {
+ ch := make(chan struct{}, 1)
+ go func() {
+ f()
+ ch <- struct{}{}
+ }()
+ return ch
+}
+
+// Async1 is an alias to Async.
+func Async1[A any](f func() A) <-chan A {
+ return Async(f)
+}
+
+// Async2 has the same behavior as Async, but returns the 2 results as a tuple inside the channel.
+func Async2[A, B any](f func() (A, B)) <-chan Tuple2[A, B] {
+ ch := make(chan Tuple2[A, B], 1)
+ go func() {
+ ch <- T2(f())
+ }()
+ return ch
+}
+
+// Async3 has the same behavior as Async, but returns the 3 results as a tuple inside the channel.
+func Async3[A, B, C any](f func() (A, B, C)) <-chan Tuple3[A, B, C] {
+ ch := make(chan Tuple3[A, B, C], 1)
+ go func() {
+ ch <- T3(f())
+ }()
+ return ch
+}
+
+// Async4 has the same behavior as Async, but returns the 4 results as a tuple inside the channel.
+func Async4[A, B, C, D any](f func() (A, B, C, D)) <-chan Tuple4[A, B, C, D] {
+ ch := make(chan Tuple4[A, B, C, D], 1)
+ go func() {
+ ch <- T4(f())
+ }()
+ return ch
+}
+
+// Async5 has the same behavior as Async, but returns the 5 results as a tuple inside the channel.
+func Async5[A, B, C, D, E any](f func() (A, B, C, D, E)) <-chan Tuple5[A, B, C, D, E] {
+ ch := make(chan Tuple5[A, B, C, D, E], 1)
+ go func() {
+ ch <- T5(f())
+ }()
+ return ch
+}
+
+// Async6 has the same behavior as Async, but returns the 6 results as a tuple inside the channel.
+func Async6[A, B, C, D, E, F any](f func() (A, B, C, D, E, F)) <-chan Tuple6[A, B, C, D, E, F] {
+ ch := make(chan Tuple6[A, B, C, D, E, F], 1)
+ go func() {
+ ch <- T6(f())
+ }()
+ return ch
+}
+
+// WaitFor runs periodically until a condition is validated.
+func WaitFor(condition func(i int) bool, timeout time.Duration, heartbeatDelay time.Duration) (totalIterations int, elapsed time.Duration, conditionFound bool) {
+ conditionWithContext := func(_ context.Context, currentIteration int) bool {
+ return condition(currentIteration)
+ }
+ return WaitForWithContext(context.Background(), conditionWithContext, timeout, heartbeatDelay)
+}
+
+// WaitForWithContext runs periodically until a condition is validated or context is canceled.
+func WaitForWithContext(ctx context.Context, condition func(ctx context.Context, currentIteration int) bool, timeout time.Duration, heartbeatDelay time.Duration) (totalIterations int, elapsed time.Duration, conditionFound bool) {
+ start := time.Now()
+
+ if ctx.Err() != nil {
+ return totalIterations, time.Since(start), false
+ }
+
+ ctx, cleanCtx := context.WithTimeout(ctx, timeout)
+ ticker := time.NewTicker(heartbeatDelay)
+
+ defer func() {
+ cleanCtx()
+ ticker.Stop()
+ }()
+
+ for {
+ select {
+ case <-ctx.Done():
+ return totalIterations, time.Since(start), false
+ case <-ticker.C:
+ totalIterations++
+ if condition(ctx, totalIterations-1) {
+ return totalIterations, time.Since(start), true
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/samber/lo/condition.go b/vendor/github.com/samber/lo/condition.go
new file mode 100644
index 00000000..1d4e75d2
--- /dev/null
+++ b/vendor/github.com/samber/lo/condition.go
@@ -0,0 +1,150 @@
+package lo
+
+// Ternary is a 1 line if/else statement.
+// Play: https://go.dev/play/p/t-D7WBL44h2
+func Ternary[T any](condition bool, ifOutput T, elseOutput T) T {
+ if condition {
+ return ifOutput
+ }
+
+ return elseOutput
+}
+
+// TernaryF is a 1 line if/else statement whose options are functions
+// Play: https://go.dev/play/p/AO4VW20JoqM
+func TernaryF[T any](condition bool, ifFunc func() T, elseFunc func() T) T {
+ if condition {
+ return ifFunc()
+ }
+
+ return elseFunc()
+}
+
+type ifElse[T any] struct {
+ result T
+ done bool
+}
+
+// If.
+// Play: https://go.dev/play/p/WSw3ApMxhyW
+func If[T any](condition bool, result T) *ifElse[T] {
+ if condition {
+ return &ifElse[T]{result, true}
+ }
+
+ var t T
+ return &ifElse[T]{t, false}
+}
+
+// IfF.
+// Play: https://go.dev/play/p/WSw3ApMxhyW
+func IfF[T any](condition bool, resultF func() T) *ifElse[T] {
+ if condition {
+ return &ifElse[T]{resultF(), true}
+ }
+
+ var t T
+ return &ifElse[T]{t, false}
+}
+
+// ElseIf.
+// Play: https://go.dev/play/p/WSw3ApMxhyW
+func (i *ifElse[T]) ElseIf(condition bool, result T) *ifElse[T] {
+ if !i.done && condition {
+ i.result = result
+ i.done = true
+ }
+
+ return i
+}
+
+// ElseIfF.
+// Play: https://go.dev/play/p/WSw3ApMxhyW
+func (i *ifElse[T]) ElseIfF(condition bool, resultF func() T) *ifElse[T] {
+ if !i.done && condition {
+ i.result = resultF()
+ i.done = true
+ }
+
+ return i
+}
+
+// Else.
+// Play: https://go.dev/play/p/WSw3ApMxhyW
+func (i *ifElse[T]) Else(result T) T {
+ if i.done {
+ return i.result
+ }
+
+ return result
+}
+
+// ElseF.
+// Play: https://go.dev/play/p/WSw3ApMxhyW
+func (i *ifElse[T]) ElseF(resultF func() T) T {
+ if i.done {
+ return i.result
+ }
+
+ return resultF()
+}
+
+type switchCase[T comparable, R any] struct {
+ predicate T
+ result R
+ done bool
+}
+
+// Switch is a pure functional switch/case/default statement.
+// Play: https://go.dev/play/p/TGbKUMAeRUd
+func Switch[T comparable, R any](predicate T) *switchCase[T, R] {
+ var result R
+
+ return &switchCase[T, R]{
+ predicate,
+ result,
+ false,
+ }
+}
+
+// Case.
+// Play: https://go.dev/play/p/TGbKUMAeRUd
+func (s *switchCase[T, R]) Case(val T, result R) *switchCase[T, R] {
+ if !s.done && s.predicate == val {
+ s.result = result
+ s.done = true
+ }
+
+ return s
+}
+
+// CaseF.
+// Play: https://go.dev/play/p/TGbKUMAeRUd
+func (s *switchCase[T, R]) CaseF(val T, cb func() R) *switchCase[T, R] {
+ if !s.done && s.predicate == val {
+ s.result = cb()
+ s.done = true
+ }
+
+ return s
+}
+
+// Default.
+// Play: https://go.dev/play/p/TGbKUMAeRUd
+func (s *switchCase[T, R]) Default(result R) R {
+ if !s.done {
+ s.result = result
+ }
+
+ return s.result
+}
+
+// DefaultF.
+// Play: https://go.dev/play/p/TGbKUMAeRUd
+func (s *switchCase[T, R]) DefaultF(cb func() R) R {
+ if !s.done {
+ s.result = cb()
+ }
+
+ return s.result
+}
diff --git a/vendor/github.com/samber/lo/constraints.go b/vendor/github.com/samber/lo/constraints.go
new file mode 100644
index 00000000..c1f35296
--- /dev/null
+++ b/vendor/github.com/samber/lo/constraints.go
@@ -0,0 +1,6 @@
+package lo
+
+// Clonable defines a constraint of types having Clone() T method.
+type Clonable[T any] interface {
+ Clone() T
+}
diff --git a/vendor/github.com/samber/lo/errors.go b/vendor/github.com/samber/lo/errors.go
new file mode 100644
index 00000000..e63bf5d8
--- /dev/null
+++ b/vendor/github.com/samber/lo/errors.go
@@ -0,0 +1,354 @@
+package lo
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+)
+
+// Validate is a helper that creates an error when a condition is not met.
+// Play: https://go.dev/play/p/vPyh51XpCBt
+func Validate(ok bool, format string, args ...any) error {
+ if !ok {
+ return fmt.Errorf(fmt.Sprintf(format, args...))
+ }
+ return nil
+}
+
+func messageFromMsgAndArgs(msgAndArgs ...any) string {
+ if len(msgAndArgs) == 1 {
+ if msgAsStr, ok := msgAndArgs[0].(string); ok {
+ return msgAsStr
+ }
+ return fmt.Sprintf("%+v", msgAndArgs[0])
+ }
+ if len(msgAndArgs) > 1 {
+ return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
+ }
+ return ""
+}
+
+// must panics if err is error or false.
+func must(err any, messageArgs ...any) {
+ if err == nil {
+ return
+ }
+
+ switch e := err.(type) {
+ case bool:
+ if !e {
+ message := messageFromMsgAndArgs(messageArgs...)
+ if message == "" {
+ message = "not ok"
+ }
+
+ panic(message)
+ }
+
+ case error:
+ message := messageFromMsgAndArgs(messageArgs...)
+ if message != "" {
+ panic(message + ": " + e.Error())
+ } else {
+ panic(e.Error())
+ }
+
+ default:
+ panic("must: invalid err type '" + reflect.TypeOf(err).Name() + "', should either be a bool or an error")
+ }
+}
+
+// Must is a helper that wraps a call to a function returning a value and an error
+// and panics if err is error or false.
+// Play: https://go.dev/play/p/TMoWrRp3DyC
+func Must[T any](val T, err any, messageArgs ...any) T {
+ must(err, messageArgs...)
+ return val
+}
+
+// Must0 has the same behavior as Must, but callback returns no variable.
+// Play: https://go.dev/play/p/TMoWrRp3DyC
+func Must0(err any, messageArgs ...any) {
+ must(err, messageArgs...)
+}
+
+// Must1 is an alias to Must
+// Play: https://go.dev/play/p/TMoWrRp3DyC
+func Must1[T any](val T, err any, messageArgs ...any) T {
+ return Must(val, err, messageArgs...)
+}
+
+// Must2 has the same behavior as Must, but callback returns 2 variables.
+// Play: https://go.dev/play/p/TMoWrRp3DyC
+func Must2[T1, T2 any](val1 T1, val2 T2, err any, messageArgs ...any) (T1, T2) {
+ must(err, messageArgs...)
+ return val1, val2
+}
+
+// Must3 has the same behavior as Must, but callback returns 3 variables.
+// Play: https://go.dev/play/p/TMoWrRp3DyC
+func Must3[T1, T2, T3 any](val1 T1, val2 T2, val3 T3, err any, messageArgs ...any) (T1, T2, T3) {
+ must(err, messageArgs...)
+ return val1, val2, val3
+}
+
+// Must4 has the same behavior as Must, but callback returns 4 variables.
+// Play: https://go.dev/play/p/TMoWrRp3DyC
+func Must4[T1, T2, T3, T4 any](val1 T1, val2 T2, val3 T3, val4 T4, err any, messageArgs ...any) (T1, T2, T3, T4) {
+ must(err, messageArgs...)
+ return val1, val2, val3, val4
+}
+
+// Must5 has the same behavior as Must, but callback returns 5 variables.
+// Play: https://go.dev/play/p/TMoWrRp3DyC
+func Must5[T1, T2, T3, T4, T5 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, err any, messageArgs ...any) (T1, T2, T3, T4, T5) {
+ must(err, messageArgs...)
+ return val1, val2, val3, val4, val5
+}
+
+// Must6 has the same behavior as Must, but callback returns 6 variables.
+// Play: https://go.dev/play/p/TMoWrRp3DyC
+func Must6[T1, T2, T3, T4, T5, T6 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, val6 T6, err any, messageArgs ...any) (T1, T2, T3, T4, T5, T6) {
+ must(err, messageArgs...)
+ return val1, val2, val3, val4, val5, val6
+}
+
+// Try calls the function and return false in case of error.
+func Try(callback func() error) (ok bool) {
+ ok = true
+
+ defer func() {
+ if r := recover(); r != nil {
+ ok = false
+ }
+ }()
+
+ err := callback()
+ if err != nil {
+ ok = false
+ }
+
+ return
+}
+
+// Try0 has the same behavior as Try, but callback returns no variable.
+// Play: https://go.dev/play/p/mTyyWUvn9u4
+func Try0(callback func()) bool {
+ return Try(func() error {
+ callback()
+ return nil
+ })
+}
+
+// Try1 is an alias to Try.
+// Play: https://go.dev/play/p/mTyyWUvn9u4
+func Try1(callback func() error) bool {
+ return Try(callback)
+}
+
+// Try2 has the same behavior as Try, but callback returns 2 variables.
+// Play: https://go.dev/play/p/mTyyWUvn9u4
+func Try2[T any](callback func() (T, error)) bool {
+ return Try(func() error {
+ _, err := callback()
+ return err
+ })
+}
+
+// Try3 has the same behavior as Try, but callback returns 3 variables.
+// Play: https://go.dev/play/p/mTyyWUvn9u4
+func Try3[T, R any](callback func() (T, R, error)) bool {
+ return Try(func() error {
+ _, _, err := callback()
+ return err
+ })
+}
+
+// Try4 has the same behavior as Try, but callback returns 4 variables.
+// Play: https://go.dev/play/p/mTyyWUvn9u4
+func Try4[T, R, S any](callback func() (T, R, S, error)) bool {
+ return Try(func() error {
+ _, _, _, err := callback()
+ return err
+ })
+}
+
+// Try5 has the same behavior as Try, but callback returns 5 variables.
+// Play: https://go.dev/play/p/mTyyWUvn9u4
+func Try5[T, R, S, Q any](callback func() (T, R, S, Q, error)) bool {
+ return Try(func() error {
+ _, _, _, _, err := callback()
+ return err
+ })
+}
+
+// Try6 has the same behavior as Try, but callback returns 6 variables.
+// Play: https://go.dev/play/p/mTyyWUvn9u4
+func Try6[T, R, S, Q, U any](callback func() (T, R, S, Q, U, error)) bool {
+ return Try(func() error {
+ _, _, _, _, _, err := callback()
+ return err
+ })
+}
+
+// TryOr has the same behavior as Must, but returns a default value in case of error.
+// Play: https://go.dev/play/p/B4F7Wg2Zh9X
+func TryOr[A any](callback func() (A, error), fallbackA A) (A, bool) {
+ return TryOr1(callback, fallbackA)
+}
+
+// TryOr1 has the same behavior as Must, but returns a default value in case of error.
+// Play: https://go.dev/play/p/B4F7Wg2Zh9X
+func TryOr1[A any](callback func() (A, error), fallbackA A) (A, bool) {
+ ok := false
+
+ Try0(func() {
+ a, err := callback()
+ if err == nil {
+ fallbackA = a
+ ok = true
+ }
+ })
+
+ return fallbackA, ok
+}
+
+// TryOr2 has the same behavior as Must, but returns a default value in case of error.
+// Play: https://go.dev/play/p/B4F7Wg2Zh9X
+func TryOr2[A, B any](callback func() (A, B, error), fallbackA A, fallbackB B) (A, B, bool) {
+ ok := false
+
+ Try0(func() {
+ a, b, err := callback()
+ if err == nil {
+ fallbackA = a
+ fallbackB = b
+ ok = true
+ }
+ })
+
+ return fallbackA, fallbackB, ok
+}
+
+// TryOr3 has the same behavior as Must, but returns a default value in case of error.
+// Play: https://go.dev/play/p/B4F7Wg2Zh9X
+func TryOr3[A, B, C any](callback func() (A, B, C, error), fallbackA A, fallbackB B, fallbackC C) (A, B, C, bool) {
+ ok := false
+
+ Try0(func() {
+ a, b, c, err := callback()
+ if err == nil {
+ fallbackA = a
+ fallbackB = b
+ fallbackC = c
+ ok = true
+ }
+ })
+
+ return fallbackA, fallbackB, fallbackC, ok
+}
+
+// TryOr4 has the same behavior as Must, but returns a default value in case of error.
+// Play: https://go.dev/play/p/B4F7Wg2Zh9X
+func TryOr4[A, B, C, D any](callback func() (A, B, C, D, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D) (A, B, C, D, bool) {
+ ok := false
+
+ Try0(func() {
+ a, b, c, d, err := callback()
+ if err == nil {
+ fallbackA = a
+ fallbackB = b
+ fallbackC = c
+ fallbackD = d
+ ok = true
+ }
+ })
+
+ return fallbackA, fallbackB, fallbackC, fallbackD, ok
+}
+
+// TryOr5 has the same behavior as Must, but returns a default value in case of error.
+// Play: https://go.dev/play/p/B4F7Wg2Zh9X
+func TryOr5[A, B, C, D, E any](callback func() (A, B, C, D, E, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D, fallbackE E) (A, B, C, D, E, bool) {
+ ok := false
+
+ Try0(func() {
+ a, b, c, d, e, err := callback()
+ if err == nil {
+ fallbackA = a
+ fallbackB = b
+ fallbackC = c
+ fallbackD = d
+ fallbackE = e
+ ok = true
+ }
+ })
+
+ return fallbackA, fallbackB, fallbackC, fallbackD, fallbackE, ok
+}
+
+// TryOr6 has the same behavior as Must, but returns a default value in case of error.
+// Play: https://go.dev/play/p/B4F7Wg2Zh9X
+func TryOr6[A, B, C, D, E, F any](callback func() (A, B, C, D, E, F, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D, fallbackE E, fallbackF F) (A, B, C, D, E, F, bool) {
+ ok := false
+
+ Try0(func() {
+ a, b, c, d, e, f, err := callback()
+ if err == nil {
+ fallbackA = a
+ fallbackB = b
+ fallbackC = c
+ fallbackD = d
+ fallbackE = e
+ fallbackF = f
+ ok = true
+ }
+ })
+
+ return fallbackA, fallbackB, fallbackC, fallbackD, fallbackE, fallbackF, ok
+}
+
+// TryWithErrorValue has the same behavior as Try, but also returns value passed to panic.
+// Play: https://go.dev/play/p/Kc7afQIT2Fs
+func TryWithErrorValue(callback func() error) (errorValue any, ok bool) {
+ ok = true
+
+ defer func() {
+ if r := recover(); r != nil {
+ ok = false
+ errorValue = r
+ }
+ }()
+
+ err := callback()
+ if err != nil {
+ ok = false
+ errorValue = err
+ }
+
+ return
+}
+
+// TryCatch has the same behavior as Try, but calls the catch function in case of error.
+// Play: https://go.dev/play/p/PnOON-EqBiU
+func TryCatch(callback func() error, catch func()) {
+ if !Try(callback) {
+ catch()
+ }
+}
+
+// TryCatchWithErrorValue has the same behavior as TryWithErrorValue, but calls the catch function in case of error.
+// Play: https://go.dev/play/p/8Pc9gwX_GZO
+func TryCatchWithErrorValue(callback func() error, catch func(any)) {
+ if err, ok := TryWithErrorValue(callback); !ok {
+ catch(err)
+ }
+}
+
+// ErrorsAs is a shortcut for errors.As(err, &&T).
+// Play: https://go.dev/play/p/8wk5rH8UfrE
+func ErrorsAs[T error](err error) (T, bool) {
+ var t T
+ ok := errors.As(err, &t)
+ return t, ok
+}
diff --git a/vendor/github.com/samber/lo/find.go b/vendor/github.com/samber/lo/find.go
new file mode 100644
index 00000000..ea577ae2
--- /dev/null
+++ b/vendor/github.com/samber/lo/find.go
@@ -0,0 +1,507 @@
+package lo
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/samber/lo/internal/constraints"
+ "github.com/samber/lo/internal/rand"
+)
+
+// IndexOf returns the index at which the first occurrence of a value is found in an array or return -1
+// if the value cannot be found.
+func IndexOf[T comparable](collection []T, element T) int {
+ for i := range collection {
+ if collection[i] == element {
+ return i
+ }
+ }
+
+ return -1
+}
+
+// LastIndexOf returns the index at which the last occurrence of a value is found in an array or return -1
+// if the value cannot be found.
+func LastIndexOf[T comparable](collection []T, element T) int {
+ length := len(collection)
+
+ for i := length - 1; i >= 0; i-- {
+ if collection[i] == element {
+ return i
+ }
+ }
+
+ return -1
+}
+
+// Find search an element in a slice based on a predicate. It returns element and true if element was found.
+func Find[T any](collection []T, predicate func(item T) bool) (T, bool) {
+ for i := range collection {
+ if predicate(collection[i]) {
+ return collection[i], true
+ }
+ }
+
+ var result T
+ return result, false
+}
+
+// FindIndexOf searches an element in a slice based on a predicate and returns the index and true.
+// It returns -1 and false if the element is not found.
+func FindIndexOf[T any](collection []T, predicate func(item T) bool) (T, int, bool) {
+ for i := range collection {
+ if predicate(collection[i]) {
+ return collection[i], i, true
+ }
+ }
+
+ var result T
+ return result, -1, false
+}
+
+// FindLastIndexOf searches last element in a slice based on a predicate and returns the index and true.
+// It returns -1 and false if the element is not found.
+func FindLastIndexOf[T any](collection []T, predicate func(item T) bool) (T, int, bool) {
+ length := len(collection)
+
+ for i := length - 1; i >= 0; i-- {
+ if predicate(collection[i]) {
+ return collection[i], i, true
+ }
+ }
+
+ var result T
+ return result, -1, false
+}
+
+// FindOrElse search an element in a slice based on a predicate. It returns the element if found or a given fallback value otherwise.
+func FindOrElse[T any](collection []T, fallback T, predicate func(item T) bool) T {
+ for i := range collection {
+ if predicate(collection[i]) {
+ return collection[i]
+ }
+ }
+
+ return fallback
+}
+
+// FindKey returns the key of the first value matching.
+func FindKey[K comparable, V comparable](object map[K]V, value V) (K, bool) {
+ for k := range object {
+ if object[k] == value {
+ return k, true
+ }
+ }
+
+ return Empty[K](), false
+}
+
+// FindKeyBy returns the key of the first element predicate returns truthy for.
+func FindKeyBy[K comparable, V any](object map[K]V, predicate func(key K, value V) bool) (K, bool) {
+ for k := range object {
+ if predicate(k, object[k]) {
+ return k, true
+ }
+ }
+
+ return Empty[K](), false
+}
+
+// FindUniques returns a slice with all the unique elements of the collection.
+// The order of result values is determined by the order they occur in the collection.
+func FindUniques[T comparable, Slice ~[]T](collection Slice) Slice {
+ isDupl := make(map[T]bool, len(collection))
+
+ for i := range collection {
+ duplicated, ok := isDupl[collection[i]]
+ if !ok {
+ isDupl[collection[i]] = false
+ } else if !duplicated {
+ isDupl[collection[i]] = true
+ }
+ }
+
+ result := make(Slice, 0, len(collection)-len(isDupl))
+
+ for i := range collection {
+ if duplicated := isDupl[collection[i]]; !duplicated {
+ result = append(result, collection[i])
+ }
+ }
+
+ return result
+}
+
+// FindUniquesBy returns a slice with all the unique elements of the collection.
+// The order of result values is determined by the order they occur in the array. It accepts `iteratee` which is
+// invoked for each element in array to generate the criterion by which uniqueness is computed.
+func FindUniquesBy[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) U) Slice {
+ isDupl := make(map[U]bool, len(collection))
+
+ for i := range collection {
+ key := iteratee(collection[i])
+
+ duplicated, ok := isDupl[key]
+ if !ok {
+ isDupl[key] = false
+ } else if !duplicated {
+ isDupl[key] = true
+ }
+ }
+
+ result := make(Slice, 0, len(collection)-len(isDupl))
+
+ for i := range collection {
+ key := iteratee(collection[i])
+
+ if duplicated := isDupl[key]; !duplicated {
+ result = append(result, collection[i])
+ }
+ }
+
+ return result
+}
+
+// FindDuplicates returns a slice with the first occurrence of each duplicated elements of the collection.
+// The order of result values is determined by the order they occur in the collection.
+func FindDuplicates[T comparable, Slice ~[]T](collection Slice) Slice {
+ isDupl := make(map[T]bool, len(collection))
+
+ for i := range collection {
+ duplicated, ok := isDupl[collection[i]]
+ if !ok {
+ isDupl[collection[i]] = false
+ } else if !duplicated {
+ isDupl[collection[i]] = true
+ }
+ }
+
+ result := make(Slice, 0, len(collection)-len(isDupl))
+
+ for i := range collection {
+ if duplicated := isDupl[collection[i]]; duplicated {
+ result = append(result, collection[i])
+ isDupl[collection[i]] = false
+ }
+ }
+
+ return result
+}
+
+// FindDuplicatesBy returns a slice with the first occurrence of each duplicated elements of the collection.
+// The order of result values is determined by the order they occur in the array. It accepts `iteratee` which is
+// invoked for each element in array to generate the criterion by which uniqueness is computed.
+func FindDuplicatesBy[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) U) Slice {
+ isDupl := make(map[U]bool, len(collection))
+
+ for i := range collection {
+ key := iteratee(collection[i])
+
+ duplicated, ok := isDupl[key]
+ if !ok {
+ isDupl[key] = false
+ } else if !duplicated {
+ isDupl[key] = true
+ }
+ }
+
+ result := make(Slice, 0, len(collection)-len(isDupl))
+
+ for i := range collection {
+ key := iteratee(collection[i])
+
+ if duplicated := isDupl[key]; duplicated {
+ result = append(result, collection[i])
+ isDupl[key] = false
+ }
+ }
+
+ return result
+}
+
+// Min search the minimum value of a collection.
+// Returns zero value when the collection is empty.
+func Min[T constraints.Ordered](collection []T) T {
+ var min T
+
+ if len(collection) == 0 {
+ return min
+ }
+
+ min = collection[0]
+
+ for i := 1; i < len(collection); i++ {
+ item := collection[i]
+
+ if item < min {
+ min = item
+ }
+ }
+
+ return min
+}
+
+// MinBy search the minimum value of a collection using the given comparison function.
+// If several values of the collection are equal to the smallest value, returns the first such value.
+// Returns zero value when the collection is empty.
+func MinBy[T any](collection []T, comparison func(a T, b T) bool) T {
+ var min T
+
+ if len(collection) == 0 {
+ return min
+ }
+
+ min = collection[0]
+
+ for i := 1; i < len(collection); i++ {
+ item := collection[i]
+
+ if comparison(item, min) {
+ min = item
+ }
+ }
+
+ return min
+}
+
+// Earliest search the minimum time.Time of a collection.
+// Returns zero value when the collection is empty.
+func Earliest(times ...time.Time) time.Time {
+ var min time.Time
+
+ if len(times) == 0 {
+ return min
+ }
+
+ min = times[0]
+
+ for i := 1; i < len(times); i++ {
+ item := times[i]
+
+ if item.Before(min) {
+ min = item
+ }
+ }
+
+ return min
+}
+
+// EarliestBy search the minimum time.Time of a collection using the given iteratee function.
+// Returns zero value when the collection is empty.
+func EarliestBy[T any](collection []T, iteratee func(item T) time.Time) T {
+ var earliest T
+
+ if len(collection) == 0 {
+ return earliest
+ }
+
+ earliest = collection[0]
+ earliestTime := iteratee(collection[0])
+
+ for i := 1; i < len(collection); i++ {
+ itemTime := iteratee(collection[i])
+
+ if itemTime.Before(earliestTime) {
+ earliest = collection[i]
+ earliestTime = itemTime
+ }
+ }
+
+ return earliest
+}
+
+// Max searches the maximum value of a collection.
+// Returns zero value when the collection is empty.
+func Max[T constraints.Ordered](collection []T) T {
+ var max T
+
+ if len(collection) == 0 {
+ return max
+ }
+
+ max = collection[0]
+
+ for i := 1; i < len(collection); i++ {
+ item := collection[i]
+
+ if item > max {
+ max = item
+ }
+ }
+
+ return max
+}
+
+// MaxBy search the maximum value of a collection using the given comparison function.
+// If several values of the collection are equal to the greatest value, returns the first such value.
+// Returns zero value when the collection is empty.
+func MaxBy[T any](collection []T, comparison func(a T, b T) bool) T {
+ var max T
+
+ if len(collection) == 0 {
+ return max
+ }
+
+ max = collection[0]
+
+ for i := 1; i < len(collection); i++ {
+ item := collection[i]
+
+ if comparison(item, max) {
+ max = item
+ }
+ }
+
+ return max
+}
+
+// Latest search the maximum time.Time of a collection.
+// Returns zero value when the collection is empty.
+func Latest(times ...time.Time) time.Time {
+ var max time.Time
+
+ if len(times) == 0 {
+ return max
+ }
+
+ max = times[0]
+
+ for i := 1; i < len(times); i++ {
+ item := times[i]
+
+ if item.After(max) {
+ max = item
+ }
+ }
+
+ return max
+}
+
+// LatestBy search the maximum time.Time of a collection using the given iteratee function.
+// Returns zero value when the collection is empty.
+func LatestBy[T any](collection []T, iteratee func(item T) time.Time) T {
+ var latest T
+
+ if len(collection) == 0 {
+ return latest
+ }
+
+ latest = collection[0]
+ latestTime := iteratee(collection[0])
+
+ for i := 1; i < len(collection); i++ {
+ itemTime := iteratee(collection[i])
+
+ if itemTime.After(latestTime) {
+ latest = collection[i]
+ latestTime = itemTime
+ }
+ }
+
+ return latest
+}
+
+// First returns the first element of a collection and check for availability of the first element.
+func First[T any](collection []T) (T, bool) {
+ length := len(collection)
+
+ if length == 0 {
+ var t T
+ return t, false
+ }
+
+ return collection[0], true
+}
+
+// FirstOrEmpty returns the first element of a collection or zero value if empty.
+func FirstOrEmpty[T any](collection []T) T {
+ i, _ := First(collection)
+ return i
+}
+
+// FirstOr returns the first element of a collection or the fallback value if empty.
+func FirstOr[T any](collection []T, fallback T) T {
+ i, ok := First(collection)
+ if !ok {
+ return fallback
+ }
+
+ return i
+}
+
+// Last returns the last element of a collection or error if empty.
+func Last[T any](collection []T) (T, bool) {
+ length := len(collection)
+
+ if length == 0 {
+ var t T
+ return t, false
+ }
+
+ return collection[length-1], true
+}
+
+// Returns the last element of a collection or zero value if empty.
+func LastOrEmpty[T any](collection []T) T {
+ i, _ := Last(collection)
+ return i
+}
+
+// LastOr returns the last element of a collection or the fallback value if empty.
+func LastOr[T any](collection []T, fallback T) T {
+ i, ok := Last(collection)
+ if !ok {
+ return fallback
+ }
+
+ return i
+}
+
+// Nth returns the element at index `nth` of collection. If `nth` is negative, the nth element
+// from the end is returned. An error is returned when nth is out of slice bounds.
+func Nth[T any, N constraints.Integer](collection []T, nth N) (T, error) {
+ n := int(nth)
+ l := len(collection)
+ if n >= l || -n > l {
+ var t T
+ return t, fmt.Errorf("nth: %d out of slice bounds", n)
+ }
+
+ if n >= 0 {
+ return collection[n], nil
+ }
+ return collection[l+n], nil
+}
+
+// Sample returns a random item from collection.
+func Sample[T any](collection []T) T {
+ size := len(collection)
+ if size == 0 {
+ return Empty[T]()
+ }
+
+ return collection[rand.IntN(size)]
+}
+
+// Samples returns N random unique items from collection.
+func Samples[T any, Slice ~[]T](collection Slice, count int) Slice {
+ size := len(collection)
+
+ copy := append(Slice{}, collection...)
+
+ results := Slice{}
+
+ for i := 0; i < size && i < count; i++ {
+ copyLength := size - i
+
+ index := rand.IntN(size - i)
+ results = append(results, copy[index])
+
+ // Removes element.
+ // It is faster to swap with last element and remove it.
+ copy[index] = copy[copyLength-1]
+ copy = copy[:copyLength-1]
+ }
+
+ return results
+}
diff --git a/vendor/github.com/samber/lo/func.go b/vendor/github.com/samber/lo/func.go
new file mode 100644
index 00000000..5fa1cbc8
--- /dev/null
+++ b/vendor/github.com/samber/lo/func.go
@@ -0,0 +1,41 @@
+package lo
+
+// Partial returns new function that, when called, has its first argument set to the provided value.
+func Partial[T1, T2, R any](f func(a T1, b T2) R, arg1 T1) func(T2) R {
+ return func(t2 T2) R {
+ return f(arg1, t2)
+ }
+}
+
+// Partial1 returns new function that, when called, has its first argument set to the provided value.
+func Partial1[T1, T2, R any](f func(T1, T2) R, arg1 T1) func(T2) R {
+ return Partial(f, arg1)
+}
+
+// Partial2 returns new function that, when called, has its first argument set to the provided value.
+func Partial2[T1, T2, T3, R any](f func(T1, T2, T3) R, arg1 T1) func(T2, T3) R {
+ return func(t2 T2, t3 T3) R {
+ return f(arg1, t2, t3)
+ }
+}
+
+// Partial3 returns new function that, when called, has its first argument set to the provided value.
+func Partial3[T1, T2, T3, T4, R any](f func(T1, T2, T3, T4) R, arg1 T1) func(T2, T3, T4) R {
+ return func(t2 T2, t3 T3, t4 T4) R {
+ return f(arg1, t2, t3, t4)
+ }
+}
+
+// Partial4 returns new function that, when called, has its first argument set to the provided value.
+func Partial4[T1, T2, T3, T4, T5, R any](f func(T1, T2, T3, T4, T5) R, arg1 T1) func(T2, T3, T4, T5) R {
+ return func(t2 T2, t3 T3, t4 T4, t5 T5) R {
+ return f(arg1, t2, t3, t4, t5)
+ }
+}
+
+// Partial5 returns new function that, when called, has its first argument set to the provided value
+func Partial5[T1, T2, T3, T4, T5, T6, R any](f func(T1, T2, T3, T4, T5, T6) R, arg1 T1) func(T2, T3, T4, T5, T6) R {
+ return func(t2 T2, t3 T3, t4 T4, t5 T5, t6 T6) R {
+ return f(arg1, t2, t3, t4, t5, t6)
+ }
+}
diff --git a/vendor/github.com/samber/lo/internal/constraints/constraints.go b/vendor/github.com/samber/lo/internal/constraints/constraints.go
new file mode 100644
index 00000000..3eb1cda5
--- /dev/null
+++ b/vendor/github.com/samber/lo/internal/constraints/constraints.go
@@ -0,0 +1,42 @@
+// Copyright 2021 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 constraints defines a set of useful constraints to be used
+// with type parameters.
+package constraints
+
+// Signed is a constraint that permits any signed integer type.
+// If future releases of Go add new predeclared signed integer types,
+// this constraint will be modified to include them.
+type Signed interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64
+}
+
+// Unsigned is a constraint that permits any unsigned integer type.
+// If future releases of Go add new predeclared unsigned integer types,
+// this constraint will be modified to include them.
+type Unsigned interface {
+ ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
+}
+
+// Integer is a constraint that permits any integer type.
+// If future releases of Go add new predeclared integer types,
+// this constraint will be modified to include them.
+type Integer interface {
+ Signed | Unsigned
+}
+
+// Float is a constraint that permits any floating-point type.
+// If future releases of Go add new predeclared floating-point types,
+// this constraint will be modified to include them.
+type Float interface {
+ ~float32 | ~float64
+}
+
+// Complex is a constraint that permits any complex numeric type.
+// If future releases of Go add new predeclared complex numeric types,
+// this constraint will be modified to include them.
+type Complex interface {
+ ~complex64 | ~complex128
+}
diff --git a/vendor/github.com/samber/lo/internal/constraints/ordered_go118.go b/vendor/github.com/samber/lo/internal/constraints/ordered_go118.go
new file mode 100644
index 00000000..a124366f
--- /dev/null
+++ b/vendor/github.com/samber/lo/internal/constraints/ordered_go118.go
@@ -0,0 +1,11 @@
+//go:build !go1.21
+
+package constraints
+
+// Ordered is a constraint that permits any ordered type: any type
+// that supports the operators < <= >= >.
+// If future releases of Go add new ordered types,
+// this constraint will be modified to include them.
+type Ordered interface {
+ Integer | Float | ~string
+}
diff --git a/vendor/github.com/samber/lo/internal/constraints/ordered_go121.go b/vendor/github.com/samber/lo/internal/constraints/ordered_go121.go
new file mode 100644
index 00000000..c02de935
--- /dev/null
+++ b/vendor/github.com/samber/lo/internal/constraints/ordered_go121.go
@@ -0,0 +1,9 @@
+//go:build go1.21
+
+package constraints
+
+import (
+ "cmp"
+)
+
+type Ordered = cmp.Ordered
diff --git a/vendor/github.com/samber/lo/internal/rand/ordered_go118.go b/vendor/github.com/samber/lo/internal/rand/ordered_go118.go
new file mode 100644
index 00000000..a31bb9f2
--- /dev/null
+++ b/vendor/github.com/samber/lo/internal/rand/ordered_go118.go
@@ -0,0 +1,14 @@
+//go:build !go1.22
+
+package rand
+
+import "math/rand"
+
+func Shuffle(n int, swap func(i, j int)) {
+ rand.Shuffle(n, swap)
+}
+
+func IntN(n int) int {
+ // bearer:disable go_gosec_crypto_weak_random
+ return rand.Intn(n)
+}
diff --git a/vendor/github.com/samber/lo/internal/rand/ordered_go122.go b/vendor/github.com/samber/lo/internal/rand/ordered_go122.go
new file mode 100644
index 00000000..532ed339
--- /dev/null
+++ b/vendor/github.com/samber/lo/internal/rand/ordered_go122.go
@@ -0,0 +1,13 @@
+//go:build go1.22
+
+package rand
+
+import "math/rand/v2"
+
+func Shuffle(n int, swap func(i, j int)) {
+ rand.Shuffle(n, swap)
+}
+
+func IntN(n int) int {
+ return rand.IntN(n)
+}
diff --git a/vendor/github.com/samber/lo/intersect.go b/vendor/github.com/samber/lo/intersect.go
new file mode 100644
index 00000000..2df0e741
--- /dev/null
+++ b/vendor/github.com/samber/lo/intersect.go
@@ -0,0 +1,184 @@
+package lo
+
+// Contains returns true if an element is present in a collection.
+func Contains[T comparable](collection []T, element T) bool {
+ for i := range collection {
+ if collection[i] == element {
+ return true
+ }
+ }
+
+ return false
+}
+
+// ContainsBy returns true if predicate function return true.
+func ContainsBy[T any](collection []T, predicate func(item T) bool) bool {
+ for i := range collection {
+ if predicate(collection[i]) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Every returns true if all elements of a subset are contained into a collection or if the subset is empty.
+func Every[T comparable](collection []T, subset []T) bool {
+ for i := range subset {
+ if !Contains(collection, subset[i]) {
+ return false
+ }
+ }
+
+ return true
+}
+
+// EveryBy returns true if the predicate returns true for all of the elements in the collection or if the collection is empty.
+func EveryBy[T any](collection []T, predicate func(item T) bool) bool {
+ for i := range collection {
+ if !predicate(collection[i]) {
+ return false
+ }
+ }
+
+ return true
+}
+
+// Some returns true if at least 1 element of a subset is contained into a collection.
+// If the subset is empty Some returns false.
+func Some[T comparable](collection []T, subset []T) bool {
+ for i := range subset {
+ if Contains(collection, subset[i]) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// SomeBy returns true if the predicate returns true for any of the elements in the collection.
+// If the collection is empty SomeBy returns false.
+func SomeBy[T any](collection []T, predicate func(item T) bool) bool {
+ for i := range collection {
+ if predicate(collection[i]) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// None returns true if no element of a subset are contained into a collection or if the subset is empty.
+func None[T comparable](collection []T, subset []T) bool {
+ for i := range subset {
+ if Contains(collection, subset[i]) {
+ return false
+ }
+ }
+
+ return true
+}
+
+// NoneBy returns true if the predicate returns true for none of the elements in the collection or if the collection is empty.
+func NoneBy[T any](collection []T, predicate func(item T) bool) bool {
+ for i := range collection {
+ if predicate(collection[i]) {
+ return false
+ }
+ }
+
+ return true
+}
+
+// Intersect returns the intersection between two collections.
+func Intersect[T comparable, Slice ~[]T](list1 Slice, list2 Slice) Slice {
+ result := Slice{}
+ seen := map[T]struct{}{}
+
+ for i := range list1 {
+ seen[list1[i]] = struct{}{}
+ }
+
+ for i := range list2 {
+ if _, ok := seen[list2[i]]; ok {
+ result = append(result, list2[i])
+ }
+ }
+
+ return result
+}
+
+// Difference returns the difference between two collections.
+// The first value is the collection of element absent of list2.
+// The second value is the collection of element absent of list1.
+func Difference[T comparable, Slice ~[]T](list1 Slice, list2 Slice) (Slice, Slice) {
+ left := Slice{}
+ right := Slice{}
+
+ seenLeft := map[T]struct{}{}
+ seenRight := map[T]struct{}{}
+
+ for i := range list1 {
+ seenLeft[list1[i]] = struct{}{}
+ }
+
+ for i := range list2 {
+ seenRight[list2[i]] = struct{}{}
+ }
+
+ for i := range list1 {
+ if _, ok := seenRight[list1[i]]; !ok {
+ left = append(left, list1[i])
+ }
+ }
+
+ for i := range list2 {
+ if _, ok := seenLeft[list2[i]]; !ok {
+ right = append(right, list2[i])
+ }
+ }
+
+ return left, right
+}
+
+// Union returns all distinct elements from given collections.
+// result returns will not change the order of elements relatively.
+func Union[T comparable, Slice ~[]T](lists ...Slice) Slice {
+ var capLen int
+
+ for _, list := range lists {
+ capLen += len(list)
+ }
+
+ result := make(Slice, 0, capLen)
+ seen := make(map[T]struct{}, capLen)
+
+ for i := range lists {
+ for j := range lists[i] {
+ if _, ok := seen[lists[i][j]]; !ok {
+ seen[lists[i][j]] = struct{}{}
+ result = append(result, lists[i][j])
+ }
+ }
+ }
+
+ return result
+}
+
+// Without returns slice excluding all given values.
+func Without[T comparable, Slice ~[]T](collection Slice, exclude ...T) Slice {
+ result := make(Slice, 0, len(collection))
+ for i := range collection {
+ if !Contains(exclude, collection[i]) {
+ result = append(result, collection[i])
+ }
+ }
+ return result
+}
+
+// WithoutEmpty returns slice excluding empty values.
+//
+// Deprecated: Use lo.Compact instead.
+func WithoutEmpty[T comparable, Slice ~[]T](collection Slice) Slice {
+ return Compact(collection)
+}
diff --git a/vendor/github.com/samber/lo/map.go b/vendor/github.com/samber/lo/map.go
new file mode 100644
index 00000000..d8feb434
--- /dev/null
+++ b/vendor/github.com/samber/lo/map.go
@@ -0,0 +1,297 @@
+package lo
+
+// Keys creates an array of the map keys.
+// Play: https://go.dev/play/p/Uu11fHASqrU
+func Keys[K comparable, V any](in ...map[K]V) []K {
+ size := 0
+ for i := range in {
+ size += len(in[i])
+ }
+ result := make([]K, 0, size)
+
+ for i := range in {
+ for k := range in[i] {
+ result = append(result, k)
+ }
+ }
+
+ return result
+}
+
+// UniqKeys creates an array of unique keys in the map.
+// Play: https://go.dev/play/p/TPKAb6ILdHk
+func UniqKeys[K comparable, V any](in ...map[K]V) []K {
+ size := 0
+ for i := range in {
+ size += len(in[i])
+ }
+
+ seen := make(map[K]struct{}, size)
+ result := make([]K, 0)
+
+ for i := range in {
+ for k := range in[i] {
+ if _, exists := seen[k]; exists {
+ continue
+ }
+ seen[k] = struct{}{}
+ result = append(result, k)
+ }
+ }
+
+ return result
+}
+
+// HasKey returns whether the given key exists.
+// Play: https://go.dev/play/p/aVwubIvECqS
+func HasKey[K comparable, V any](in map[K]V, key K) bool {
+ _, ok := in[key]
+ return ok
+}
+
+// Values creates an array of the map values.
+// Play: https://go.dev/play/p/nnRTQkzQfF6
+func Values[K comparable, V any](in ...map[K]V) []V {
+ size := 0
+ for i := range in {
+ size += len(in[i])
+ }
+ result := make([]V, 0, size)
+
+ for i := range in {
+ for k := range in[i] {
+ result = append(result, in[i][k])
+ }
+ }
+
+ return result
+}
+
+// UniqValues creates an array of unique values in the map.
+// Play: https://go.dev/play/p/nf6bXMh7rM3
+func UniqValues[K comparable, V comparable](in ...map[K]V) []V {
+ size := 0
+ for i := range in {
+ size += len(in[i])
+ }
+
+ seen := make(map[V]struct{}, size)
+ result := make([]V, 0)
+
+ for i := range in {
+ for k := range in[i] {
+ val := in[i][k]
+ if _, exists := seen[val]; exists {
+ continue
+ }
+ seen[val] = struct{}{}
+ result = append(result, val)
+ }
+ }
+
+ return result
+}
+
+// ValueOr returns the value of the given key or the fallback value if the key is not present.
+// Play: https://go.dev/play/p/bAq9mHErB4V
+func ValueOr[K comparable, V any](in map[K]V, key K, fallback V) V {
+ if v, ok := in[key]; ok {
+ return v
+ }
+ return fallback
+}
+
+// PickBy returns same map type filtered by given predicate.
+// Play: https://go.dev/play/p/kdg8GR_QMmf
+func PickBy[K comparable, V any, Map ~map[K]V](in Map, predicate func(key K, value V) bool) Map {
+ r := Map{}
+ for k := range in {
+ if predicate(k, in[k]) {
+ r[k] = in[k]
+ }
+ }
+ return r
+}
+
+// PickByKeys returns same map type filtered by given keys.
+// Play: https://go.dev/play/p/R1imbuci9qU
+func PickByKeys[K comparable, V any, Map ~map[K]V](in Map, keys []K) Map {
+ r := Map{}
+ for i := range keys {
+ if v, ok := in[keys[i]]; ok {
+ r[keys[i]] = v
+ }
+ }
+ return r
+}
+
+// PickByValues returns same map type filtered by given values.
+// Play: https://go.dev/play/p/1zdzSvbfsJc
+func PickByValues[K comparable, V comparable, Map ~map[K]V](in Map, values []V) Map {
+ r := Map{}
+ for k := range in {
+ if Contains(values, in[k]) {
+ r[k] = in[k]
+ }
+ }
+ return r
+}
+
+// OmitBy returns same map type filtered by given predicate.
+// Play: https://go.dev/play/p/EtBsR43bdsd
+func OmitBy[K comparable, V any, Map ~map[K]V](in Map, predicate func(key K, value V) bool) Map {
+ r := Map{}
+ for k := range in {
+ if !predicate(k, in[k]) {
+ r[k] = in[k]
+ }
+ }
+ return r
+}
+
+// OmitByKeys returns same map type filtered by given keys.
+// Play: https://go.dev/play/p/t1QjCrs-ysk
+func OmitByKeys[K comparable, V any, Map ~map[K]V](in Map, keys []K) Map {
+ r := Map{}
+ for k := range in {
+ r[k] = in[k]
+ }
+ for i := range keys {
+ delete(r, keys[i])
+ }
+ return r
+}
+
+// OmitByValues returns same map type filtered by given values.
+// Play: https://go.dev/play/p/9UYZi-hrs8j
+func OmitByValues[K comparable, V comparable, Map ~map[K]V](in Map, values []V) Map {
+ r := Map{}
+ for k := range in {
+ if !Contains(values, in[k]) {
+ r[k] = in[k]
+ }
+ }
+ return r
+}
+
+// Entries transforms a map into array of key/value pairs.
+// Play:
+func Entries[K comparable, V any](in map[K]V) []Entry[K, V] {
+ entries := make([]Entry[K, V], 0, len(in))
+
+ for k := range in {
+ entries = append(entries, Entry[K, V]{
+ Key: k,
+ Value: in[k],
+ })
+ }
+
+ return entries
+}
+
+// ToPairs transforms a map into array of key/value pairs.
+// Alias of Entries().
+// Play: https://go.dev/play/p/3Dhgx46gawJ
+func ToPairs[K comparable, V any](in map[K]V) []Entry[K, V] {
+ return Entries(in)
+}
+
+// FromEntries transforms an array of key/value pairs into a map.
+// Play: https://go.dev/play/p/oIr5KHFGCEN
+func FromEntries[K comparable, V any](entries []Entry[K, V]) map[K]V {
+ out := make(map[K]V, len(entries))
+
+ for i := range entries {
+ out[entries[i].Key] = entries[i].Value
+ }
+
+ return out
+}
+
+// FromPairs transforms an array of key/value pairs into a map.
+// Alias of FromEntries().
+// Play: https://go.dev/play/p/oIr5KHFGCEN
+func FromPairs[K comparable, V any](entries []Entry[K, V]) map[K]V {
+ return FromEntries(entries)
+}
+
+// Invert creates a map composed of the inverted keys and values. If map
+// contains duplicate values, subsequent values overwrite property assignments
+// of previous values.
+// Play: https://go.dev/play/p/rFQ4rak6iA1
+func Invert[K comparable, V comparable](in map[K]V) map[V]K {
+ out := make(map[V]K, len(in))
+
+ for k := range in {
+ out[in[k]] = k
+ }
+
+ return out
+}
+
+// Assign merges multiple maps from left to right.
+// Play: https://go.dev/play/p/VhwfJOyxf5o
+func Assign[K comparable, V any, Map ~map[K]V](maps ...Map) Map {
+ count := 0
+ for i := range maps {
+ count += len(maps[i])
+ }
+
+ out := make(Map, count)
+ for i := range maps {
+ for k := range maps[i] {
+ out[k] = maps[i][k]
+ }
+ }
+
+ return out
+}
+
+// MapKeys manipulates a map keys and transforms it to a map of another type.
+// Play: https://go.dev/play/p/9_4WPIqOetJ
+func MapKeys[K comparable, V any, R comparable](in map[K]V, iteratee func(value V, key K) R) map[R]V {
+ result := make(map[R]V, len(in))
+
+ for k := range in {
+ result[iteratee(in[k], k)] = in[k]
+ }
+
+ return result
+}
+
+// MapValues manipulates a map values and transforms it to a map of another type.
+// Play: https://go.dev/play/p/T_8xAfvcf0W
+func MapValues[K comparable, V any, R any](in map[K]V, iteratee func(value V, key K) R) map[K]R {
+ result := make(map[K]R, len(in))
+
+ for k := range in {
+ result[k] = iteratee(in[k], k)
+ }
+
+ return result
+}
+
+// MapEntries manipulates a map entries and transforms it to a map of another type.
+// Play: https://go.dev/play/p/VuvNQzxKimT
+func MapEntries[K1 comparable, V1 any, K2 comparable, V2 any](in map[K1]V1, iteratee func(key K1, value V1) (K2, V2)) map[K2]V2 {
+ result := make(map[K2]V2, len(in))
+
+ for k1 := range in {
+ k2, v2 := iteratee(k1, in[k1])
+ result[k2] = v2
+ }
+
+ return result
+}
+
+// MapToSlice transforms a map into a slice based on specific iteratee
+// Play: https://go.dev/play/p/ZuiCZpDt6LD
+func MapToSlice[K comparable, V any, R any](in map[K]V, iteratee func(key K, value V) R) []R {
+ result := make([]R, 0, len(in))
+
+ for k := range in {
+ result = append(result, iteratee(k, in[k]))
+ }
+
+ return result
+}
diff --git a/vendor/github.com/samber/lo/math.go b/vendor/github.com/samber/lo/math.go
new file mode 100644
index 00000000..e866f88e
--- /dev/null
+++ b/vendor/github.com/samber/lo/math.go
@@ -0,0 +1,106 @@
+package lo
+
+import (
+ "github.com/samber/lo/internal/constraints"
+)
+
+// Range creates an array of numbers (positive and/or negative) with given length.
+// Play: https://go.dev/play/p/0r6VimXAi9H
+func Range(elementNum int) []int {
+ length := If(elementNum < 0, -elementNum).Else(elementNum)
+ result := make([]int, length)
+ step := If(elementNum < 0, -1).Else(1)
+ for i, j := 0, 0; i < length; i, j = i+1, j+step {
+ result[i] = j
+ }
+ return result
+}
+
+// RangeFrom creates an array of numbers from start with specified length.
+// Play: https://go.dev/play/p/0r6VimXAi9H
+func RangeFrom[T constraints.Integer | constraints.Float](start T, elementNum int) []T {
+ length := If(elementNum < 0, -elementNum).Else(elementNum)
+ result := make([]T, length)
+ step := If(elementNum < 0, -1).Else(1)
+ for i, j := 0, start; i < length; i, j = i+1, j+T(step) {
+ result[i] = j
+ }
+ return result
+}
+
+// RangeWithSteps creates an array of numbers (positive and/or negative) progressing from start up to, but not including end.
+// step set to zero will return empty array.
+// Play: https://go.dev/play/p/0r6VimXAi9H
+func RangeWithSteps[T constraints.Integer | constraints.Float](start, end, step T) []T {
+ result := []T{}
+ if start == end || step == 0 {
+ return result
+ }
+ if start < end {
+ if step < 0 {
+ return result
+ }
+ for i := start; i < end; i += step {
+ result = append(result, i)
+ }
+ return result
+ }
+ if step > 0 {
+ return result
+ }
+ for i := start; i > end; i += step {
+ result = append(result, i)
+ }
+ return result
+}
+
+// Clamp clamps number within the inclusive lower and upper bounds.
+// Play: https://go.dev/play/p/RU4lJNC2hlI
+func Clamp[T constraints.Ordered](value T, min T, max T) T {
+ if value < min {
+ return min
+ } else if value > max {
+ return max
+ }
+ return value
+}
+
+// Sum sums the values in a collection. If collection is empty 0 is returned.
+// Play: https://go.dev/play/p/upfeJVqs4Bt
+func Sum[T constraints.Float | constraints.Integer | constraints.Complex](collection []T) T {
+ var sum T = 0
+ for i := range collection {
+ sum += collection[i]
+ }
+ return sum
+}
+
+// SumBy summarizes the values in a collection using the given return value from the iteration function. If collection is empty 0 is returned.
+// Play: https://go.dev/play/p/Dz_a_7jN_ca
+func SumBy[T any, R constraints.Float | constraints.Integer | constraints.Complex](collection []T, iteratee func(item T) R) R {
+ var sum R = 0
+ for i := range collection {
+ sum = sum + iteratee(collection[i])
+ }
+ return sum
+}
+
+// Mean calculates the mean of a collection of numbers.
+func Mean[T constraints.Float | constraints.Integer](collection []T) T {
+ var length T = T(len(collection))
+ if length == 0 {
+ return 0
+ }
+ var sum T = Sum(collection)
+ return sum / length
+}
+
+// MeanBy calculates the mean of a collection of numbers using the given return value from the iteration function.
+func MeanBy[T any, R constraints.Float | constraints.Integer](collection []T, iteratee func(item T) R) R {
+ var length R = R(len(collection))
+ if length == 0 {
+ return 0
+ }
+ var sum R = SumBy(collection, iteratee)
+ return sum / length
+}
diff --git a/vendor/github.com/samber/lo/retry.go b/vendor/github.com/samber/lo/retry.go
new file mode 100644
index 00000000..f026aa33
--- /dev/null
+++ b/vendor/github.com/samber/lo/retry.go
@@ -0,0 +1,290 @@
+package lo
+
+import (
+ "sync"
+ "time"
+)
+
+type debounce struct {
+ after time.Duration
+ mu *sync.Mutex
+ timer *time.Timer
+ done bool
+ callbacks []func()
+}
+
+func (d *debounce) reset() {
+ d.mu.Lock()
+ defer d.mu.Unlock()
+
+ if d.done {
+ return
+ }
+
+ if d.timer != nil {
+ d.timer.Stop()
+ }
+
+ d.timer = time.AfterFunc(d.after, func() {
+ for i := range d.callbacks {
+ d.callbacks[i]()
+ }
+ })
+}
+
+func (d *debounce) cancel() {
+ d.mu.Lock()
+ defer d.mu.Unlock()
+
+ if d.timer != nil {
+ d.timer.Stop()
+ d.timer = nil
+ }
+
+ d.done = true
+}
+
+// NewDebounce creates a debounced instance that delays invoking functions given until after wait milliseconds have elapsed.
+// Play: https://go.dev/play/p/mz32VMK2nqe
+func NewDebounce(duration time.Duration, f ...func()) (func(), func()) {
+ d := &debounce{
+ after: duration,
+ mu: new(sync.Mutex),
+ timer: nil,
+ done: false,
+ callbacks: f,
+ }
+
+ return func() {
+ d.reset()
+ }, d.cancel
+}
+
+type debounceByItem struct {
+ mu *sync.Mutex
+ timer *time.Timer
+ count int
+}
+
+type debounceBy[T comparable] struct {
+ after time.Duration
+ mu *sync.Mutex
+ items map[T]*debounceByItem
+ callbacks []func(key T, count int)
+}
+
+func (d *debounceBy[T]) reset(key T) {
+ d.mu.Lock()
+ if _, ok := d.items[key]; !ok {
+ d.items[key] = &debounceByItem{
+ mu: new(sync.Mutex),
+ timer: nil,
+ }
+ }
+
+ item := d.items[key]
+
+ d.mu.Unlock()
+
+ item.mu.Lock()
+ defer item.mu.Unlock()
+
+ item.count++
+
+ if item.timer != nil {
+ item.timer.Stop()
+ }
+
+ item.timer = time.AfterFunc(d.after, func() {
+ item.mu.Lock()
+ count := item.count
+ item.count = 0
+ item.mu.Unlock()
+
+ for i := range d.callbacks {
+ d.callbacks[i](key, count)
+ }
+
+ })
+}
+
+func (d *debounceBy[T]) cancel(key T) {
+ d.mu.Lock()
+ defer d.mu.Unlock()
+
+ if item, ok := d.items[key]; ok {
+ item.mu.Lock()
+
+ if item.timer != nil {
+ item.timer.Stop()
+ item.timer = nil
+ }
+
+ item.mu.Unlock()
+
+ delete(d.items, key)
+ }
+}
+
+// NewDebounceBy creates a debounced instance for each distinct key, that delays invoking functions given until after wait milliseconds have elapsed.
+// Play: https://go.dev/play/p/d3Vpt6pxhY8
+func NewDebounceBy[T comparable](duration time.Duration, f ...func(key T, count int)) (func(key T), func(key T)) {
+ d := &debounceBy[T]{
+ after: duration,
+ mu: new(sync.Mutex),
+ items: map[T]*debounceByItem{},
+ callbacks: f,
+ }
+
+ return func(key T) {
+ d.reset(key)
+ }, d.cancel
+}
+
+// Attempt invokes a function N times until it returns valid output. Returning either the caught error or nil. When first argument is less than `1`, the function runs until a successful response is returned.
+// Play: https://go.dev/play/p/3ggJZ2ZKcMj
+func Attempt(maxIteration int, f func(index int) error) (int, error) {
+ var err error
+
+ for i := 0; maxIteration <= 0 || i < maxIteration; i++ {
+ // for retries >= 0 {
+ err = f(i)
+ if err == nil {
+ return i + 1, nil
+ }
+ }
+
+ return maxIteration, err
+}
+
+// AttemptWithDelay invokes a function N times until it returns valid output,
+// with a pause between each call. Returning either the caught error or nil.
+// When first argument is less than `1`, the function runs until a successful
+// response is returned.
+// Play: https://go.dev/play/p/tVs6CygC7m1
+func AttemptWithDelay(maxIteration int, delay time.Duration, f func(index int, duration time.Duration) error) (int, time.Duration, error) {
+ var err error
+
+ start := time.Now()
+
+ for i := 0; maxIteration <= 0 || i < maxIteration; i++ {
+ err = f(i, time.Since(start))
+ if err == nil {
+ return i + 1, time.Since(start), nil
+ }
+
+ if maxIteration <= 0 || i+1 < maxIteration {
+ time.Sleep(delay)
+ }
+ }
+
+ return maxIteration, time.Since(start), err
+}
+
+// AttemptWhile invokes a function N times until it returns valid output.
+// Returning either the caught error or nil, and along with a bool value to identify
+// whether it needs invoke function continuously. It will terminate the invoke
+// immediately if second bool value is returned with falsy value. When first
+// argument is less than `1`, the function runs until a successful response is
+// returned.
+func AttemptWhile(maxIteration int, f func(int) (error, bool)) (int, error) {
+ var err error
+ var shouldContinueInvoke bool
+
+ for i := 0; maxIteration <= 0 || i < maxIteration; i++ {
+ // for retries >= 0 {
+ err, shouldContinueInvoke = f(i)
+ if !shouldContinueInvoke { // if shouldContinueInvoke is false, then return immediately
+ return i + 1, err
+ }
+ if err == nil {
+ return i + 1, nil
+ }
+ }
+
+ return maxIteration, err
+}
+
+// AttemptWhileWithDelay invokes a function N times until it returns valid output,
+// with a pause between each call. Returning either the caught error or nil, and along
+// with a bool value to identify whether it needs to invoke function continuously.
+// It will terminate the invoke immediately if second bool value is returned with falsy
+// value. When first argument is less than `1`, the function runs until a successful
+// response is returned.
+func AttemptWhileWithDelay(maxIteration int, delay time.Duration, f func(int, time.Duration) (error, bool)) (int, time.Duration, error) {
+ var err error
+ var shouldContinueInvoke bool
+
+ start := time.Now()
+
+ for i := 0; maxIteration <= 0 || i < maxIteration; i++ {
+ err, shouldContinueInvoke = f(i, time.Since(start))
+ if !shouldContinueInvoke { // if shouldContinueInvoke is false, then return immediately
+ return i + 1, time.Since(start), err
+ }
+ if err == nil {
+ return i + 1, time.Since(start), nil
+ }
+
+ if maxIteration <= 0 || i+1 < maxIteration {
+ time.Sleep(delay)
+ }
+ }
+
+ return maxIteration, time.Since(start), err
+}
+
+type transactionStep[T any] struct {
+ exec func(T) (T, error)
+ onRollback func(T) T
+}
+
+// NewTransaction instantiate a new transaction.
+func NewTransaction[T any]() *Transaction[T] {
+ return &Transaction[T]{
+ steps: []transactionStep[T]{},
+ }
+}
+
+// Transaction implements a Saga pattern
+type Transaction[T any] struct {
+ steps []transactionStep[T]
+}
+
+// Then adds a step to the chain of callbacks. It returns the same Transaction.
+func (t *Transaction[T]) Then(exec func(T) (T, error), onRollback func(T) T) *Transaction[T] {
+ t.steps = append(t.steps, transactionStep[T]{
+ exec: exec,
+ onRollback: onRollback,
+ })
+
+ return t
+}
+
+// Process runs the Transaction steps and rollbacks in case of errors.
+func (t *Transaction[T]) Process(state T) (T, error) {
+ var i int
+ var err error
+
+ for i < len(t.steps) {
+ state, err = t.steps[i].exec(state)
+ if err != nil {
+ break
+ }
+
+ i++
+ }
+
+ if err == nil {
+ return state, nil
+ }
+
+ for i > 0 {
+ i--
+ state = t.steps[i].onRollback(state)
+ }
+
+ return state, err
+}
+
+// throttle ?
diff --git a/vendor/github.com/samber/lo/slice.go b/vendor/github.com/samber/lo/slice.go
new file mode 100644
index 00000000..d2d3fd84
--- /dev/null
+++ b/vendor/github.com/samber/lo/slice.go
@@ -0,0 +1,695 @@
+package lo
+
+import (
+ "sort"
+
+ "github.com/samber/lo/internal/constraints"
+ "github.com/samber/lo/internal/rand"
+)
+
+// Filter iterates over elements of collection, returning an array of all elements predicate returns truthy for.
+// Play: https://go.dev/play/p/Apjg3WeSi7K
+func Filter[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) Slice {
+ result := make(Slice, 0, len(collection))
+
+ for i := range collection {
+ if predicate(collection[i], i) {
+ result = append(result, collection[i])
+ }
+ }
+
+ return result
+}
+
+// Map manipulates a slice and transforms it to a slice of another type.
+// Play: https://go.dev/play/p/OkPcYAhBo0D
+func Map[T any, R any](collection []T, iteratee func(item T, index int) R) []R {
+ result := make([]R, len(collection))
+
+ for i := range collection {
+ result[i] = iteratee(collection[i], i)
+ }
+
+ return result
+}
+
+// FilterMap returns a slice which obtained after both filtering and mapping using the given callback function.
+// The callback function should return two values:
+// - the result of the mapping operation and
+// - whether the result element should be included or not.
+//
+// Play: https://go.dev/play/p/-AuYXfy7opz
+func FilterMap[T any, R any](collection []T, callback func(item T, index int) (R, bool)) []R {
+ result := []R{}
+
+ for i := range collection {
+ if r, ok := callback(collection[i], i); ok {
+ result = append(result, r)
+ }
+ }
+
+ return result
+}
+
+// FlatMap manipulates a slice and transforms and flattens it to a slice of another type.
+// The transform function can either return a slice or a `nil`, and in the `nil` case
+// no value is added to the final slice.
+// Play: https://go.dev/play/p/YSoYmQTA8-U
+func FlatMap[T any, R any](collection []T, iteratee func(item T, index int) []R) []R {
+ result := make([]R, 0, len(collection))
+
+ for i := range collection {
+ result = append(result, iteratee(collection[i], i)...)
+ }
+
+ return result
+}
+
+// Reduce reduces collection to a value which is the accumulated result of running each element in collection
+// through accumulator, where each successive invocation is supplied the return value of the previous.
+// Play: https://go.dev/play/p/R4UHXZNaaUG
+func Reduce[T any, R any](collection []T, accumulator func(agg R, item T, index int) R, initial R) R {
+ for i := range collection {
+ initial = accumulator(initial, collection[i], i)
+ }
+
+ return initial
+}
+
+// ReduceRight helper is like Reduce except that it iterates over elements of collection from right to left.
+// Play: https://go.dev/play/p/Fq3W70l7wXF
+func ReduceRight[T any, R any](collection []T, accumulator func(agg R, item T, index int) R, initial R) R {
+ for i := len(collection) - 1; i >= 0; i-- {
+ initial = accumulator(initial, collection[i], i)
+ }
+
+ return initial
+}
+
+// ForEach iterates over elements of collection and invokes iteratee for each element.
+// Play: https://go.dev/play/p/oofyiUPRf8t
+func ForEach[T any](collection []T, iteratee func(item T, index int)) {
+ for i := range collection {
+ iteratee(collection[i], i)
+ }
+}
+
+// ForEachWhile iterates over elements of collection and invokes iteratee for each element
+// collection return value decide to continue or break, like do while().
+// Play: https://go.dev/play/p/QnLGt35tnow
+func ForEachWhile[T any](collection []T, iteratee func(item T, index int) (goon bool)) {
+ for i := range collection {
+ if !iteratee(collection[i], i) {
+ break
+ }
+ }
+}
+
+// Times invokes the iteratee n times, returning an array of the results of each invocation.
+// The iteratee is invoked with index as argument.
+// Play: https://go.dev/play/p/vgQj3Glr6lT
+func Times[T any](count int, iteratee func(index int) T) []T {
+ result := make([]T, count)
+
+ for i := 0; i < count; i++ {
+ result[i] = iteratee(i)
+ }
+
+ return result
+}
+
+// Uniq returns a duplicate-free version of an array, in which only the first occurrence of each element is kept.
+// The order of result values is determined by the order they occur in the array.
+// Play: https://go.dev/play/p/DTzbeXZ6iEN
+func Uniq[T comparable, Slice ~[]T](collection Slice) Slice {
+ result := make(Slice, 0, len(collection))
+ seen := make(map[T]struct{}, len(collection))
+
+ for i := range collection {
+ if _, ok := seen[collection[i]]; ok {
+ continue
+ }
+
+ seen[collection[i]] = struct{}{}
+ result = append(result, collection[i])
+ }
+
+ return result
+}
+
+// UniqBy returns a duplicate-free version of an array, in which only the first occurrence of each element is kept.
+// The order of result values is determined by the order they occur in the array. It accepts `iteratee` which is
+// invoked for each element in array to generate the criterion by which uniqueness is computed.
+// Play: https://go.dev/play/p/g42Z3QSb53u
+func UniqBy[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) U) Slice {
+ result := make(Slice, 0, len(collection))
+ seen := make(map[U]struct{}, len(collection))
+
+ for i := range collection {
+ key := iteratee(collection[i])
+
+ if _, ok := seen[key]; ok {
+ continue
+ }
+
+ seen[key] = struct{}{}
+ result = append(result, collection[i])
+ }
+
+ return result
+}
+
+// GroupBy returns an object composed of keys generated from the results of running each element of collection through iteratee.
+// Play: https://go.dev/play/p/XnQBd_v6brd
+func GroupBy[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) U) map[U]Slice {
+ result := map[U]Slice{}
+
+ for i := range collection {
+ key := iteratee(collection[i])
+
+ result[key] = append(result[key], collection[i])
+ }
+
+ return result
+}
+
+// Chunk returns an array of elements split into groups the length of size. If array can't be split evenly,
+// the final chunk will be the remaining elements.
+// Play: https://go.dev/play/p/EeKl0AuTehH
+func Chunk[T any, Slice ~[]T](collection Slice, size int) []Slice {
+ if size <= 0 {
+ panic("Second parameter must be greater than 0")
+ }
+
+ chunksNum := len(collection) / size
+ if len(collection)%size != 0 {
+ chunksNum += 1
+ }
+
+ result := make([]Slice, 0, chunksNum)
+
+ for i := 0; i < chunksNum; i++ {
+ last := (i + 1) * size
+ if last > len(collection) {
+ last = len(collection)
+ }
+ result = append(result, collection[i*size:last:last])
+ }
+
+ return result
+}
+
+// PartitionBy returns an array of elements split into groups. The order of grouped values is
+// determined by the order they occur in collection. The grouping is generated from the results
+// of running each element of collection through iteratee.
+// Play: https://go.dev/play/p/NfQ_nGjkgXW
+func PartitionBy[T any, K comparable, Slice ~[]T](collection Slice, iteratee func(item T) K) []Slice {
+ result := []Slice{}
+ seen := map[K]int{}
+
+ for i := range collection {
+ key := iteratee(collection[i])
+
+ resultIndex, ok := seen[key]
+ if !ok {
+ resultIndex = len(result)
+ seen[key] = resultIndex
+ result = append(result, Slice{})
+ }
+
+ result[resultIndex] = append(result[resultIndex], collection[i])
+ }
+
+ return result
+
+ // unordered:
+ // groups := GroupBy[T, K](collection, iteratee)
+ // return Values[K, []T](groups)
+}
+
+// Flatten returns an array a single level deep.
+// Play: https://go.dev/play/p/rbp9ORaMpjw
+func Flatten[T any, Slice ~[]T](collection []Slice) Slice {
+ totalLen := 0
+ for i := range collection {
+ totalLen += len(collection[i])
+ }
+
+ result := make(Slice, 0, totalLen)
+ for i := range collection {
+ result = append(result, collection[i]...)
+ }
+
+ return result
+}
+
+// Interleave round-robin alternating input slices and sequentially appending value at index into result
+// Play: https://go.dev/play/p/-RJkTLQEDVt
+func Interleave[T any, Slice ~[]T](collections ...Slice) Slice {
+ if len(collections) == 0 {
+ return Slice{}
+ }
+
+ maxSize := 0
+ totalSize := 0
+ for i := range collections {
+ size := len(collections[i])
+ totalSize += size
+ if size > maxSize {
+ maxSize = size
+ }
+ }
+
+ if maxSize == 0 {
+ return Slice{}
+ }
+
+ result := make(Slice, totalSize)
+
+ resultIdx := 0
+ for i := 0; i < maxSize; i++ {
+ for j := range collections {
+ if len(collections[j])-1 < i {
+ continue
+ }
+
+ result[resultIdx] = collections[j][i]
+ resultIdx++
+ }
+ }
+
+ return result
+}
+
+// Shuffle returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm.
+// Play: https://go.dev/play/p/Qp73bnTDnc7
+func Shuffle[T any, Slice ~[]T](collection Slice) Slice {
+ rand.Shuffle(len(collection), func(i, j int) {
+ collection[i], collection[j] = collection[j], collection[i]
+ })
+
+ return collection
+}
+
+// Reverse reverses array so that the first element becomes the last, the second element becomes the second to last, and so on.
+// Play: https://go.dev/play/p/fhUMLvZ7vS6
+func Reverse[T any, Slice ~[]T](collection Slice) Slice {
+ length := len(collection)
+ half := length / 2
+
+ for i := 0; i < half; i = i + 1 {
+ j := length - 1 - i
+ collection[i], collection[j] = collection[j], collection[i]
+ }
+
+ return collection
+}
+
+// Fill fills elements of array with `initial` value.
+// Play: https://go.dev/play/p/VwR34GzqEub
+func Fill[T Clonable[T]](collection []T, initial T) []T {
+ result := make([]T, 0, len(collection))
+
+ for range collection {
+ result = append(result, initial.Clone())
+ }
+
+ return result
+}
+
+// Repeat builds a slice with N copies of initial value.
+// Play: https://go.dev/play/p/g3uHXbmc3b6
+func Repeat[T Clonable[T]](count int, initial T) []T {
+ result := make([]T, 0, count)
+
+ for i := 0; i < count; i++ {
+ result = append(result, initial.Clone())
+ }
+
+ return result
+}
+
+// RepeatBy builds a slice with values returned by N calls of callback.
+// Play: https://go.dev/play/p/ozZLCtX_hNU
+func RepeatBy[T any](count int, predicate func(index int) T) []T {
+ result := make([]T, 0, count)
+
+ for i := 0; i < count; i++ {
+ result = append(result, predicate(i))
+ }
+
+ return result
+}
+
+// KeyBy transforms a slice or an array of structs to a map based on a pivot callback.
+// Play: https://go.dev/play/p/mdaClUAT-zZ
+func KeyBy[K comparable, V any](collection []V, iteratee func(item V) K) map[K]V {
+ result := make(map[K]V, len(collection))
+
+ for i := range collection {
+ k := iteratee(collection[i])
+ result[k] = collection[i]
+ }
+
+ return result
+}
+
+// Associate returns a map containing key-value pairs provided by transform function applied to elements of the given slice.
+// If any of two pairs would have the same key the last one gets added to the map.
+// The order of keys in returned map is not specified and is not guaranteed to be the same from the original array.
+// Play: https://go.dev/play/p/WHa2CfMO3Lr
+func Associate[T any, K comparable, V any](collection []T, transform func(item T) (K, V)) map[K]V {
+ result := make(map[K]V, len(collection))
+
+ for i := range collection {
+ k, v := transform(collection[i])
+ result[k] = v
+ }
+
+ return result
+}
+
+// SliceToMap returns a map containing key-value pairs provided by transform function applied to elements of the given slice.
+// If any of two pairs would have the same key the last one gets added to the map.
+// The order of keys in returned map is not specified and is not guaranteed to be the same from the original array.
+// Alias of Associate().
+// Play: https://go.dev/play/p/WHa2CfMO3Lr
+func SliceToMap[T any, K comparable, V any](collection []T, transform func(item T) (K, V)) map[K]V {
+ return Associate(collection, transform)
+}
+
+// Drop drops n elements from the beginning of a slice or array.
+// Play: https://go.dev/play/p/JswS7vXRJP2
+func Drop[T any, Slice ~[]T](collection Slice, n int) Slice {
+ if len(collection) <= n {
+ return make(Slice, 0)
+ }
+
+ result := make(Slice, 0, len(collection)-n)
+
+ return append(result, collection[n:]...)
+}
+
+// DropRight drops n elements from the end of a slice or array.
+// Play: https://go.dev/play/p/GG0nXkSJJa3
+func DropRight[T any, Slice ~[]T](collection Slice, n int) Slice {
+ if len(collection) <= n {
+ return Slice{}
+ }
+
+ result := make(Slice, 0, len(collection)-n)
+ return append(result, collection[:len(collection)-n]...)
+}
+
+// DropWhile drops elements from the beginning of a slice or array while the predicate returns true.
+// Play: https://go.dev/play/p/7gBPYw2IK16
+func DropWhile[T any, Slice ~[]T](collection Slice, predicate func(item T) bool) Slice {
+ i := 0
+ for ; i < len(collection); i++ {
+ if !predicate(collection[i]) {
+ break
+ }
+ }
+
+ result := make(Slice, 0, len(collection)-i)
+ return append(result, collection[i:]...)
+}
+
+// DropRightWhile drops elements from the end of a slice or array while the predicate returns true.
+// Play: https://go.dev/play/p/3-n71oEC0Hz
+func DropRightWhile[T any, Slice ~[]T](collection Slice, predicate func(item T) bool) Slice {
+ i := len(collection) - 1
+ for ; i >= 0; i-- {
+ if !predicate(collection[i]) {
+ break
+ }
+ }
+
+ result := make(Slice, 0, i+1)
+ return append(result, collection[:i+1]...)
+}
+
+// DropByIndex drops elements from a slice or array by the index.
+// A negative index will drop elements from the end of the slice.
+// Play: https://go.dev/play/p/bPIH4npZRxS
+func DropByIndex[T any](collection []T, indexes ...int) []T {
+ initialSize := len(collection)
+ if initialSize == 0 {
+ return make([]T, 0)
+ }
+
+ for i := range indexes {
+ if indexes[i] < 0 {
+ indexes[i] = initialSize + indexes[i]
+ }
+ }
+
+ indexes = Uniq(indexes)
+ sort.Ints(indexes)
+
+ result := make([]T, 0, initialSize)
+ result = append(result, collection...)
+
+ for i := range indexes {
+ if indexes[i]-i < 0 || indexes[i]-i >= initialSize-i {
+ continue
+ }
+
+ result = append(result[:indexes[i]-i], result[indexes[i]-i+1:]...)
+ }
+
+ return result
+}
+
+// Reject is the opposite of Filter, this method returns the elements of collection that predicate does not return truthy for.
+// Play: https://go.dev/play/p/YkLMODy1WEL
+func Reject[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) Slice {
+ result := Slice{}
+
+ for i := range collection {
+ if !predicate(collection[i], i) {
+ result = append(result, collection[i])
+ }
+ }
+
+ return result
+}
+
+// RejectMap is the opposite of FilterMap, this method returns a slice which obtained after both filtering and mapping using the given callback function.
+// The callback function should return two values:
+// - the result of the mapping operation and
+// - whether the result element should be included or not.
+func RejectMap[T any, R any](collection []T, callback func(item T, index int) (R, bool)) []R {
+ result := []R{}
+
+ for i := range collection {
+ if r, ok := callback(collection[i], i); !ok {
+ result = append(result, r)
+ }
+ }
+
+ return result
+}
+
+// FilterReject mixes Filter and Reject, this method returns two slices, one for the elements of collection that
+// predicate returns truthy for and one for the elements that predicate does not return truthy for.
+func FilterReject[T any, Slice ~[]T](collection Slice, predicate func(T, int) bool) (kept Slice, rejected Slice) {
+ kept = make(Slice, 0, len(collection))
+ rejected = make(Slice, 0, len(collection))
+
+ for i := range collection {
+ if predicate(collection[i], i) {
+ kept = append(kept, collection[i])
+ } else {
+ rejected = append(rejected, collection[i])
+ }
+ }
+
+ return kept, rejected
+}
+
+// Count counts the number of elements in the collection that compare equal to value.
+// Play: https://go.dev/play/p/Y3FlK54yveC
+func Count[T comparable](collection []T, value T) (count int) {
+ for i := range collection {
+ if collection[i] == value {
+ count++
+ }
+ }
+
+ return count
+}
+
+// CountBy counts the number of elements in the collection for which predicate is true.
+// Play: https://go.dev/play/p/ByQbNYQQi4X
+func CountBy[T any](collection []T, predicate func(item T) bool) (count int) {
+ for i := range collection {
+ if predicate(collection[i]) {
+ count++
+ }
+ }
+
+ return count
+}
+
+// CountValues counts the number of each element in the collection.
+// Play: https://go.dev/play/p/-p-PyLT4dfy
+func CountValues[T comparable](collection []T) map[T]int {
+ result := make(map[T]int)
+
+ for i := range collection {
+ result[collection[i]]++
+ }
+
+ return result
+}
+
+// CountValuesBy counts the number of each element return from mapper function.
+// Is equivalent to chaining lo.Map and lo.CountValues.
+// Play: https://go.dev/play/p/2U0dG1SnOmS
+func CountValuesBy[T any, U comparable](collection []T, mapper func(item T) U) map[U]int {
+ result := make(map[U]int)
+
+ for i := range collection {
+ result[mapper(collection[i])]++
+ }
+
+ return result
+}
+
+// Subset returns a copy of a slice from `offset` up to `length` elements. Like `slice[start:start+length]`, but does not panic on overflow.
+// Play: https://go.dev/play/p/tOQu1GhFcog
+func Subset[T any, Slice ~[]T](collection Slice, offset int, length uint) Slice {
+ size := len(collection)
+
+ if offset < 0 {
+ offset = size + offset
+ if offset < 0 {
+ offset = 0
+ }
+ }
+
+ if offset > size {
+ return Slice{}
+ }
+
+ if length > uint(size)-uint(offset) {
+ length = uint(size - offset)
+ }
+
+ return collection[offset : offset+int(length)]
+}
+
+// Slice returns a copy of a slice from `start` up to, but not including `end`. Like `slice[start:end]`, but does not panic on overflow.
+// Play: https://go.dev/play/p/8XWYhfMMA1h
+func Slice[T any, Slice ~[]T](collection Slice, start int, end int) Slice {
+ size := len(collection)
+
+ if start >= end {
+ return Slice{}
+ }
+
+ if start > size {
+ start = size
+ }
+ if start < 0 {
+ start = 0
+ }
+
+ if end > size {
+ end = size
+ }
+ if end < 0 {
+ end = 0
+ }
+
+ return collection[start:end]
+}
+
+// Replace returns a copy of the slice with the first n non-overlapping instances of old replaced by new.
+// Play: https://go.dev/play/p/XfPzmf9gql6
+func Replace[T comparable, Slice ~[]T](collection Slice, old T, new T, n int) Slice {
+ result := make(Slice, len(collection))
+ copy(result, collection)
+
+ for i := range result {
+ if result[i] == old && n != 0 {
+ result[i] = new
+ n--
+ }
+ }
+
+ return result
+}
+
+// ReplaceAll returns a copy of the slice with all non-overlapping instances of old replaced by new.
+// Play: https://go.dev/play/p/a9xZFUHfYcV
+func ReplaceAll[T comparable, Slice ~[]T](collection Slice, old T, new T) Slice {
+ return Replace(collection, old, new, -1)
+}
+
+// Compact returns a slice of all non-zero elements.
+// Play: https://go.dev/play/p/tXiy-iK6PAc
+func Compact[T comparable, Slice ~[]T](collection Slice) Slice {
+ var zero T
+
+ result := make(Slice, 0, len(collection))
+
+ for i := range collection {
+ if collection[i] != zero {
+ result = append(result, collection[i])
+ }
+ }
+
+ return result
+}
+
+// IsSorted checks if a slice is sorted.
+// Play: https://go.dev/play/p/mc3qR-t4mcx
+func IsSorted[T constraints.Ordered](collection []T) bool {
+ for i := 1; i < len(collection); i++ {
+ if collection[i-1] > collection[i] {
+ return false
+ }
+ }
+
+ return true
+}
+
+// IsSortedByKey checks if a slice is sorted by iteratee.
+// Play: https://go.dev/play/p/wiG6XyBBu49
+func IsSortedByKey[T any, K constraints.Ordered](collection []T, iteratee func(item T) K) bool {
+ size := len(collection)
+
+ for i := 0; i < size-1; i++ {
+ if iteratee(collection[i]) > iteratee(collection[i+1]) {
+ return false
+ }
+ }
+
+ return true
+}
+
+// Splice inserts multiple elements at index i. A negative index counts back
+// from the end of the slice. The helper is protected against overflow errors.
+// Play: https://go.dev/play/p/G5_GhkeSUBA
+func Splice[T any, Slice ~[]T](collection Slice, i int, elements ...T) Slice {
+ sizeCollection := len(collection)
+ sizeElements := len(elements)
+ output := make(Slice, 0, sizeCollection+sizeElements) // preallocate memory for the output slice
+
+ if sizeElements == 0 {
+ return append(output, collection...) // simple copy
+ } else if i > sizeCollection {
+ // positive overflow
+ return append(append(output, collection...), elements...)
+ } else if i < -sizeCollection {
+ // negative overflow
+ return append(append(output, elements...), collection...)
+ } else if i < 0 {
+ // backward
+ i = sizeCollection + i
+ }
+
+ return append(append(append(output, collection[:i]...), elements...), collection[i:]...)
+}
diff --git a/vendor/github.com/samber/lo/string.go b/vendor/github.com/samber/lo/string.go
new file mode 100644
index 00000000..1d808788
--- /dev/null
+++ b/vendor/github.com/samber/lo/string.go
@@ -0,0 +1,180 @@
+package lo
+
+import (
+ "regexp"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/samber/lo/internal/rand"
+
+ "golang.org/x/text/cases"
+ "golang.org/x/text/language"
+)
+
+var (
+ LowerCaseLettersCharset = []rune("abcdefghijklmnopqrstuvwxyz")
+ UpperCaseLettersCharset = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+ LettersCharset = append(LowerCaseLettersCharset, UpperCaseLettersCharset...)
+ NumbersCharset = []rune("0123456789")
+ AlphanumericCharset = append(LettersCharset, NumbersCharset...)
+ SpecialCharset = []rune("!@#$%^&*()_+-=[]{}|;':\",./<>?")
+ AllCharset = append(AlphanumericCharset, SpecialCharset...)
+
+ // bearer:disable go_lang_permissive_regex_validation
+ splitWordReg = regexp.MustCompile(`([a-z])([A-Z0-9])|([a-zA-Z])([0-9])|([0-9])([a-zA-Z])|([A-Z])([A-Z])([a-z])`)
+ // bearer:disable go_lang_permissive_regex_validation
+ splitNumberLetterReg = regexp.MustCompile(`([0-9])([a-zA-Z])`)
+)
+
+// RandomString return a random string.
+// Play: https://go.dev/play/p/rRseOQVVum4
+func RandomString(size int, charset []rune) string {
+ if size <= 0 {
+ panic("lo.RandomString: Size parameter must be greater than 0")
+ }
+ if len(charset) <= 0 {
+ panic("lo.RandomString: Charset parameter must not be empty")
+ }
+
+ b := make([]rune, size)
+ possibleCharactersCount := len(charset)
+ for i := range b {
+ b[i] = charset[rand.IntN(possibleCharactersCount)]
+ }
+ return string(b)
+}
+
+// Substring return part of a string.
+// Play: https://go.dev/play/p/TQlxQi82Lu1
+func Substring[T ~string](str T, offset int, length uint) T {
+ rs := []rune(str)
+ size := len(rs)
+
+ if offset < 0 {
+ offset = size + offset
+ if offset < 0 {
+ offset = 0
+ }
+ }
+
+ if offset >= size {
+ return Empty[T]()
+ }
+
+ if length > uint(size)-uint(offset) {
+ length = uint(size - offset)
+ }
+
+ return T(strings.Replace(string(rs[offset:offset+int(length)]), "\x00", "", -1))
+}
+
+// ChunkString returns an array of strings split into groups the length of size. If array can't be split evenly,
+// the final chunk will be the remaining elements.
+// Play: https://go.dev/play/p/__FLTuJVz54
+func ChunkString[T ~string](str T, size int) []T {
+ if size <= 0 {
+ panic("lo.ChunkString: Size parameter must be greater than 0")
+ }
+
+ if len(str) == 0 {
+ return []T{""}
+ }
+
+ if size >= len(str) {
+ return []T{str}
+ }
+
+ var chunks []T = make([]T, 0, ((len(str)-1)/size)+1)
+ currentLen := 0
+ currentStart := 0
+ for i := range str {
+ if currentLen == size {
+ chunks = append(chunks, str[currentStart:i])
+ currentLen = 0
+ currentStart = i
+ }
+ currentLen++
+ }
+ chunks = append(chunks, str[currentStart:])
+ return chunks
+}
+
+// RuneLength is an alias to utf8.RuneCountInString which returns the number of runes in string.
+// Play: https://go.dev/play/p/tuhgW_lWY8l
+func RuneLength(str string) int {
+ return utf8.RuneCountInString(str)
+}
+
+// PascalCase converts string to pascal case.
+func PascalCase(str string) string {
+ items := Words(str)
+ for i := range items {
+ items[i] = Capitalize(items[i])
+ }
+ return strings.Join(items, "")
+}
+
+// CamelCase converts string to camel case.
+func CamelCase(str string) string {
+ items := Words(str)
+ for i, item := range items {
+ item = strings.ToLower(item)
+ if i > 0 {
+ item = Capitalize(item)
+ }
+ items[i] = item
+ }
+ return strings.Join(items, "")
+}
+
+// KebabCase converts string to kebab case.
+func KebabCase(str string) string {
+ items := Words(str)
+ for i := range items {
+ items[i] = strings.ToLower(items[i])
+ }
+ return strings.Join(items, "-")
+}
+
+// SnakeCase converts string to snake case.
+func SnakeCase(str string) string {
+ items := Words(str)
+ for i := range items {
+ items[i] = strings.ToLower(items[i])
+ }
+ return strings.Join(items, "_")
+}
+
+// Words splits string into an array of its words.
+func Words(str string) []string {
+ str = splitWordReg.ReplaceAllString(str, `$1$3$5$7 $2$4$6$8$9`)
+ // example: Int8Value => Int 8Value => Int 8 Value
+ str = splitNumberLetterReg.ReplaceAllString(str, "$1 $2")
+ var result strings.Builder
+ for _, r := range str {
+ if unicode.IsLetter(r) || unicode.IsDigit(r) {
+ result.WriteRune(r)
+ } else {
+ result.WriteRune(' ')
+ }
+ }
+ return strings.Fields(result.String())
+}
+
+// Capitalize converts the first character of string to upper case and the remaining to lower case.
+func Capitalize(str string) string {
+ return cases.Title(language.English).String(str)
+}
+
+// Elipse truncates a string to a specified length and appends an ellipsis if truncated.
+func Elipse(str string, length int) string {
+ if len(str) > length {
+ if len(str) < 3 || length < 3 {
+ return "..."
+ }
+ return str[0:length-3] + "..."
+ }
+
+ return str
+}
diff --git a/vendor/github.com/samber/lo/time.go b/vendor/github.com/samber/lo/time.go
new file mode 100644
index 00000000..e98e80f9
--- /dev/null
+++ b/vendor/github.com/samber/lo/time.go
@@ -0,0 +1,85 @@
+package lo
+
+import "time"
+
+// Duration returns the time taken to execute a function.
+func Duration(cb func()) time.Duration {
+ return Duration0(cb)
+}
+
+// Duration0 returns the time taken to execute a function.
+func Duration0(cb func()) time.Duration {
+ start := time.Now()
+ cb()
+ return time.Since(start)
+}
+
+// Duration1 returns the time taken to execute a function.
+func Duration1[A any](cb func() A) (A, time.Duration) {
+ start := time.Now()
+ a := cb()
+ return a, time.Since(start)
+}
+
+// Duration2 returns the time taken to execute a function.
+func Duration2[A, B any](cb func() (A, B)) (A, B, time.Duration) {
+ start := time.Now()
+ a, b := cb()
+ return a, b, time.Since(start)
+}
+
+// Duration3 returns the time taken to execute a function.
+func Duration3[A, B, C any](cb func() (A, B, C)) (A, B, C, time.Duration) {
+ start := time.Now()
+ a, b, c := cb()
+ return a, b, c, time.Since(start)
+}
+
+// Duration4 returns the time taken to execute a function.
+func Duration4[A, B, C, D any](cb func() (A, B, C, D)) (A, B, C, D, time.Duration) {
+ start := time.Now()
+ a, b, c, d := cb()
+ return a, b, c, d, time.Since(start)
+}
+
+// Duration5 returns the time taken to execute a function.
+func Duration5[A, B, C, D, E any](cb func() (A, B, C, D, E)) (A, B, C, D, E, time.Duration) {
+ start := time.Now()
+ a, b, c, d, e := cb()
+ return a, b, c, d, e, time.Since(start)
+}
+
+// Duration6 returns the time taken to execute a function.
+func Duration6[A, B, C, D, E, F any](cb func() (A, B, C, D, E, F)) (A, B, C, D, E, F, time.Duration) {
+ start := time.Now()
+ a, b, c, d, e, f := cb()
+ return a, b, c, d, e, f, time.Since(start)
+}
+
+// Duration7 returns the time taken to execute a function.
+func Duration7[A, B, C, D, E, F, G any](cb func() (A, B, C, D, E, F, G)) (A, B, C, D, E, F, G, time.Duration) {
+ start := time.Now()
+ a, b, c, d, e, f, g := cb()
+ return a, b, c, d, e, f, g, time.Since(start)
+}
+
+// Duration8 returns the time taken to execute a function.
+func Duration8[A, B, C, D, E, F, G, H any](cb func() (A, B, C, D, E, F, G, H)) (A, B, C, D, E, F, G, H, time.Duration) {
+ start := time.Now()
+ a, b, c, d, e, f, g, h := cb()
+ return a, b, c, d, e, f, g, h, time.Since(start)
+}
+
+// Duration9 returns the time taken to execute a function.
+func Duration9[A, B, C, D, E, F, G, H, I any](cb func() (A, B, C, D, E, F, G, H, I)) (A, B, C, D, E, F, G, H, I, time.Duration) {
+ start := time.Now()
+ a, b, c, d, e, f, g, h, i := cb()
+ return a, b, c, d, e, f, g, h, i, time.Since(start)
+}
+
+// Duration10 returns the time taken to execute a function.
+func Duration10[A, B, C, D, E, F, G, H, I, J any](cb func() (A, B, C, D, E, F, G, H, I, J)) (A, B, C, D, E, F, G, H, I, J, time.Duration) {
+ start := time.Now()
+ a, b, c, d, e, f, g, h, i, j := cb()
+ return a, b, c, d, e, f, g, h, i, j, time.Since(start)
+}
diff --git a/vendor/github.com/samber/lo/tuples.go b/vendor/github.com/samber/lo/tuples.go
new file mode 100644
index 00000000..18a03009
--- /dev/null
+++ b/vendor/github.com/samber/lo/tuples.go
@@ -0,0 +1,869 @@
+package lo
+
+// T2 creates a tuple from a list of values.
+// Play: https://go.dev/play/p/IllL3ZO4BQm
+func T2[A, B any](a A, b B) Tuple2[A, B] {
+ return Tuple2[A, B]{A: a, B: b}
+}
+
+// T3 creates a tuple from a list of values.
+// Play: https://go.dev/play/p/IllL3ZO4BQm
+func T3[A, B, C any](a A, b B, c C) Tuple3[A, B, C] {
+ return Tuple3[A, B, C]{A: a, B: b, C: c}
+}
+
+// T4 creates a tuple from a list of values.
+// Play: https://go.dev/play/p/IllL3ZO4BQm
+func T4[A, B, C, D any](a A, b B, c C, d D) Tuple4[A, B, C, D] {
+ return Tuple4[A, B, C, D]{A: a, B: b, C: c, D: d}
+}
+
+// T5 creates a tuple from a list of values.
+// Play: https://go.dev/play/p/IllL3ZO4BQm
+func T5[A, B, C, D, E any](a A, b B, c C, d D, e E) Tuple5[A, B, C, D, E] {
+ return Tuple5[A, B, C, D, E]{A: a, B: b, C: c, D: d, E: e}
+}
+
+// T6 creates a tuple from a list of values.
+// Play: https://go.dev/play/p/IllL3ZO4BQm
+func T6[A, B, C, D, E, F any](a A, b B, c C, d D, e E, f F) Tuple6[A, B, C, D, E, F] {
+ return Tuple6[A, B, C, D, E, F]{A: a, B: b, C: c, D: d, E: e, F: f}
+}
+
+// T7 creates a tuple from a list of values.
+// Play: https://go.dev/play/p/IllL3ZO4BQm
+func T7[A, B, C, D, E, F, G any](a A, b B, c C, d D, e E, f F, g G) Tuple7[A, B, C, D, E, F, G] {
+ return Tuple7[A, B, C, D, E, F, G]{A: a, B: b, C: c, D: d, E: e, F: f, G: g}
+}
+
+// T8 creates a tuple from a list of values.
+// Play: https://go.dev/play/p/IllL3ZO4BQm
+func T8[A, B, C, D, E, F, G, H any](a A, b B, c C, d D, e E, f F, g G, h H) Tuple8[A, B, C, D, E, F, G, H] {
+ return Tuple8[A, B, C, D, E, F, G, H]{A: a, B: b, C: c, D: d, E: e, F: f, G: g, H: h}
+}
+
+// T9 creates a tuple from a list of values.
+// Play: https://go.dev/play/p/IllL3ZO4BQm
+func T9[A, B, C, D, E, F, G, H, I any](a A, b B, c C, d D, e E, f F, g G, h H, i I) Tuple9[A, B, C, D, E, F, G, H, I] {
+ return Tuple9[A, B, C, D, E, F, G, H, I]{A: a, B: b, C: c, D: d, E: e, F: f, G: g, H: h, I: i}
+}
+
+// Unpack2 returns values contained in tuple.
+// Play: https://go.dev/play/p/xVP_k0kJ96W
+func Unpack2[A, B any](tuple Tuple2[A, B]) (A, B) {
+ return tuple.A, tuple.B
+}
+
+// Unpack3 returns values contained in tuple.
+// Play: https://go.dev/play/p/xVP_k0kJ96W
+func Unpack3[A, B, C any](tuple Tuple3[A, B, C]) (A, B, C) {
+ return tuple.A, tuple.B, tuple.C
+}
+
+// Unpack4 returns values contained in tuple.
+// Play: https://go.dev/play/p/xVP_k0kJ96W
+func Unpack4[A, B, C, D any](tuple Tuple4[A, B, C, D]) (A, B, C, D) {
+ return tuple.A, tuple.B, tuple.C, tuple.D
+}
+
+// Unpack5 returns values contained in tuple.
+// Play: https://go.dev/play/p/xVP_k0kJ96W
+func Unpack5[A, B, C, D, E any](tuple Tuple5[A, B, C, D, E]) (A, B, C, D, E) {
+ return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E
+}
+
+// Unpack6 returns values contained in tuple.
+// Play: https://go.dev/play/p/xVP_k0kJ96W
+func Unpack6[A, B, C, D, E, F any](tuple Tuple6[A, B, C, D, E, F]) (A, B, C, D, E, F) {
+ return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E, tuple.F
+}
+
+// Unpack7 returns values contained in tuple.
+// Play: https://go.dev/play/p/xVP_k0kJ96W
+func Unpack7[A, B, C, D, E, F, G any](tuple Tuple7[A, B, C, D, E, F, G]) (A, B, C, D, E, F, G) {
+ return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E, tuple.F, tuple.G
+}
+
+// Unpack8 returns values contained in tuple.
+// Play: https://go.dev/play/p/xVP_k0kJ96W
+func Unpack8[A, B, C, D, E, F, G, H any](tuple Tuple8[A, B, C, D, E, F, G, H]) (A, B, C, D, E, F, G, H) {
+ return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E, tuple.F, tuple.G, tuple.H
+}
+
+// Unpack9 returns values contained in tuple.
+// Play: https://go.dev/play/p/xVP_k0kJ96W
+func Unpack9[A, B, C, D, E, F, G, H, I any](tuple Tuple9[A, B, C, D, E, F, G, H, I]) (A, B, C, D, E, F, G, H, I) {
+ return tuple.A, tuple.B, tuple.C, tuple.D, tuple.E, tuple.F, tuple.G, tuple.H, tuple.I
+}
+
+// Zip2 creates a slice of grouped elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+// Play: https://go.dev/play/p/jujaA6GaJTp
+func Zip2[A, B any](a []A, b []B) []Tuple2[A, B] {
+ size := Max([]int{len(a), len(b)})
+
+ result := make([]Tuple2[A, B], 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+
+ result = append(result, Tuple2[A, B]{
+ A: _a,
+ B: _b,
+ })
+ }
+
+ return result
+}
+
+// Zip3 creates a slice of grouped elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+// Play: https://go.dev/play/p/jujaA6GaJTp
+func Zip3[A, B, C any](a []A, b []B, c []C) []Tuple3[A, B, C] {
+ size := Max([]int{len(a), len(b), len(c)})
+
+ result := make([]Tuple3[A, B, C], 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+
+ result = append(result, Tuple3[A, B, C]{
+ A: _a,
+ B: _b,
+ C: _c,
+ })
+ }
+
+ return result
+}
+
+// Zip4 creates a slice of grouped elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+// Play: https://go.dev/play/p/jujaA6GaJTp
+func Zip4[A, B, C, D any](a []A, b []B, c []C, d []D) []Tuple4[A, B, C, D] {
+ size := Max([]int{len(a), len(b), len(c), len(d)})
+
+ result := make([]Tuple4[A, B, C, D], 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+
+ result = append(result, Tuple4[A, B, C, D]{
+ A: _a,
+ B: _b,
+ C: _c,
+ D: _d,
+ })
+ }
+
+ return result
+}
+
+// Zip5 creates a slice of grouped elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+// Play: https://go.dev/play/p/jujaA6GaJTp
+func Zip5[A, B, C, D, E any](a []A, b []B, c []C, d []D, e []E) []Tuple5[A, B, C, D, E] {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e)})
+
+ result := make([]Tuple5[A, B, C, D, E], 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+
+ result = append(result, Tuple5[A, B, C, D, E]{
+ A: _a,
+ B: _b,
+ C: _c,
+ D: _d,
+ E: _e,
+ })
+ }
+
+ return result
+}
+
+// Zip6 creates a slice of grouped elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+// Play: https://go.dev/play/p/jujaA6GaJTp
+func Zip6[A, B, C, D, E, F any](a []A, b []B, c []C, d []D, e []E, f []F) []Tuple6[A, B, C, D, E, F] {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f)})
+
+ result := make([]Tuple6[A, B, C, D, E, F], 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+ _f, _ := Nth(f, index)
+
+ result = append(result, Tuple6[A, B, C, D, E, F]{
+ A: _a,
+ B: _b,
+ C: _c,
+ D: _d,
+ E: _e,
+ F: _f,
+ })
+ }
+
+ return result
+}
+
+// Zip7 creates a slice of grouped elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+// Play: https://go.dev/play/p/jujaA6GaJTp
+func Zip7[A, B, C, D, E, F, G any](a []A, b []B, c []C, d []D, e []E, f []F, g []G) []Tuple7[A, B, C, D, E, F, G] {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f), len(g)})
+
+ result := make([]Tuple7[A, B, C, D, E, F, G], 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+ _f, _ := Nth(f, index)
+ _g, _ := Nth(g, index)
+
+ result = append(result, Tuple7[A, B, C, D, E, F, G]{
+ A: _a,
+ B: _b,
+ C: _c,
+ D: _d,
+ E: _e,
+ F: _f,
+ G: _g,
+ })
+ }
+
+ return result
+}
+
+// Zip8 creates a slice of grouped elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+// Play: https://go.dev/play/p/jujaA6GaJTp
+func Zip8[A, B, C, D, E, F, G, H any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H) []Tuple8[A, B, C, D, E, F, G, H] {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h)})
+
+ result := make([]Tuple8[A, B, C, D, E, F, G, H], 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+ _f, _ := Nth(f, index)
+ _g, _ := Nth(g, index)
+ _h, _ := Nth(h, index)
+
+ result = append(result, Tuple8[A, B, C, D, E, F, G, H]{
+ A: _a,
+ B: _b,
+ C: _c,
+ D: _d,
+ E: _e,
+ F: _f,
+ G: _g,
+ H: _h,
+ })
+ }
+
+ return result
+}
+
+// Zip9 creates a slice of grouped elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+// Play: https://go.dev/play/p/jujaA6GaJTp
+func Zip9[A, B, C, D, E, F, G, H, I any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I) []Tuple9[A, B, C, D, E, F, G, H, I] {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h), len(i)})
+
+ result := make([]Tuple9[A, B, C, D, E, F, G, H, I], 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+ _f, _ := Nth(f, index)
+ _g, _ := Nth(g, index)
+ _h, _ := Nth(h, index)
+ _i, _ := Nth(i, index)
+
+ result = append(result, Tuple9[A, B, C, D, E, F, G, H, I]{
+ A: _a,
+ B: _b,
+ C: _c,
+ D: _d,
+ E: _e,
+ F: _f,
+ G: _g,
+ H: _h,
+ I: _i,
+ })
+ }
+
+ return result
+}
+
+// ZipBy2 creates a slice of transformed elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+func ZipBy2[A any, B any, Out any](a []A, b []B, iteratee func(a A, b B) Out) []Out {
+ size := Max([]int{len(a), len(b)})
+
+ result := make([]Out, 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+
+ result = append(result, iteratee(_a, _b))
+ }
+
+ return result
+}
+
+// ZipBy3 creates a slice of transformed elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+func ZipBy3[A any, B any, C any, Out any](a []A, b []B, c []C, iteratee func(a A, b B, c C) Out) []Out {
+ size := Max([]int{len(a), len(b), len(c)})
+
+ result := make([]Out, 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+
+ result = append(result, iteratee(_a, _b, _c))
+ }
+
+ return result
+}
+
+// ZipBy4 creates a slice of transformed elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+func ZipBy4[A any, B any, C any, D any, Out any](a []A, b []B, c []C, d []D, iteratee func(a A, b B, c C, d D) Out) []Out {
+ size := Max([]int{len(a), len(b), len(c), len(d)})
+
+ result := make([]Out, 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+
+ result = append(result, iteratee(_a, _b, _c, _d))
+ }
+
+ return result
+}
+
+// ZipBy5 creates a slice of transformed elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+func ZipBy5[A any, B any, C any, D any, E any, Out any](a []A, b []B, c []C, d []D, e []E, iteratee func(a A, b B, c C, d D, e E) Out) []Out {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e)})
+
+ result := make([]Out, 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+
+ result = append(result, iteratee(_a, _b, _c, _d, _e))
+ }
+
+ return result
+}
+
+// ZipBy6 creates a slice of transformed elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+func ZipBy6[A any, B any, C any, D any, E any, F any, Out any](a []A, b []B, c []C, d []D, e []E, f []F, iteratee func(a A, b B, c C, d D, e E, f F) Out) []Out {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f)})
+
+ result := make([]Out, 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+ _f, _ := Nth(f, index)
+
+ result = append(result, iteratee(_a, _b, _c, _d, _e, _f))
+ }
+
+ return result
+}
+
+// ZipBy7 creates a slice of transformed elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+func ZipBy7[A any, B any, C any, D any, E any, F any, G any, Out any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, iteratee func(a A, b B, c C, d D, e E, f F, g G) Out) []Out {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f)})
+
+ result := make([]Out, 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+ _f, _ := Nth(f, index)
+ _g, _ := Nth(g, index)
+
+ result = append(result, iteratee(_a, _b, _c, _d, _e, _f, _g))
+ }
+
+ return result
+}
+
+// ZipBy8 creates a slice of transformed elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+func ZipBy8[A any, B any, C any, D any, E any, F any, G any, H any, Out any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, iteratee func(a A, b B, c C, d D, e E, f F, g G, h H) Out) []Out {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f), len(g)})
+
+ result := make([]Out, 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+ _f, _ := Nth(f, index)
+ _g, _ := Nth(g, index)
+ _h, _ := Nth(h, index)
+
+ result = append(result, iteratee(_a, _b, _c, _d, _e, _f, _g, _h))
+ }
+
+ return result
+}
+
+// ZipBy9 creates a slice of transformed elements, the first of which contains the first elements
+// of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+// When collections have different size, the Tuple attributes are filled with zero value.
+func ZipBy9[A any, B any, C any, D any, E any, F any, G any, H any, I any, Out any](a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I, iteratee func(a A, b B, c C, d D, e E, f F, g G, h H, i I) Out) []Out {
+ size := Max([]int{len(a), len(b), len(c), len(d), len(e), len(f), len(g), len(h), len(i)})
+
+ result := make([]Out, 0, size)
+
+ for index := 0; index < size; index++ {
+ _a, _ := Nth(a, index)
+ _b, _ := Nth(b, index)
+ _c, _ := Nth(c, index)
+ _d, _ := Nth(d, index)
+ _e, _ := Nth(e, index)
+ _f, _ := Nth(f, index)
+ _g, _ := Nth(g, index)
+ _h, _ := Nth(h, index)
+ _i, _ := Nth(i, index)
+
+ result = append(result, iteratee(_a, _b, _c, _d, _e, _f, _g, _h, _i))
+ }
+
+ return result
+}
+
+// Unzip2 accepts an array of grouped elements and creates an array regrouping the elements
+// to their pre-zip configuration.
+// Play: https://go.dev/play/p/ciHugugvaAW
+func Unzip2[A, B any](tuples []Tuple2[A, B]) ([]A, []B) {
+ size := len(tuples)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+
+ for i := range tuples {
+ r1 = append(r1, tuples[i].A)
+ r2 = append(r2, tuples[i].B)
+ }
+
+ return r1, r2
+}
+
+// Unzip3 accepts an array of grouped elements and creates an array regrouping the elements
+// to their pre-zip configuration.
+// Play: https://go.dev/play/p/ciHugugvaAW
+func Unzip3[A, B, C any](tuples []Tuple3[A, B, C]) ([]A, []B, []C) {
+ size := len(tuples)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+
+ for i := range tuples {
+ r1 = append(r1, tuples[i].A)
+ r2 = append(r2, tuples[i].B)
+ r3 = append(r3, tuples[i].C)
+ }
+
+ return r1, r2, r3
+}
+
+// Unzip4 accepts an array of grouped elements and creates an array regrouping the elements
+// to their pre-zip configuration.
+// Play: https://go.dev/play/p/ciHugugvaAW
+func Unzip4[A, B, C, D any](tuples []Tuple4[A, B, C, D]) ([]A, []B, []C, []D) {
+ size := len(tuples)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+
+ for i := range tuples {
+ r1 = append(r1, tuples[i].A)
+ r2 = append(r2, tuples[i].B)
+ r3 = append(r3, tuples[i].C)
+ r4 = append(r4, tuples[i].D)
+ }
+
+ return r1, r2, r3, r4
+}
+
+// Unzip5 accepts an array of grouped elements and creates an array regrouping the elements
+// to their pre-zip configuration.
+// Play: https://go.dev/play/p/ciHugugvaAW
+func Unzip5[A, B, C, D, E any](tuples []Tuple5[A, B, C, D, E]) ([]A, []B, []C, []D, []E) {
+ size := len(tuples)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+
+ for i := range tuples {
+ r1 = append(r1, tuples[i].A)
+ r2 = append(r2, tuples[i].B)
+ r3 = append(r3, tuples[i].C)
+ r4 = append(r4, tuples[i].D)
+ r5 = append(r5, tuples[i].E)
+ }
+
+ return r1, r2, r3, r4, r5
+}
+
+// Unzip6 accepts an array of grouped elements and creates an array regrouping the elements
+// to their pre-zip configuration.
+// Play: https://go.dev/play/p/ciHugugvaAW
+func Unzip6[A, B, C, D, E, F any](tuples []Tuple6[A, B, C, D, E, F]) ([]A, []B, []C, []D, []E, []F) {
+ size := len(tuples)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+ r6 := make([]F, 0, size)
+
+ for i := range tuples {
+ r1 = append(r1, tuples[i].A)
+ r2 = append(r2, tuples[i].B)
+ r3 = append(r3, tuples[i].C)
+ r4 = append(r4, tuples[i].D)
+ r5 = append(r5, tuples[i].E)
+ r6 = append(r6, tuples[i].F)
+ }
+
+ return r1, r2, r3, r4, r5, r6
+}
+
+// Unzip7 accepts an array of grouped elements and creates an array regrouping the elements
+// to their pre-zip configuration.
+// Play: https://go.dev/play/p/ciHugugvaAW
+func Unzip7[A, B, C, D, E, F, G any](tuples []Tuple7[A, B, C, D, E, F, G]) ([]A, []B, []C, []D, []E, []F, []G) {
+ size := len(tuples)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+ r6 := make([]F, 0, size)
+ r7 := make([]G, 0, size)
+
+ for i := range tuples {
+ r1 = append(r1, tuples[i].A)
+ r2 = append(r2, tuples[i].B)
+ r3 = append(r3, tuples[i].C)
+ r4 = append(r4, tuples[i].D)
+ r5 = append(r5, tuples[i].E)
+ r6 = append(r6, tuples[i].F)
+ r7 = append(r7, tuples[i].G)
+ }
+
+ return r1, r2, r3, r4, r5, r6, r7
+}
+
+// Unzip8 accepts an array of grouped elements and creates an array regrouping the elements
+// to their pre-zip configuration.
+// Play: https://go.dev/play/p/ciHugugvaAW
+func Unzip8[A, B, C, D, E, F, G, H any](tuples []Tuple8[A, B, C, D, E, F, G, H]) ([]A, []B, []C, []D, []E, []F, []G, []H) {
+ size := len(tuples)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+ r6 := make([]F, 0, size)
+ r7 := make([]G, 0, size)
+ r8 := make([]H, 0, size)
+
+ for i := range tuples {
+ r1 = append(r1, tuples[i].A)
+ r2 = append(r2, tuples[i].B)
+ r3 = append(r3, tuples[i].C)
+ r4 = append(r4, tuples[i].D)
+ r5 = append(r5, tuples[i].E)
+ r6 = append(r6, tuples[i].F)
+ r7 = append(r7, tuples[i].G)
+ r8 = append(r8, tuples[i].H)
+ }
+
+ return r1, r2, r3, r4, r5, r6, r7, r8
+}
+
+// Unzip9 accepts an array of grouped elements and creates an array regrouping the elements
+// to their pre-zip configuration.
+// Play: https://go.dev/play/p/ciHugugvaAW
+func Unzip9[A, B, C, D, E, F, G, H, I any](tuples []Tuple9[A, B, C, D, E, F, G, H, I]) ([]A, []B, []C, []D, []E, []F, []G, []H, []I) {
+ size := len(tuples)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+ r6 := make([]F, 0, size)
+ r7 := make([]G, 0, size)
+ r8 := make([]H, 0, size)
+ r9 := make([]I, 0, size)
+
+ for i := range tuples {
+ r1 = append(r1, tuples[i].A)
+ r2 = append(r2, tuples[i].B)
+ r3 = append(r3, tuples[i].C)
+ r4 = append(r4, tuples[i].D)
+ r5 = append(r5, tuples[i].E)
+ r6 = append(r6, tuples[i].F)
+ r7 = append(r7, tuples[i].G)
+ r8 = append(r8, tuples[i].H)
+ r9 = append(r9, tuples[i].I)
+ }
+
+ return r1, r2, r3, r4, r5, r6, r7, r8, r9
+}
+
+// UnzipBy2 iterates over a collection and creates an array regrouping the elements
+// to their pre-zip configuration.
+func UnzipBy2[In any, A any, B any](items []In, iteratee func(In) (a A, b B)) ([]A, []B) {
+ size := len(items)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+
+ for i := range items {
+ a, b := iteratee(items[i])
+ r1 = append(r1, a)
+ r2 = append(r2, b)
+ }
+
+ return r1, r2
+}
+
+// UnzipBy3 iterates over a collection and creates an array regrouping the elements
+// to their pre-zip configuration.
+func UnzipBy3[In any, A any, B any, C any](items []In, iteratee func(In) (a A, b B, c C)) ([]A, []B, []C) {
+ size := len(items)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+
+ for i := range items {
+ a, b, c := iteratee(items[i])
+ r1 = append(r1, a)
+ r2 = append(r2, b)
+ r3 = append(r3, c)
+ }
+
+ return r1, r2, r3
+}
+
+// UnzipBy4 iterates over a collection and creates an array regrouping the elements
+// to their pre-zip configuration.
+func UnzipBy4[In any, A any, B any, C any, D any](items []In, iteratee func(In) (a A, b B, c C, d D)) ([]A, []B, []C, []D) {
+ size := len(items)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+
+ for i := range items {
+ a, b, c, d := iteratee(items[i])
+ r1 = append(r1, a)
+ r2 = append(r2, b)
+ r3 = append(r3, c)
+ r4 = append(r4, d)
+ }
+
+ return r1, r2, r3, r4
+}
+
+// UnzipBy5 iterates over a collection and creates an array regrouping the elements
+// to their pre-zip configuration.
+func UnzipBy5[In any, A any, B any, C any, D any, E any](items []In, iteratee func(In) (a A, b B, c C, d D, e E)) ([]A, []B, []C, []D, []E) {
+ size := len(items)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+
+ for i := range items {
+ a, b, c, d, e := iteratee(items[i])
+ r1 = append(r1, a)
+ r2 = append(r2, b)
+ r3 = append(r3, c)
+ r4 = append(r4, d)
+ r5 = append(r5, e)
+ }
+
+ return r1, r2, r3, r4, r5
+}
+
+// UnzipBy6 iterates over a collection and creates an array regrouping the elements
+// to their pre-zip configuration.
+func UnzipBy6[In any, A any, B any, C any, D any, E any, F any](items []In, iteratee func(In) (a A, b B, c C, d D, e E, f F)) ([]A, []B, []C, []D, []E, []F) {
+ size := len(items)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+ r6 := make([]F, 0, size)
+
+ for i := range items {
+ a, b, c, d, e, f := iteratee(items[i])
+ r1 = append(r1, a)
+ r2 = append(r2, b)
+ r3 = append(r3, c)
+ r4 = append(r4, d)
+ r5 = append(r5, e)
+ r6 = append(r6, f)
+ }
+
+ return r1, r2, r3, r4, r5, r6
+}
+
+// UnzipBy7 iterates over a collection and creates an array regrouping the elements
+// to their pre-zip configuration.
+func UnzipBy7[In any, A any, B any, C any, D any, E any, F any, G any](items []In, iteratee func(In) (a A, b B, c C, d D, e E, f F, g G)) ([]A, []B, []C, []D, []E, []F, []G) {
+ size := len(items)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+ r6 := make([]F, 0, size)
+ r7 := make([]G, 0, size)
+
+ for i := range items {
+ a, b, c, d, e, f, g := iteratee(items[i])
+ r1 = append(r1, a)
+ r2 = append(r2, b)
+ r3 = append(r3, c)
+ r4 = append(r4, d)
+ r5 = append(r5, e)
+ r6 = append(r6, f)
+ r7 = append(r7, g)
+ }
+
+ return r1, r2, r3, r4, r5, r6, r7
+}
+
+// UnzipBy8 iterates over a collection and creates an array regrouping the elements
+// to their pre-zip configuration.
+func UnzipBy8[In any, A any, B any, C any, D any, E any, F any, G any, H any](items []In, iteratee func(In) (a A, b B, c C, d D, e E, f F, g G, h H)) ([]A, []B, []C, []D, []E, []F, []G, []H) {
+ size := len(items)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+ r6 := make([]F, 0, size)
+ r7 := make([]G, 0, size)
+ r8 := make([]H, 0, size)
+
+ for i := range items {
+ a, b, c, d, e, f, g, h := iteratee(items[i])
+ r1 = append(r1, a)
+ r2 = append(r2, b)
+ r3 = append(r3, c)
+ r4 = append(r4, d)
+ r5 = append(r5, e)
+ r6 = append(r6, f)
+ r7 = append(r7, g)
+ r8 = append(r8, h)
+ }
+
+ return r1, r2, r3, r4, r5, r6, r7, r8
+}
+
+// UnzipBy9 iterates over a collection and creates an array regrouping the elements
+// to their pre-zip configuration.
+func UnzipBy9[In any, A any, B any, C any, D any, E any, F any, G any, H any, I any](items []In, iteratee func(In) (a A, b B, c C, d D, e E, f F, g G, h H, i I)) ([]A, []B, []C, []D, []E, []F, []G, []H, []I) {
+ size := len(items)
+ r1 := make([]A, 0, size)
+ r2 := make([]B, 0, size)
+ r3 := make([]C, 0, size)
+ r4 := make([]D, 0, size)
+ r5 := make([]E, 0, size)
+ r6 := make([]F, 0, size)
+ r7 := make([]G, 0, size)
+ r8 := make([]H, 0, size)
+ r9 := make([]I, 0, size)
+
+ for i := range items {
+ a, b, c, d, e, f, g, h, i := iteratee(items[i])
+ r1 = append(r1, a)
+ r2 = append(r2, b)
+ r3 = append(r3, c)
+ r4 = append(r4, d)
+ r5 = append(r5, e)
+ r6 = append(r6, f)
+ r7 = append(r7, g)
+ r8 = append(r8, h)
+ r9 = append(r9, i)
+ }
+
+ return r1, r2, r3, r4, r5, r6, r7, r8, r9
+}
diff --git a/vendor/github.com/samber/lo/type_manipulation.go b/vendor/github.com/samber/lo/type_manipulation.go
new file mode 100644
index 00000000..ef070281
--- /dev/null
+++ b/vendor/github.com/samber/lo/type_manipulation.go
@@ -0,0 +1,143 @@
+package lo
+
+import "reflect"
+
+// IsNil checks if a value is nil or if it's a reference type with a nil underlying value.
+func IsNil(x any) bool {
+ defer func() { recover() }() // nolint:errcheck
+ return x == nil || reflect.ValueOf(x).IsNil()
+}
+
+// ToPtr returns a pointer copy of value.
+func ToPtr[T any](x T) *T {
+ return &x
+}
+
+// Nil returns a nil pointer of type.
+func Nil[T any]() *T {
+ return nil
+}
+
+// EmptyableToPtr returns a pointer copy of value if it's nonzero.
+// Otherwise, returns nil pointer.
+func EmptyableToPtr[T any](x T) *T {
+ // 🤮
+ isZero := reflect.ValueOf(&x).Elem().IsZero()
+ if isZero {
+ return nil
+ }
+
+ return &x
+}
+
+// FromPtr returns the pointer value or empty.
+func FromPtr[T any](x *T) T {
+ if x == nil {
+ return Empty[T]()
+ }
+
+ return *x
+}
+
+// FromPtrOr returns the pointer value or the fallback value.
+func FromPtrOr[T any](x *T, fallback T) T {
+ if x == nil {
+ return fallback
+ }
+
+ return *x
+}
+
+// ToSlicePtr returns a slice of pointer copy of value.
+func ToSlicePtr[T any](collection []T) []*T {
+ result := make([]*T, len(collection))
+
+ for i := range collection {
+ result[i] = &collection[i]
+ }
+ return result
+}
+
+// FromSlicePtr returns a slice with the pointer values.
+// Returns a zero value in case of a nil pointer element.
+func FromSlicePtr[T any](collection []*T) []T {
+ return Map(collection, func(x *T, _ int) T {
+ if x == nil {
+ return Empty[T]()
+ }
+ return *x
+ })
+}
+
+// FromSlicePtr returns a slice with the pointer values or the fallback value.
+func FromSlicePtrOr[T any](collection []*T, fallback T) []T {
+ return Map(collection, func(x *T, _ int) T {
+ if x == nil {
+ return fallback
+ }
+ return *x
+ })
+}
+
+// ToAnySlice returns a slice with all elements mapped to `any` type
+func ToAnySlice[T any](collection []T) []any {
+ result := make([]any, len(collection))
+ for i := range collection {
+ result[i] = collection[i]
+ }
+ return result
+}
+
+// FromAnySlice returns an `any` slice with all elements mapped to a type.
+// Returns false in case of type conversion failure.
+func FromAnySlice[T any](in []any) (out []T, ok bool) {
+ defer func() {
+ if r := recover(); r != nil {
+ out = []T{}
+ ok = false
+ }
+ }()
+
+ result := make([]T, len(in))
+ for i := range in {
+ result[i] = in[i].(T)
+ }
+ return result, true
+}
+
+// Empty returns an empty value.
+func Empty[T any]() T {
+ var zero T
+ return zero
+}
+
+// IsEmpty returns true if argument is a zero value.
+func IsEmpty[T comparable](v T) bool {
+ var zero T
+ return zero == v
+}
+
+// IsNotEmpty returns true if argument is not a zero value.
+func IsNotEmpty[T comparable](v T) bool {
+ var zero T
+ return zero != v
+}
+
+// Coalesce returns the first non-empty arguments. Arguments must be comparable.
+func Coalesce[T comparable](values ...T) (result T, ok bool) {
+ for i := range values {
+ if values[i] != result {
+ result = values[i]
+ ok = true
+ return
+ }
+ }
+
+ return
+}
+
+// CoalesceOrEmpty returns the first non-empty arguments. Arguments must be comparable.
+func CoalesceOrEmpty[T comparable](v ...T) T {
+ result, _ := Coalesce(v...)
+ return result
+}
diff --git a/vendor/github.com/samber/lo/types.go b/vendor/github.com/samber/lo/types.go
new file mode 100644
index 00000000..1c6f0d00
--- /dev/null
+++ b/vendor/github.com/samber/lo/types.go
@@ -0,0 +1,123 @@
+package lo
+
+// Entry defines a key/value pairs.
+type Entry[K comparable, V any] struct {
+ Key K
+ Value V
+}
+
+// Tuple2 is a group of 2 elements (pair).
+type Tuple2[A, B any] struct {
+ A A
+ B B
+}
+
+// Unpack returns values contained in tuple.
+func (t Tuple2[A, B]) Unpack() (A, B) {
+ return t.A, t.B
+}
+
+// Tuple3 is a group of 3 elements.
+type Tuple3[A, B, C any] struct {
+ A A
+ B B
+ C C
+}
+
+// Unpack returns values contained in tuple.
+func (t Tuple3[A, B, C]) Unpack() (A, B, C) {
+ return t.A, t.B, t.C
+}
+
+// Tuple4 is a group of 4 elements.
+type Tuple4[A, B, C, D any] struct {
+ A A
+ B B
+ C C
+ D D
+}
+
+// Unpack returns values contained in tuple.
+func (t Tuple4[A, B, C, D]) Unpack() (A, B, C, D) {
+ return t.A, t.B, t.C, t.D
+}
+
+// Tuple5 is a group of 5 elements.
+type Tuple5[A, B, C, D, E any] struct {
+ A A
+ B B
+ C C
+ D D
+ E E
+}
+
+// Unpack returns values contained in tuple.
+func (t Tuple5[A, B, C, D, E]) Unpack() (A, B, C, D, E) {
+ return t.A, t.B, t.C, t.D, t.E
+}
+
+// Tuple6 is a group of 6 elements.
+type Tuple6[A, B, C, D, E, F any] struct {
+ A A
+ B B
+ C C
+ D D
+ E E
+ F F
+}
+
+// Unpack returns values contained in tuple.
+func (t Tuple6[A, B, C, D, E, F]) Unpack() (A, B, C, D, E, F) {
+ return t.A, t.B, t.C, t.D, t.E, t.F
+}
+
+// Tuple7 is a group of 7 elements.
+type Tuple7[A, B, C, D, E, F, G any] struct {
+ A A
+ B B
+ C C
+ D D
+ E E
+ F F
+ G G
+}
+
+// Unpack returns values contained in tuple.
+func (t Tuple7[A, B, C, D, E, F, G]) Unpack() (A, B, C, D, E, F, G) {
+ return t.A, t.B, t.C, t.D, t.E, t.F, t.G
+}
+
+// Tuple8 is a group of 8 elements.
+type Tuple8[A, B, C, D, E, F, G, H any] struct {
+ A A
+ B B
+ C C
+ D D
+ E E
+ F F
+ G G
+ H H
+}
+
+// Unpack returns values contained in tuple.
+func (t Tuple8[A, B, C, D, E, F, G, H]) Unpack() (A, B, C, D, E, F, G, H) {
+ return t.A, t.B, t.C, t.D, t.E, t.F, t.G, t.H
+}
+
+// Tuple9 is a group of 9 elements.
+type Tuple9[A, B, C, D, E, F, G, H, I any] struct {
+ A A
+ B B
+ C C
+ D D
+ E E
+ F F
+ G G
+ H H
+ I I
+}
+
+// Unpack returns values contained in tuple.
+func (t Tuple9[A, B, C, D, E, F, G, H, I]) Unpack() (A, B, C, D, E, F, G, H, I) {
+ return t.A, t.B, t.C, t.D, t.E, t.F, t.G, t.H, t.I
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index e635074d..4072a523 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -296,6 +296,11 @@ github.com/sagikazarmark/slog-shim
# github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f
## explicit
github.com/sahilm/fuzzy
+# github.com/samber/lo v1.47.0
+## explicit; go 1.18
+github.com/samber/lo
+github.com/samber/lo/internal/constraints
+github.com/samber/lo/internal/rand
# github.com/sourcegraph/conc v0.3.0
## explicit; go 1.19
github.com/sourcegraph/conc