From 7fea7c9d897a1cd4b3bd226e62e280670f28186c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 21 Mar 2024 20:55:37 +0000 Subject: [PATCH 01/48] kafka + lua scripting + flatbuffers (#1461) In theory kafka could be merged without lua, instead having some default json encoding, but that seems a bit pointless --- .github/workflows/flow.yml | 5 + flow/activities/flowable.go | 1 + flow/cmd/handler.go | 11 +- flow/connectors/core.go | 4 + flow/connectors/eventhub/eventhub.go | 12 +- flow/connectors/external_metadata/store.go | 7 + flow/connectors/kafka/kafka.go | 338 ++++++++++++++ flow/connectors/postgres/cdc.go | 33 +- flow/connectors/postgres/postgres.go | 6 +- .../cdc_records/cdc_records_storage_test.go | 5 +- flow/e2e/kafka/kafka_test.go | 137 ++++++ flow/go.mod | 7 + flow/go.sum | 14 + flow/model/model.go | 87 ++-- flow/model/qrecord_test.go | 4 +- flow/model/qvalue/qvalue.go | 5 +- flow/model/record_items.go | 3 +- flow/pua/peerdb.go | 442 ++++++++++++++++++ flow/pua/peerdb_test.go | 50 ++ nexus/analyzer/src/lib.rs | 49 +- nexus/catalog/migrations/V23__scripts.sql | 8 + nexus/catalog/src/lib.rs | 15 +- nexus/flow-rs/src/grpc.rs | 3 +- nexus/pt/src/flow_model.rs | 3 +- nexus/pt/src/lib.rs | 2 +- protos/flow.proto | 2 + protos/peers.proto | 11 + ui/README.md | 2 +- ui/app/api/peers/getTruePeer.ts | 16 +- ui/app/api/peers/info/[peerName]/route.ts | 5 + ui/app/api/peers/route.ts | 7 + ui/app/dto/PeersDTO.ts | 4 +- ui/app/mirrors/[mirrorId]/configValues.ts | 20 +- ui/app/mirrors/create/helpers/cdc.ts | 10 + ui/app/mirrors/create/helpers/common.ts | 1 + ui/app/peers/create/[peerType]/handlers.ts | 5 + ui/app/peers/create/[peerType]/helpers/ch.ts | 1 + .../peers/create/[peerType]/helpers/common.ts | 2 + ui/app/peers/create/[peerType]/helpers/ka.ts | 73 +++ ui/app/peers/create/[peerType]/page.tsx | 3 + ui/app/peers/create/[peerType]/schema.ts | 27 ++ ui/components/PeerComponent.tsx | 3 + ui/components/PeerForms/KafkaConfig.tsx | 116 +++++ ui/components/PeerTypeComponent.tsx | 2 + ui/components/SelectSource.tsx | 3 +- ui/public/svgs/kafka.svg | 1 + 46 files changed, 1462 insertions(+), 103 deletions(-) create mode 100644 flow/connectors/kafka/kafka.go create mode 100644 flow/e2e/kafka/kafka_test.go create mode 100644 flow/pua/peerdb.go create mode 100644 flow/pua/peerdb_test.go create mode 100644 nexus/catalog/migrations/V23__scripts.sql create mode 100644 ui/app/peers/create/[peerType]/helpers/ka.ts create mode 100644 ui/components/PeerForms/KafkaConfig.tsx create mode 100644 ui/public/svgs/kafka.svg diff --git a/.github/workflows/flow.yml b/.github/workflows/flow.yml index 38bc636f51..54919f0bde 100644 --- a/.github/workflows/flow.yml +++ b/.github/workflows/flow.yml @@ -86,6 +86,11 @@ jobs: env: PGPASSWORD: postgres + - name: start redpanda + uses: redpanda-data/github-action@v0.1.4 + with: + version: "latest" + - name: Install Temporal CLI uses: temporalio/setup-temporal@v0 diff --git a/flow/activities/flowable.go b/flow/activities/flowable.go index 52ab1a8ca7..3d6e7815b7 100644 --- a/flow/activities/flowable.go +++ b/flow/activities/flowable.go @@ -400,6 +400,7 @@ func (a *FlowableActivity) SyncFlow( FlowJobName: flowName, TableMappings: options.TableMappings, StagingPath: config.CdcStagingPath, + Script: config.Script, }) if err != nil { a.Alerter.LogFlowError(ctx, flowName, err) diff --git a/flow/cmd/handler.go b/flow/cmd/handler.go index 554e177dc1..f0264608bb 100644 --- a/flow/cmd/handler.go +++ b/flow/cmd/handler.go @@ -533,9 +533,7 @@ func (h *FlowRequestHandler) CreatePeer( return wrongConfigResponse, nil } pgConfig := pgConfigObject.PostgresConfig - encodedConfig, encodingErr = proto.Marshal(pgConfig) - case protos.DBType_SNOWFLAKE: sfConfigObject, ok := config.(*protos.Peer_SnowflakeConfig) if !ok { @@ -566,13 +564,18 @@ func (h *FlowRequestHandler) CreatePeer( encodedConfig, encodingErr = proto.Marshal(s3Config) case protos.DBType_CLICKHOUSE: chConfigObject, ok := config.(*protos.Peer_ClickhouseConfig) - if !ok { return wrongConfigResponse, nil } - chConfig := chConfigObject.ClickhouseConfig encodedConfig, encodingErr = proto.Marshal(chConfig) + case protos.DBType_KAFKA: + kaConfigObject, ok := config.(*protos.Peer_KafkaConfig) + if !ok { + return wrongConfigResponse, nil + } + kaConfig := kaConfigObject.KafkaConfig + encodedConfig, encodingErr = proto.Marshal(kaConfig) default: return wrongConfigResponse, nil } diff --git a/flow/connectors/core.go b/flow/connectors/core.go index 39e31f8171..4251c1726a 100644 --- a/flow/connectors/core.go +++ b/flow/connectors/core.go @@ -11,6 +11,7 @@ import ( connbigquery "github.com/PeerDB-io/peer-flow/connectors/bigquery" connclickhouse "github.com/PeerDB-io/peer-flow/connectors/clickhouse" conneventhub "github.com/PeerDB-io/peer-flow/connectors/eventhub" + connkafka "github.com/PeerDB-io/peer-flow/connectors/kafka" connpostgres "github.com/PeerDB-io/peer-flow/connectors/postgres" conns3 "github.com/PeerDB-io/peer-flow/connectors/s3" connsnowflake "github.com/PeerDB-io/peer-flow/connectors/snowflake" @@ -202,6 +203,8 @@ func GetConnector(ctx context.Context, config *protos.Peer) (Connector, error) { return connsqlserver.NewSQLServerConnector(ctx, inner.SqlserverConfig) case *protos.Peer_ClickhouseConfig: return connclickhouse.NewClickhouseConnector(ctx, inner.ClickhouseConfig) + case *protos.Peer_KafkaConfig: + return connkafka.NewKafkaConnector(ctx, inner.KafkaConfig) default: return nil, ErrUnsupportedFunctionality } @@ -260,6 +263,7 @@ var ( _ CDCSyncConnector = &connbigquery.BigQueryConnector{} _ CDCSyncConnector = &connsnowflake.SnowflakeConnector{} _ CDCSyncConnector = &conneventhub.EventHubConnector{} + _ CDCSyncConnector = &connkafka.KafkaConnector{} _ CDCSyncConnector = &conns3.S3Connector{} _ CDCSyncConnector = &connclickhouse.ClickhouseConnector{} diff --git a/flow/connectors/eventhub/eventhub.go b/flow/connectors/eventhub/eventhub.go index d34c1d9274..7d75298777 100644 --- a/flow/connectors/eventhub/eventhub.go +++ b/flow/connectors/eventhub/eventhub.go @@ -88,13 +88,7 @@ func (c *EventHubConnector) GetLastOffset(ctx context.Context, jobName string) ( } func (c *EventHubConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { - err := c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) - if err != nil { - c.logger.Error("failed to update last offset", slog.Any("error", err)) - return err - } - - return nil + return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) } // returns the number of records synced @@ -204,9 +198,7 @@ func (c *EventHubConnector) processBatch( } func (c *EventHubConnector) SyncRecords(ctx context.Context, req *model.SyncRecordsRequest) (*model.SyncResponse, error) { - batch := req.Records - - numRecords, err := c.processBatch(ctx, req.FlowJobName, batch) + numRecords, err := c.processBatch(ctx, req.FlowJobName, req.Records) if err != nil { c.logger.Error("failed to process batch", slog.Any("error", err)) return nil, err diff --git a/flow/connectors/external_metadata/store.go b/flow/connectors/external_metadata/store.go index 5fffec0f69..bbe986b497 100644 --- a/flow/connectors/external_metadata/store.go +++ b/flow/connectors/external_metadata/store.go @@ -55,6 +55,13 @@ func (p *PostgresMetadataStore) Ping(ctx context.Context) error { return nil } +func (p *PostgresMetadataStore) LogFlowInfo(ctx context.Context, flowName string, info string) error { + _, err := p.pool.Exec(ctx, + "INSERT INTO peerdb_stats.flow_errors(flow_name,error_message,error_type) VALUES($1,$2,$3)", + flowName, info, "info") + return err +} + func (p *PostgresMetadataStore) FetchLastOffset(ctx context.Context, jobName string) (int64, error) { row := p.pool.QueryRow(ctx, `SELECT last_offset FROM `+ diff --git a/flow/connectors/kafka/kafka.go b/flow/connectors/kafka/kafka.go new file mode 100644 index 0000000000..b879e31def --- /dev/null +++ b/flow/connectors/kafka/kafka.go @@ -0,0 +1,338 @@ +package connkafka + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "log/slog" + "strings" + "sync" + "unsafe" + + "github.com/twmb/franz-go/pkg/kgo" + "github.com/twmb/franz-go/pkg/sasl/plain" + "github.com/twmb/franz-go/pkg/sasl/scram" + "github.com/twmb/franz-go/plugin/kslog" + "github.com/yuin/gopher-lua" + "go.temporal.io/sdk/log" + + "github.com/PeerDB-io/gluaflatbuffers" + metadataStore "github.com/PeerDB-io/peer-flow/connectors/external_metadata" + "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/peerdbenv" + "github.com/PeerDB-io/peer-flow/pua" +) + +type KafkaConnector struct { + client *kgo.Client + pgMetadata *metadataStore.PostgresMetadataStore + logger log.Logger +} + +func unsafeFastStringToReadOnlyBytes(s string) []byte { + return unsafe.Slice(unsafe.StringData(s), len(s)) +} + +func LVAsReadOnlyBytes(ls *lua.LState, v lua.LValue) ([]byte, error) { + str, err := LVAsStringOrNil(ls, v) + if err != nil { + return nil, err + } else if str == "" { + return nil, nil + } else { + return unsafeFastStringToReadOnlyBytes(str), nil + } +} + +func LVAsStringOrNil(ls *lua.LState, v lua.LValue) (string, error) { + if lstr, ok := v.(lua.LString); ok { + return string(lstr), nil + } else if v == lua.LNil { + return "", nil + } else { + return "", fmt.Errorf("invalid bytes, must be nil or string: %s", v) + } +} + +func NewKafkaConnector( + ctx context.Context, + config *protos.KafkaConfig, +) (*KafkaConnector, error) { + optionalOpts := append( + make([]kgo.Opt, 0, 7), + kgo.SeedBrokers(config.Servers...), + kgo.AllowAutoTopicCreation(), + kgo.WithLogger(kslog.New(slog.Default())), // TODO use logger.LoggerFromCtx + kgo.SoftwareNameAndVersion("peerdb", peerdbenv.PeerDBVersionShaShort()), + ) + if !config.DisableTls { + optionalOpts = append(optionalOpts, kgo.DialTLSConfig(&tls.Config{MinVersion: tls.VersionTLS13})) + } + switch config.Partitioner { + case "LeastBackup": + optionalOpts = append(optionalOpts, kgo.RecordPartitioner(kgo.LeastBackupPartitioner())) + case "Manual": + optionalOpts = append(optionalOpts, kgo.RecordPartitioner(kgo.ManualPartitioner())) + case "RoundRobin": + optionalOpts = append(optionalOpts, kgo.RecordPartitioner(kgo.RoundRobinPartitioner())) + case "StickyKey": + optionalOpts = append(optionalOpts, kgo.RecordPartitioner(kgo.StickyKeyPartitioner(nil))) + case "Sticky": + optionalOpts = append(optionalOpts, kgo.RecordPartitioner(kgo.StickyPartitioner())) + } + if config.Username != "" { + switch config.Sasl { + case "PLAIN": + auth := plain.Auth{User: config.Username, Pass: config.Password} + optionalOpts = append(optionalOpts, kgo.SASL(auth.AsMechanism())) + case "SCRAM-SHA-256": + auth := scram.Auth{User: config.Username, Pass: config.Password} + optionalOpts = append(optionalOpts, kgo.SASL(auth.AsSha256Mechanism())) + case "SCRAM-SHA-512": + auth := scram.Auth{User: config.Username, Pass: config.Password} + optionalOpts = append(optionalOpts, kgo.SASL(auth.AsSha512Mechanism())) + default: + return nil, fmt.Errorf("unsupported SASL mechanism: %s", config.Sasl) + } + } + client, err := kgo.NewClient(optionalOpts...) + if err != nil { + return nil, fmt.Errorf("failed to create kafka client: %w", err) + } + + pgMetadata, err := metadataStore.NewPostgresMetadataStore(ctx) + if err != nil { + return nil, err + } + + return &KafkaConnector{ + client: client, + pgMetadata: pgMetadata, + logger: logger.LoggerFromCtx(ctx), + }, nil +} + +func (c *KafkaConnector) Close() error { + if c != nil { + c.client.Close() + } + return nil +} + +func (c *KafkaConnector) ConnectionActive(ctx context.Context) error { + return c.client.Ping(ctx) +} + +func (c *KafkaConnector) CreateRawTable(ctx context.Context, req *protos.CreateRawTableInput) (*protos.CreateRawTableOutput, error) { + return &protos.CreateRawTableOutput{TableIdentifier: "n/a"}, nil +} + +func (c *KafkaConnector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { + return c.pgMetadata.GetLastBatchID(ctx, jobName) +} + +func (c *KafkaConnector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { + return c.pgMetadata.FetchLastOffset(ctx, jobName) +} + +func (c *KafkaConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { + return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) +} + +func (c *KafkaConnector) NeedsSetupMetadataTables(_ context.Context) bool { + return false +} + +func (c *KafkaConnector) SetupMetadataTables(_ context.Context) error { + return nil +} + +func (c *KafkaConnector) ReplayTableSchemaDeltas(_ context.Context, flowJobName string, schemaDeltas []*protos.TableSchemaDelta) error { + return nil +} + +func (c *KafkaConnector) SyncFlowCleanup(ctx context.Context, jobName string) error { + return c.pgMetadata.DropMetadata(ctx, jobName) +} + +func loadScript(ctx context.Context, script string, printfn lua.LGFunction) (*lua.LState, error) { + if script == "" { + return nil, errors.New("kafka mirror must have script") + } + + ls := lua.NewState(lua.Options{SkipOpenLibs: true}) + ls.SetContext(ctx) + for _, pair := range []struct { + n string + f lua.LGFunction + }{ + {lua.LoadLibName, lua.OpenPackage}, // Must be first + {lua.BaseLibName, lua.OpenBase}, + {lua.TabLibName, lua.OpenTable}, + {lua.StringLibName, lua.OpenString}, + {lua.MathLibName, lua.OpenMath}, + } { + ls.Push(ls.NewFunction(pair.f)) + ls.Push(lua.LString(pair.n)) + err := ls.PCall(1, 0, nil) + if err != nil { + return nil, fmt.Errorf("failed to initialize Lua runtime: %w", err) + } + } + ls.PreloadModule("flatbuffers", gluaflatbuffers.Loader) + pua.RegisterTypes(ls) + ls.Env.RawSetString("print", ls.NewFunction(printfn)) + err := ls.GPCall(pua.LoadPeerdbScript, lua.LString(script)) + if err != nil { + return nil, fmt.Errorf("error loading script %s: %w", script, err) + } + err = ls.PCall(0, 0, nil) + if err != nil { + return nil, fmt.Errorf("error executing script %s: %w", script, err) + } + return ls, nil +} + +func lvalueToKafkaRecord(ls *lua.LState, value lua.LValue) (*kgo.Record, error) { + var kr *kgo.Record + switch v := value.(type) { + case lua.LString: + kr = kgo.StringRecord(string(v)) + case *lua.LTable: + key, err := LVAsReadOnlyBytes(ls, ls.GetField(v, "key")) + if err != nil { + return nil, fmt.Errorf("invalid key, %w", err) + } + value, err := LVAsReadOnlyBytes(ls, ls.GetField(v, "value")) + if err != nil { + return nil, fmt.Errorf("invalid value, %w", err) + } + topic, err := LVAsStringOrNil(ls, ls.GetField(v, "topic")) + if err != nil { + return nil, fmt.Errorf("invalid topic, %w", err) + } + partition := int32(lua.LVAsNumber(ls.GetField(v, "partition"))) + kr = &kgo.Record{ + Key: key, + Value: value, + Topic: topic, + Partition: partition, + } + lheaders := ls.GetField(v, "headers") + if headers, ok := lheaders.(*lua.LTable); ok { + headers.ForEach(func(k, v lua.LValue) { + kstr := k.String() + vbytes, err := LVAsReadOnlyBytes(ls, v) + if err != nil { + vbytes = unsafeFastStringToReadOnlyBytes(err.Error()) + } + kr.Headers = append(kr.Headers, kgo.RecordHeader{ + Key: kstr, + Value: vbytes, + }) + }) + } else if lua.LVAsBool(lheaders) { + return nil, fmt.Errorf("invalid headers, must be nil or table: %s", lheaders) + } + case *lua.LNilType: + default: + return nil, fmt.Errorf("script returned invalid value: %s", value) + } + return kr, nil +} + +func (c *KafkaConnector) SyncRecords(ctx context.Context, req *model.SyncRecordsRequest) (*model.SyncResponse, error) { + var wg sync.WaitGroup + wgCtx, wgErr := context.WithCancelCause(ctx) + produceCb := func(r *kgo.Record, err error) { + if err != nil { + wgErr(err) + } + wg.Done() + } + + numRecords := int64(0) + tableNameRowsMapping := make(map[string]uint32) + + ls, err := loadScript(wgCtx, req.Script, func(ls *lua.LState) int { + top := ls.GetTop() + ss := make([]string, top) + for i := range top { + ss[i] = ls.ToStringMeta(ls.Get(i + 1)).String() + } + _ = c.pgMetadata.LogFlowInfo(ctx, req.FlowJobName, strings.Join(ss, "\t")) + return 0 + }) + if err != nil { + return nil, err + } + defer ls.Close() + + lfn := ls.Env.RawGetString("onRecord") + fn, ok := lfn.(*lua.LFunction) + if !ok { + return nil, fmt.Errorf("script should define `onRecord` as function, not %s", lfn) + } + + for record := range req.Records.GetRecords() { + if err := wgCtx.Err(); err != nil { + return nil, err + } + ls.Push(fn) + ls.Push(pua.LuaRecord.New(ls, record)) + err := ls.PCall(1, -1, nil) + if err != nil { + return nil, fmt.Errorf("script failed: %w", err) + } + args := ls.GetTop() + for i := range args { + kr, err := lvalueToKafkaRecord(ls, ls.Get(i-args)) + if err != nil { + return nil, err + } + if kr != nil { + if kr.Topic == "" { + kr.Topic = record.GetDestinationTableName() + } + + wg.Add(1) + c.client.Produce(wgCtx, kr, produceCb) + tableNameRowsMapping[kr.Topic] += 1 + } + } + numRecords += 1 + ls.SetTop(0) + } + + waitChan := make(chan struct{}) + go func() { + wg.Wait() + close(waitChan) + }() + select { + case <-wgCtx.Done(): + return nil, wgCtx.Err() + case <-waitChan: + } + + if err := c.client.Flush(ctx); err != nil { + return nil, fmt.Errorf("could not flush transaction: %w", err) + } + + lastCheckpoint := req.Records.GetLastCheckpoint() + err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) + if err != nil { + return nil, err + } + + return &model.SyncResponse{ + CurrentSyncBatchID: req.SyncBatchID, + LastSyncedCheckpointID: lastCheckpoint, + NumRecordsSynced: numRecords, + TableNameRowsMapping: tableNameRowsMapping, + TableSchemaDeltas: req.Records.SchemaDeltas, + }, nil +} diff --git a/flow/connectors/postgres/cdc.go b/flow/connectors/postgres/cdc.go index acf3ba7a40..e5bad73d62 100644 --- a/flow/connectors/postgres/cdc.go +++ b/flow/connectors/postgres/cdc.go @@ -35,7 +35,7 @@ type PostgresCDCSource struct { slot string publication string typeMap *pgtype.Map - commitLock bool + commitLock *pglogrepl.BeginMessage // for partitioned tables, maps child relid to parent relid childToParentRelIDMapping map[uint32]uint32 @@ -75,7 +75,7 @@ func (c *PostgresConnector) NewPostgresCDCSource(cdcConfig *PostgresCDCConfig) * publication: cdcConfig.Publication, childToParentRelIDMapping: cdcConfig.ChildToParentRelIDMap, typeMap: pgtype.NewMap(), - commitLock: false, + commitLock: nil, catalogPool: cdcConfig.CatalogPool, flowJobName: cdcConfig.FlowJobName, } @@ -188,7 +188,7 @@ func (p *PostgresCDCSource) PullRecords(ctx context.Context, req *model.PullReco } } - if !p.commitLock { + if p.commitLock == nil { if cdcRecordsStorage.Len() >= int(req.MaxBatchSize) { return nil } @@ -208,7 +208,7 @@ func (p *PostgresCDCSource) PullRecords(ctx context.Context, req *model.PullReco if !cdcRecordsStorage.IsEmpty() { p.logger.Info(fmt.Sprintf("standby deadline reached, have %d records", cdcRecordsStorage.Len())) - if !p.commitLock { + if p.commitLock == nil { p.logger.Info( fmt.Sprintf("no commit lock, returning currently accumulated records - %d", cdcRecordsStorage.Len())) @@ -241,7 +241,7 @@ func (p *PostgresCDCSource) PullRecords(ctx context.Context, req *model.PullReco return fmt.Errorf("consumeStream preempted: %w", ctxErr) } - if err != nil && !p.commitLock { + if err != nil && p.commitLock == nil { if pgconn.Timeout(err) { p.logger.Info(fmt.Sprintf("Stand-by deadline reached, returning currently accumulated records - %d", cdcRecordsStorage.Len())) @@ -408,6 +408,17 @@ func (p *PostgresCDCSource) PullRecords(ctx context.Context, req *model.PullReco } } +func (p *PostgresCDCSource) baseRecord(lsn pglogrepl.LSN) model.BaseRecord { + var nano int64 + if p.commitLock != nil { + nano = p.commitLock.CommitTime.UnixNano() + } + return model.BaseRecord{ + CheckpointID: int64(lsn), + CommitTimeNano: nano, + } +} + func (p *PostgresCDCSource) processMessage( ctx context.Context, batch *model.CDCRecordStream, @@ -423,7 +434,7 @@ func (p *PostgresCDCSource) processMessage( case *pglogrepl.BeginMessage: p.logger.Debug(fmt.Sprintf("BeginMessage => FinalLSN: %v, XID: %v", msg.FinalLSN, msg.Xid)) p.logger.Debug("Locking PullRecords at BeginMessage, awaiting CommitMessage") - p.commitLock = true + p.commitLock = msg case *pglogrepl.InsertMessage: return p.processInsertMessage(xld.WALStart, msg) case *pglogrepl.UpdateMessage: @@ -435,7 +446,7 @@ func (p *PostgresCDCSource) processMessage( p.logger.Debug(fmt.Sprintf("CommitMessage => CommitLSN: %v, TransactionEndLSN: %v", msg.CommitLSN, msg.TransactionEndLSN)) batch.UpdateLatestCheckpoint(int64(msg.CommitLSN)) - p.commitLock = false + p.commitLock = nil case *pglogrepl.RelationMessage: // treat all relation messages as corresponding to parent if partitioned. msg.RelationID = p.getParentRelIDIfPartitioned(msg.RelationID) @@ -483,7 +494,7 @@ func (p *PostgresCDCSource) processInsertMessage( } return &model.InsertRecord{ - CheckpointID: int64(lsn), + BaseRecord: p.baseRecord(lsn), Items: items, DestinationTableName: p.tableNameMapping[tableName].Name, SourceTableName: tableName, @@ -524,7 +535,7 @@ func (p *PostgresCDCSource) processUpdateMessage( } return &model.UpdateRecord{ - CheckpointID: int64(lsn), + BaseRecord: p.baseRecord(lsn), OldItems: oldItems, NewItems: newItems, DestinationTableName: p.tableNameMapping[tableName].Name, @@ -561,7 +572,7 @@ func (p *PostgresCDCSource) processDeleteMessage( } return &model.DeleteRecord{ - CheckpointID: int64(lsn), + BaseRecord: p.baseRecord(lsn), Items: items, DestinationTableName: p.tableNameMapping[tableName].Name, SourceTableName: tableName, @@ -765,8 +776,8 @@ func (p *PostgresCDCSource) processRelationMessage( // only log audit if there is actionable delta if len(schemaDelta.AddedColumns) > 0 { rec := &model.RelationRecord{ + BaseRecord: p.baseRecord(lsn), TableSchemaDelta: schemaDelta, - CheckpointID: int64(lsn), } return rec, p.auditSchemaDelta(ctx, p.flowJobName, rec) } diff --git a/flow/connectors/postgres/postgres.go b/flow/connectors/postgres/postgres.go index bd6721c076..c57154bd7c 100644 --- a/flow/connectors/postgres/postgres.go +++ b/flow/connectors/postgres/postgres.go @@ -404,7 +404,7 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco rawTableIdentifier := getRawTableIdentifier(req.FlowJobName) c.logger.Info(fmt.Sprintf("pushing records to Postgres table %s via COPY", rawTableIdentifier)) - numRecords := 0 + numRecords := int64(0) tableNameRowsMapping := make(map[string]uint32) streamReadFunc := func() ([]any, error) { @@ -509,7 +509,7 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco if err != nil { return nil, fmt.Errorf("error syncing records: %w", err) } - if syncedRecordsCount != int64(numRecords) { + if syncedRecordsCount != numRecords { return nil, fmt.Errorf("error syncing records: expected %d records to be synced, but %d were synced", numRecords, syncedRecordsCount) } @@ -536,7 +536,7 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco return &model.SyncResponse{ LastSyncedCheckpointID: lastCP, - NumRecordsSynced: int64(numRecords), + NumRecordsSynced: numRecords, CurrentSyncBatchID: req.SyncBatchID, TableNameRowsMapping: tableNameRowsMapping, TableSchemaDeltas: req.Records.SchemaDeltas, diff --git a/flow/connectors/utils/cdc_records/cdc_records_storage_test.go b/flow/connectors/utils/cdc_records/cdc_records_storage_test.go index 50796109f3..5acbc5962a 100644 --- a/flow/connectors/utils/cdc_records/cdc_records_storage_test.go +++ b/flow/connectors/utils/cdc_records/cdc_records_storage_test.go @@ -47,9 +47,12 @@ func genKeyAndRec(t *testing.T) (model.TableWithPkey, model.Record) { PkeyColVal: [32]byte(pkeyColVal), } rec := &model.InsertRecord{ + BaseRecord: model.BaseRecord{ + CheckpointID: 1, + CommitTimeNano: time.Now().UnixNano(), + }, SourceTableName: "test_src_tbl", DestinationTableName: "test_dst_tbl", - CheckpointID: 1, CommitID: 2, Items: &model.RecordItems{ ColToValIdx: map[string]int{ diff --git a/flow/e2e/kafka/kafka_test.go b/flow/e2e/kafka/kafka_test.go new file mode 100644 index 0000000000..f35e0f568a --- /dev/null +++ b/flow/e2e/kafka/kafka_test.go @@ -0,0 +1,137 @@ +package e2e_kafka + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + "github.com/jackc/pgx/v5" + "github.com/stretchr/testify/require" + "github.com/twmb/franz-go/pkg/kgo" + + connpostgres "github.com/PeerDB-io/peer-flow/connectors/postgres" + "github.com/PeerDB-io/peer-flow/e2e" + "github.com/PeerDB-io/peer-flow/e2eshared" + "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/shared" + peerflow "github.com/PeerDB-io/peer-flow/workflows" +) + +type KafkaSuite struct { + t *testing.T + conn *connpostgres.PostgresConnector + suffix string +} + +func (s KafkaSuite) T() *testing.T { + return s.t +} + +func (s KafkaSuite) Connector() *connpostgres.PostgresConnector { + return s.conn +} + +func (s KafkaSuite) Conn() *pgx.Conn { + return s.Connector().Conn() +} + +func (s KafkaSuite) Suffix() string { + return s.suffix +} + +func (s KafkaSuite) Peer() *protos.Peer { + return &protos.Peer{ + Name: e2e.AddSuffix(s, "kasimple"), + Type: protos.DBType_KAFKA, + Config: &protos.Peer_KafkaConfig{ + KafkaConfig: &protos.KafkaConfig{ + Servers: []string{"localhost:9092"}, + DisableTls: true, + }, + }, + } +} + +func (s KafkaSuite) DestinationTable(table string) string { + return table +} + +func (s KafkaSuite) Teardown() { + e2e.TearDownPostgres(s) +} + +func SetupSuite(t *testing.T) KafkaSuite { + t.Helper() + + suffix := "ka_" + strings.ToLower(shared.RandomString(8)) + conn, err := e2e.SetupPostgres(t, suffix) + require.NoError(t, err, "failed to setup postgres") + + return KafkaSuite{ + t: t, + conn: conn, + suffix: suffix, + } +} + +func Test_Kafka(t *testing.T) { + e2eshared.RunSuite(t, SetupSuite) +} + +func (s KafkaSuite) TestSimple() { + srcTableName := e2e.AttachSchema(s, "kasimple") + + _, err := s.Conn().Exec(context.Background(), fmt.Sprintf(` + CREATE TABLE IF NOT EXISTS %s ( + id SERIAL PRIMARY KEY, + val text + ); + `, srcTableName)) + require.NoError(s.t, err) + + _, err = s.Conn().Exec(context.Background(), `insert into public.scripts (name, lang, source) values + ('e2e_kasimple', 'lua', 'function onRecord(r) return r.row and r.row.val end') on conflict do nothing`) + require.NoError(s.t, err) + + connectionGen := e2e.FlowConnectionGenerationConfig{ + FlowJobName: e2e.AddSuffix(s, "kasimple"), + TableNameMapping: map[string]string{srcTableName: "katest"}, + Destination: s.Peer(), + } + flowConnConfig := connectionGen.GenerateFlowConnectionConfigs() + flowConnConfig.Script = "e2e_kasimple" + + tc := e2e.NewTemporalClient(s.t) + env := e2e.ExecutePeerflow(tc, peerflow.CDCFlowWorkflow, flowConnConfig, nil) + e2e.SetupCDCFlowStatusQuery(s.t, env, connectionGen) + + _, err = s.Conn().Exec(context.Background(), fmt.Sprintf(` + INSERT INTO %s (id, val) VALUES (1, 'testval') + `, srcTableName)) + require.NoError(s.t, err) + + e2e.EnvWaitFor(s.t, env, 3*time.Minute, "normalize insert", func() bool { + kafka, err := kgo.NewClient( + kgo.SeedBrokers("localhost:9092"), + kgo.ConsumeTopics("katest"), + ) + if err != nil { + return false + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + fetches := kafka.PollFetches(ctx) + fetches.EachTopic(func(ft kgo.FetchTopic) { + require.Equal(s.t, "katest", ft.Topic) + ft.EachRecord(func(r *kgo.Record) { + require.Equal(s.t, "testval", string(r.Value)) + }) + }) + return true + }) + env.Cancel() + e2e.RequireEnvCanceled(s.t, env) +} diff --git a/flow/go.mod b/flow/go.mod index 154a068d20..5a5fb83094 100644 --- a/flow/go.mod +++ b/flow/go.mod @@ -10,6 +10,9 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs v1.0.4 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/eventhub/armeventhub v1.2.0 github.com/ClickHouse/clickhouse-go/v2 v2.21.1 + github.com/PeerDB-io/glua64 v1.0.1 + github.com/PeerDB-io/gluabit32 v1.0.0 + github.com/PeerDB-io/gluaflatbuffers v1.0.1 github.com/aws/aws-sdk-go-v2 v1.25.3 github.com/aws/aws-sdk-go-v2/config v1.27.7 github.com/aws/aws-sdk-go-v2/credentials v1.17.7 @@ -35,9 +38,12 @@ require ( github.com/slack-go/slack v0.12.5 github.com/snowflakedb/gosnowflake v1.8.0 github.com/stretchr/testify v1.9.0 + github.com/twmb/franz-go v1.16.1 + github.com/twmb/franz-go/plugin/kslog v1.0.0 github.com/twpayne/go-geos v0.17.0 github.com/urfave/cli/v3 v3.0.0-alpha9 github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a + github.com/yuin/gopher-lua v1.1.1 go.temporal.io/api v1.29.1 go.temporal.io/sdk v1.26.0 go.uber.org/automaxprocs v1.5.3 @@ -91,6 +97,7 @@ require ( github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/twmb/franz-go/pkg/kmsg v1.7.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect diff --git a/flow/go.sum b/flow/go.sum index 377b2c2a16..aacfa2da10 100644 --- a/flow/go.sum +++ b/flow/go.sum @@ -54,6 +54,12 @@ github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= +github.com/PeerDB-io/glua64 v1.0.1 h1:biXLlFF/L5pnJCwDon7hkWkuQPozC8NjKS3J7Wzi69I= +github.com/PeerDB-io/glua64 v1.0.1/go.mod h1:UHmAhniv61bJPMhQvxkpC7jXbn353dSbQviu83bgQVg= +github.com/PeerDB-io/gluabit32 v1.0.0 h1:jn88j22LqiqDoS47LUnvk29hsFQE6yW0imSsHHiYsV8= +github.com/PeerDB-io/gluabit32 v1.0.0/go.mod h1:tsHStN1XG5uGVWEA8d/RameB7el3PE3sVkvk8e3+FJg= +github.com/PeerDB-io/gluaflatbuffers v1.0.1 h1:Oxlv0VlMYoQ05Q5n/k4hXAsvtDnuVNC99JBUf927br0= +github.com/PeerDB-io/gluaflatbuffers v1.0.1/go.mod h1:unZOM4Mm2Sn+aAFuVjoJDZ2Dji7jlDWrt4Hvq79as2g= github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= @@ -367,6 +373,12 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/twmb/franz-go v1.16.1 h1:rpWc7fB9jd7TgmCyfxzenBI+QbgS8ZfJOUQE+tzPtbE= +github.com/twmb/franz-go v1.16.1/go.mod h1:/pER254UPPGp/4WfGqRi+SIRGE50RSQzVubQp6+N4FA= +github.com/twmb/franz-go/pkg/kmsg v1.7.0 h1:a457IbvezYfA5UkiBvyV3zj0Is3y1i8EJgqjJYoij2E= +github.com/twmb/franz-go/pkg/kmsg v1.7.0/go.mod h1:se9Mjdt0Nwzc9lnjJ0HyDtLyBnaBDAd7pCje47OhSyw= +github.com/twmb/franz-go/plugin/kslog v1.0.0 h1:I64oEmF+0PDvmyLgwrlOtg4mfpSE9GwlcLxM4af2t60= +github.com/twmb/franz-go/plugin/kslog v1.0.0/go.mod h1:8pMjK3OJJJNNYddBSbnXZkIK5dCKFIk9GcVVCDgvnQc= github.com/twpayne/go-geos v0.17.0 h1:158IwlZxA5Q1qWpBrP90dG3B8mQ5yb5RA4SPhR2CJ2E= github.com/twpayne/go-geos v0.17.0/go.mod h1:OgP9eXBQBbU1Qi2IR3kF608WTd9YtRXZP0FugQ0POi0= github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo= @@ -383,6 +395,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= diff --git a/flow/model/model.go b/flow/model/model.go index 9e38e237de..1561e66544 100644 --- a/flow/model/model.go +++ b/flow/model/model.go @@ -14,9 +14,12 @@ type NameAndExclude struct { } func NewNameAndExclude(name string, exclude []string) NameAndExclude { - exset := make(map[string]struct{}, len(exclude)) - for _, col := range exclude { - exset[col] = struct{}{} + var exset map[string]struct{} + if len(exclude) != 0 { + exset = make(map[string]struct{}, len(exclude)) + for _, col := range exclude { + exset[col] = struct{}{} + } } return NameAndExclude{Name: name, Exclude: exset} } @@ -45,10 +48,10 @@ type PullRecordsRequest struct { } type Record interface { - // GetCheckpointID returns the ID of the record. GetCheckpointID() int64 - // get table name + GetCommitTime() time.Time GetDestinationTableName() string + GetSourceTableName() string // get columns and values for the record GetItems() *RecordItems } @@ -59,9 +62,12 @@ type ToJSONOptions struct { } func NewToJSONOptions(unnestCols []string, hstoreAsJSON bool) *ToJSONOptions { - unnestColumns := make(map[string]struct{}, len(unnestCols)) - for _, col := range unnestCols { - unnestColumns[col] = struct{}{} + var unnestColumns map[string]struct{} + if len(unnestCols) != 0 { + unnestColumns = make(map[string]struct{}, len(unnestCols)) + for _, col := range unnestCols { + unnestColumns[col] = struct{}{} + } } return &ToJSONOptions{ UnnestColumns: unnestColumns, @@ -69,37 +75,49 @@ func NewToJSONOptions(unnestCols []string, hstoreAsJSON bool) *ToJSONOptions { } } +type BaseRecord struct { + // CheckpointID is the ID of the record. + CheckpointID int64 `json:"checkpointId"` + // BeginMessage.CommitTime.UnixNano(), 16 bytes smaller than time.Time + CommitTimeNano int64 `json:"commitTimeNano"` +} + +func (r *BaseRecord) GetCheckpointID() int64 { + return r.CheckpointID +} + +func (r *BaseRecord) GetCommitTime() time.Time { + return time.Unix(0, r.CommitTimeNano) +} + type InsertRecord struct { + BaseRecord // Name of the source table SourceTableName string // Name of the destination table DestinationTableName string - // CheckpointID is the ID of the record. - CheckpointID int64 // CommitID is the ID of the commit corresponding to this record. CommitID int64 // Items is a map of column name to value. Items *RecordItems } -// Implement Record interface for InsertRecord. -func (r *InsertRecord) GetCheckpointID() int64 { - return r.CheckpointID -} - func (r *InsertRecord) GetDestinationTableName() string { return r.DestinationTableName } +func (r *InsertRecord) GetSourceTableName() string { + return r.SourceTableName +} + func (r *InsertRecord) GetItems() *RecordItems { return r.Items } type UpdateRecord struct { + BaseRecord // Name of the source table SourceTableName string - // CheckpointID is the ID of the record. - CheckpointID int64 // Name of the destination table DestinationTableName string // OldItems is a map of column name to value. @@ -110,42 +128,38 @@ type UpdateRecord struct { UnchangedToastColumns map[string]struct{} } -// Implement Record interface for UpdateRecord. -func (r *UpdateRecord) GetCheckpointID() int64 { - return r.CheckpointID -} - -// Implement Record interface for UpdateRecord. func (r *UpdateRecord) GetDestinationTableName() string { return r.DestinationTableName } +func (r *UpdateRecord) GetSourceTableName() string { + return r.SourceTableName +} + func (r *UpdateRecord) GetItems() *RecordItems { return r.NewItems } type DeleteRecord struct { + BaseRecord // Name of the source table SourceTableName string // Name of the destination table DestinationTableName string - // CheckpointID is the ID of the record. - CheckpointID int64 // Items is a map of column name to value. Items *RecordItems // unchanged toast columns, filled from latest UpdateRecord UnchangedToastColumns map[string]struct{} } -// Implement Record interface for DeleteRecord. -func (r *DeleteRecord) GetCheckpointID() int64 { - return r.CheckpointID -} - func (r *DeleteRecord) GetDestinationTableName() string { return r.DestinationTableName } +func (r *DeleteRecord) GetSourceTableName() string { + return r.SourceTableName +} + func (r *DeleteRecord) GetItems() *RecordItems { return r.Items } @@ -165,6 +179,8 @@ type SyncRecordsRequest struct { TableMappings []*protos.TableMapping // Staging path for AVRO files in CDC StagingPath string + // Lua script + Script string } type NormalizeRecordsRequest struct { @@ -204,19 +220,18 @@ type NormalizeResponse struct { // being clever and passing the delta back as a regular record instead of heavy CDC refactoring. type RelationRecord struct { - CheckpointID int64 `json:"checkpointId"` + BaseRecord TableSchemaDelta *protos.TableSchemaDelta `json:"tableSchemaDelta"` } -// Implement Record interface for RelationRecord. -func (r *RelationRecord) GetCheckpointID() int64 { - return r.CheckpointID -} - func (r *RelationRecord) GetDestinationTableName() string { return r.TableSchemaDelta.DstTableName } +func (r *RelationRecord) GetSourceTableName() string { + return r.TableSchemaDelta.SrcTableName +} + func (r *RelationRecord) GetItems() *RecordItems { return nil } diff --git a/flow/model/qrecord_test.go b/flow/model/qrecord_test.go index 12b59c67bb..e6c769fd69 100644 --- a/flow/model/qrecord_test.go +++ b/flow/model/qrecord_test.go @@ -12,8 +12,8 @@ import ( ) func TestEquals(t *testing.T) { - uuidVal1, _ := uuid.NewRandom() - uuidVal2, _ := uuid.NewRandom() + uuidVal1 := uuid.New() + uuidVal2 := uuid.New() tests := []struct { name string diff --git a/flow/model/qvalue/qvalue.go b/flow/model/qvalue/qvalue.go index 4a495a31cc..bedc3decec 100644 --- a/flow/model/qvalue/qvalue.go +++ b/flow/model/qvalue/qvalue.go @@ -606,10 +606,7 @@ func getUUID(v interface{}) (uuid.UUID, bool) { return parsed, true } case [16]byte: - parsed, err := uuid.FromBytes(value[:]) - if err == nil { - return parsed, true - } + return uuid.UUID(value), true } return uuid.UUID{}, false diff --git a/flow/model/record_items.go b/flow/model/record_items.go index fe9da58af9..a258f78be5 100644 --- a/flow/model/record_items.go +++ b/flow/model/record_items.go @@ -236,8 +236,7 @@ func (r *RecordItems) ToJSONWithOptions(options *ToJSONOptions) (string, error) } func (r *RecordItems) ToJSON() (string, error) { - unnestCols := make([]string, 0) - return r.ToJSONWithOpts(NewToJSONOptions(unnestCols, true)) + return r.ToJSONWithOpts(NewToJSONOptions(nil, true)) } func (r *RecordItems) ToJSONWithOpts(opts *ToJSONOptions) (string, error) { diff --git a/flow/pua/peerdb.go b/flow/pua/peerdb.go new file mode 100644 index 0000000000..c8f9f8884c --- /dev/null +++ b/flow/pua/peerdb.go @@ -0,0 +1,442 @@ +package pua + +import ( + "bytes" + "fmt" + "math/big" + "time" + + "github.com/google/uuid" + "github.com/jackc/pgx/v5" + "github.com/shopspring/decimal" + "github.com/yuin/gopher-lua" + + "github.com/PeerDB-io/glua64" + "github.com/PeerDB-io/gluabit32" + "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" + "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/model/qvalue" +) + +var ( + LuaRecord = glua64.UserDataType[model.Record]{Name: "peerdb_record"} + LuaRow = glua64.UserDataType[*model.RecordItems]{Name: "peerdb_row"} + LuaTime = glua64.UserDataType[time.Time]{Name: "peerdb_time"} + LuaUuid = glua64.UserDataType[uuid.UUID]{Name: "peerdb_uuid"} + LuaBigInt = glua64.UserDataType[*big.Int]{Name: "peerdb_bigint"} + LuaDecimal = glua64.UserDataType[decimal.Decimal]{Name: "peerdb_bigrat"} +) + +func RegisterTypes(ls *lua.LState) { + glua64.Loader(ls) + ls.Env.RawSetString("loadfile", lua.LNil) + ls.Env.RawSetString("dofile", lua.LNil) + + // gopher-lua provides 2 loaders {preload, file} + // overwrite file loader with one retrieving scripts from database + loaders := ls.G.Registry.RawGetString("_LOADERS").(*lua.LTable) + loaders.RawSetInt(2, ls.NewFunction(LoadPeerdbScript)) + + ls.PreloadModule("bit32", bit32.Loader) + + mt := LuaRecord.NewMetatable(ls) + mt.RawSetString("__index", ls.NewFunction(LuaRecordIndex)) + + mt = LuaRow.NewMetatable(ls) + mt.RawSetString("__index", ls.NewFunction(LuaRowIndex)) + mt.RawSetString("__len", ls.NewFunction(LuaRowLen)) + + mt = LuaUuid.NewMetatable(ls) + mt.RawSetString("__index", ls.NewFunction(LuaUuidIndex)) + mt.RawSetString("__tostring", ls.NewFunction(LuaUuidString)) + + mt = LuaTime.NewMetatable(ls) + mt.RawSetString("__index", ls.NewFunction(LuaTimeIndex)) + mt.RawSetString("__tostring", ls.NewFunction(LuaTimeString)) + + mt = LuaBigInt.NewMetatable(ls) + mt.RawSetString("__index", ls.NewFunction(LuaBigIntIndex)) + mt.RawSetString("__tostring", ls.NewFunction(LuaBigIntString)) + mt.RawSetString("__len", ls.NewFunction(LuaBigIntLen)) + + mt = LuaDecimal.NewMetatable(ls) + mt.RawSetString("__index", ls.NewFunction(LuaDecimalIndex)) + mt.RawSetString("__tostring", ls.NewFunction(LuaDecimalString)) + + peerdb := ls.NewTable() + peerdb.RawSetString("RowToJSON", ls.NewFunction(LuaRowToJSON)) + peerdb.RawSetString("RowColumns", ls.NewFunction(LuaRowColumns)) + peerdb.RawSetString("RowColumnKind", ls.NewFunction(LuaRowColumnKind)) + peerdb.RawSetString("Now", ls.NewFunction(LuaNow)) + peerdb.RawSetString("UUID", ls.NewFunction(LuaUUID)) + peerdb.RawSetString("type", ls.NewFunction(LuaType)) + peerdb.RawSetString("tostring", ls.NewFunction(LuaToString)) + ls.Env.RawSetString("peerdb", peerdb) +} + +func LoadPeerdbScript(ls *lua.LState) int { + ctx := ls.Context() + name := ls.CheckString(1) + pool, err := utils.GetCatalogConnectionPoolFromEnv(ctx) + if err != nil { + ls.RaiseError("Connection failed loading %s: %s", name, err.Error()) + return 0 + } + + var source []byte + err = pool.QueryRow(ctx, "select source from scripts where lang = 'lua' and name = $1", name).Scan(&source) + if err != nil { + if err == pgx.ErrNoRows { + ls.Push(lua.LString("Could not find script " + name)) + return 1 + } + ls.RaiseError("Failed to load script %s: %s", name, err.Error()) + return 0 + } + + fn, err := ls.Load(bytes.NewReader(source), name) + if err != nil { + ls.RaiseError(err.Error()) + } + ls.Push(fn) + return 1 +} + +func GetRowQ(ls *lua.LState, row *model.RecordItems, col string) qvalue.QValue { + qv, err := row.GetValueByColName(col) + if err != nil { + ls.RaiseError(err.Error()) + return qvalue.QValue{} + } + return qv +} + +func LuaRowIndex(ls *lua.LState) int { + row, key := LuaRow.StartIndex(ls) + ls.Push(LuaQValue(ls, GetRowQ(ls, row, key))) + return 1 +} + +func LuaRowLen(ls *lua.LState) int { + _, row := LuaRow.Check(ls, 1) + ls.Push(lua.LNumber(len(row.Values))) + return 1 +} + +func LuaRowToJSON(ls *lua.LState) int { + _, row := LuaRow.Check(ls, 1) + json, err := row.ToJSON() + if err != nil { + ls.RaiseError("failed to serialize json: %s", err.Error()) + return 0 + } + ls.Push(lua.LString(json)) + return 1 +} + +func LuaRowColumns(ls *lua.LState) int { + _, row := LuaRow.Check(ls, 1) + tbl := ls.CreateTable(len(row.ColToValIdx), 0) + for col, idx := range row.ColToValIdx { + tbl.RawSetInt(idx+1, lua.LString(col)) + } + ls.Push(tbl) + return 1 +} + +func LuaRowColumnKind(ls *lua.LState) int { + row, key := LuaRow.StartIndex(ls) + ls.Push(lua.LString(GetRowQ(ls, row, key).Kind)) + return 1 +} + +func LuaRecordIndex(ls *lua.LState) int { + record, key := LuaRecord.StartIndex(ls) + switch key { + case "kind": + switch record.(type) { + case *model.InsertRecord: + ls.Push(lua.LString("insert")) + case *model.UpdateRecord: + ls.Push(lua.LString("update")) + case *model.DeleteRecord: + ls.Push(lua.LString("delete")) + case *model.RelationRecord: + ls.Push(lua.LString("relation")) + } + case "row": + items := record.GetItems() + if items != nil { + ls.Push(LuaRow.New(ls, items)) + } else { + ls.Push(lua.LNil) + } + case "old": + var items *model.RecordItems + switch rec := record.(type) { + case *model.UpdateRecord: + items = rec.OldItems + case *model.DeleteRecord: + items = rec.Items + } + if items != nil { + ls.Push(LuaRow.New(ls, items)) + } else { + ls.Push(lua.LNil) + } + case "new": + var items *model.RecordItems + switch rec := record.(type) { + case *model.InsertRecord: + items = rec.Items + case *model.UpdateRecord: + items = rec.NewItems + } + if items != nil { + ls.Push(LuaRow.New(ls, items)) + } else { + ls.Push(lua.LNil) + } + case "checkpoint": + ls.Push(glua64.I64.New(ls, record.GetCheckpointID())) + case "commit_time": + ls.Push(LuaTime.New(ls, record.GetCommitTime())) + case "target": + ls.Push(lua.LString(record.GetDestinationTableName())) + case "source": + ls.Push(lua.LString(record.GetSourceTableName())) + default: + return 0 + } + return 1 +} + +func qvToLTable[T any](ls *lua.LState, s []T, f func(x T) lua.LValue) *lua.LTable { + tbl := ls.CreateTable(len(s), 0) + for idx, val := range s { + tbl.RawSetInt(idx+1, f(val)) + } + return tbl +} + +func LuaQValue(ls *lua.LState, qv qvalue.QValue) lua.LValue { + switch v := qv.Value.(type) { + case nil: + return lua.LNil + case bool: + return lua.LBool(v) + case uint8: + if qv.Kind == qvalue.QValueKindQChar { + return lua.LString(rune(v)) + } else { + return lua.LNumber(v) + } + case int16: + return lua.LNumber(v) + case int32: + return lua.LNumber(v) + case int64: + return glua64.I64.New(ls, v) + case float32: + return lua.LNumber(v) + case float64: + return lua.LNumber(v) + case string: + if qv.Kind == qvalue.QValueKindUUID { + u, err := uuid.Parse(v) + if err != nil { + return LuaUuid.New(ls, u) + } + } + return lua.LString(v) + case time.Time: + return LuaTime.New(ls, v) + case decimal.Decimal: + return LuaDecimal.New(ls, v) + case [16]byte: + return LuaUuid.New(ls, uuid.UUID(v)) + case []byte: + return lua.LString(v) + case []float32: + return qvToLTable(ls, v, func(f float32) lua.LValue { + return lua.LNumber(f) + }) + case []float64: + return qvToLTable(ls, v, func(f float64) lua.LValue { + return lua.LNumber(f) + }) + case []int16: + return qvToLTable(ls, v, func(x int16) lua.LValue { + return lua.LNumber(x) + }) + case []int32: + return qvToLTable(ls, v, func(x int32) lua.LValue { + return lua.LNumber(x) + }) + case []int64: + return qvToLTable(ls, v, func(x int64) lua.LValue { + return glua64.I64.New(ls, x) + }) + case []string: + return qvToLTable(ls, v, func(x string) lua.LValue { + return lua.LString(x) + }) + case []time.Time: + return qvToLTable(ls, v, func(x time.Time) lua.LValue { + return LuaTime.New(ls, x) + }) + case []bool: + return qvToLTable(ls, v, func(x bool) lua.LValue { + return lua.LBool(x) + }) + default: + return lua.LString(fmt.Sprint(qv.Value)) + } +} + +func LuaUuidIndex(ls *lua.LState) int { + _, val := LuaUuid.Check(ls, 1) + key := ls.CheckNumber(2) + ki := int(key) + if ki >= 0 && ki < 16 { + ls.Push(lua.LNumber(val[ki])) + return 1 + } + return 0 +} + +func LuaUuidString(ls *lua.LState) int { + val := LuaUuid.StartMethod(ls) + ls.Push(lua.LString(val.String())) + return 1 +} + +func LuaNow(ls *lua.LState) int { + ls.Push(LuaTime.New(ls, time.Now())) + return 1 +} + +func LuaUUID(ls *lua.LState) int { + ls.Push(LuaUuid.New(ls, uuid.New())) + return 1 +} + +func LuaType(ls *lua.LState) int { + val := ls.Get(1) + if ud, ok := val.(*lua.LUserData); ok { + ls.Push(lua.LString(fmt.Sprintf("%T", ud.Value))) + return 1 + } + return 0 +} + +func LuaToString(ls *lua.LState) int { + val := ls.Get(1) + if ud, ok := val.(*lua.LUserData); ok { + ls.Push(lua.LString(fmt.Sprint(ud.Value))) + return 1 + } + return 0 +} + +func LuaTimeIndex(ls *lua.LState) int { + tm, key := LuaTime.StartIndex(ls) + switch key { + case "unix_nano": + ls.Push(glua64.I64.New(ls, tm.UnixNano())) + case "unix_micro": + ls.Push(glua64.I64.New(ls, tm.UnixMicro())) + case "unix_milli": + ls.Push(glua64.I64.New(ls, tm.UnixMilli())) + case "unix_second": + ls.Push(glua64.I64.New(ls, tm.Unix())) + case "unix": + ls.Push(lua.LNumber(float64(tm.Unix()) + float64(tm.Nanosecond())/1e9)) + case "year": + ls.Push(lua.LNumber(tm.Year())) + case "month": + ls.Push(lua.LNumber(tm.Month())) + case "day": + ls.Push(lua.LNumber(tm.Day())) + case "yearday": + ls.Push(lua.LNumber(tm.YearDay())) + case "hour": + ls.Push(lua.LNumber(tm.Hour())) + case "minute": + ls.Push(lua.LNumber(tm.Minute())) + case "second": + ls.Push(lua.LNumber(tm.Second())) + case "nanosecond": + ls.Push(lua.LNumber(tm.Nanosecond())) + default: + return 0 + } + return 1 +} + +func LuaTimeString(ls *lua.LState) int { + tm := LuaTime.StartMethod(ls) + ls.Push(lua.LString(tm.String())) + return 1 +} + +func LuaBigIntIndex(ls *lua.LState) int { + _, bi := LuaBigInt.Check(ls, 1) + switch key := ls.Get(2).(type) { + case lua.LNumber: + ls.Push(lua.LNumber(bi.Bytes()[int(key)])) + case lua.LString: + switch string(key) { + case "sign": + ls.Push(lua.LNumber(bi.Sign())) + case "bytes": + ls.Push(lua.LString(bi.Bytes())) + case "int64": + ls.Push(glua64.I64.New(ls, bi.Int64())) + case "is64": + ls.Push(lua.LBool(bi.IsInt64())) + } + default: + ls.RaiseError("BigInt accessed with non number/string") + } + return 1 +} + +func LuaBigIntString(ls *lua.LState) int { + bi := LuaBigInt.StartMethod(ls) + ls.Push(lua.LString(bi.String())) + return 1 +} + +func LuaBigIntLen(ls *lua.LState) int { + bi := LuaBigInt.StartMethod(ls) + ls.Push(lua.LNumber(len(bi.Bytes()))) + return 1 +} + +func LuaDecimalIndex(ls *lua.LState) int { + num, key := LuaDecimal.StartIndex(ls) + switch key { + case "coefficient": + ls.Push(LuaBigInt.New(ls, num.Coefficient())) + case "coefficient64": + ls.Push(glua64.I64.New(ls, num.CoefficientInt64())) + case "exponent": + ls.Push(lua.LNumber(num.Exponent())) + case "bigint": + ls.Push(LuaBigInt.New(ls, num.BigInt())) + case "int64": + ls.Push(glua64.I64.New(ls, num.IntPart())) + case "float64": + ls.Push(lua.LNumber(num.InexactFloat64())) + default: + return 0 + } + return 1 +} + +func LuaDecimalString(ls *lua.LState) int { + num := LuaDecimal.StartMethod(ls) + ls.Push(lua.LString(num.String())) + return 1 +} diff --git a/flow/pua/peerdb_test.go b/flow/pua/peerdb_test.go new file mode 100644 index 0000000000..b2a752a16b --- /dev/null +++ b/flow/pua/peerdb_test.go @@ -0,0 +1,50 @@ +package pua + +import ( + "testing" + + "github.com/google/uuid" + "github.com/yuin/gopher-lua" +) + +func assert(t *testing.T, ls *lua.LState, source string) { + t.Helper() + err := ls.DoString(source) + if err != nil { + t.Log(err) + t.FailNow() + } +} + +func Test_Lua(t *testing.T) { + t.Parallel() + + ls := lua.NewState(lua.Options{}) + RegisterTypes(ls) + + id := uuid.UUID([16]byte{2, 3, 5, 7, 11, 13, 17, 19, 127, 131, 137, 139, 149, 151, 241, 251}) + ls.Env.RawSetString("uuid", LuaUuid.New(ls, id)) + + assert(t, ls, ` +assert(require('bit32').band(173, 21) == 5) +assert(dofile == nil) +assert(loadfile == nil) + +assert(uuid[0] == 2) +assert(uuid[1] == 3) +assert(uuid[2] == 5) +assert(uuid[3] == 7) +assert(uuid[4] == 11) +assert(uuid[5] == 13) +assert(uuid[6] == 17) +assert(uuid[7] == 19) +assert(uuid[8] == 127) +assert(uuid[9] == 131) +assert(uuid[10] == 137) +assert(uuid[11] == 139) +assert(uuid[12] == 149) +assert(uuid[13] == 151) +assert(uuid[14] == 241) +assert(uuid[15] == 251) +`) +} diff --git a/nexus/analyzer/src/lib.rs b/nexus/analyzer/src/lib.rs index 81468018a8..da8cab94d4 100644 --- a/nexus/analyzer/src/lib.rs +++ b/nexus/analyzer/src/lib.rs @@ -10,8 +10,8 @@ use anyhow::Context; use pt::{ flow_model::{FlowJob, FlowJobTableMapping, QRepFlowJob}, peerdb_peers::{ - peer::Config, BigqueryConfig, ClickhouseConfig, DbType, EventHubConfig, MongoConfig, Peer, - PostgresConfig, S3Config, SnowflakeConfig, SqlServerConfig, + peer::Config, BigqueryConfig, ClickhouseConfig, DbType, EventHubConfig, KafkaConfig, + MongoConfig, Peer, PostgresConfig, S3Config, SnowflakeConfig, SqlServerConfig, }, }; use qrep::process_options; @@ -251,8 +251,8 @@ impl<'a> StatementAnalyzer for PeerDDLAnalyzer<'a> { let snapshot_staging_path = match raw_options .remove("snapshot_staging_path") { - Some(sqlparser::ast::Value::SingleQuotedString(s)) => Some(s.clone()), - _ => Some("".to_string()), + Some(sqlparser::ast::Value::SingleQuotedString(s)) => s.clone(), + _ => String::new(), }; let snapshot_max_parallel_workers: Option = match raw_options @@ -311,6 +311,11 @@ impl<'a> StatementAnalyzer for PeerDDLAnalyzer<'a> { _ => false, }; + let script = match raw_options.remove("script") { + Some(sqlparser::ast::Value::SingleQuotedString(s)) => s.clone(), + _ => String::new(), + }; + let flow_job = FlowJob { name: cdc.mirror_name.to_string().to_lowercase(), source_peer: cdc.source_peer.to_string().to_lowercase(), @@ -333,6 +338,7 @@ impl<'a> StatementAnalyzer for PeerDDLAnalyzer<'a> { soft_delete_col_name, synced_at_col_name, initial_snapshot_only: initial_copy_only, + script, }; if initial_copy_only && !do_initial_copy { @@ -813,5 +819,40 @@ fn parse_db_options( }; Config::ClickhouseConfig(clickhouse_config) } + DbType::Kafka => { + let kafka_config = KafkaConfig { + servers: opts + .get("servers") + .context("no servers specified")? + .split(',') + .map(String::from) + .collect::>(), + username: opts + .get("user") + .cloned() + .unwrap_or_default() + .to_string(), + password: opts + .get("password") + .cloned() + .unwrap_or_default() + .to_string(), + sasl: opts + .get("sasl_mechanism") + .cloned() + .unwrap_or_default() + .to_string(), + partitioner: opts + .get("sasl_mechanism") + .cloned() + .unwrap_or_default() + .to_string(), + disable_tls: opts + .get("disable_tls") + .and_then(|s| s.parse::().ok()) + .unwrap_or_default(), + }; + Config::KafkaConfig(kafka_config) + } })) } diff --git a/nexus/catalog/migrations/V23__scripts.sql b/nexus/catalog/migrations/V23__scripts.sql new file mode 100644 index 0000000000..d79c897510 --- /dev/null +++ b/nexus/catalog/migrations/V23__scripts.sql @@ -0,0 +1,8 @@ +CREATE TYPE script_lang AS ENUM ('lua'); + +CREATE TABLE scripts ( + id SERIAL PRIMARY KEY, + lang script_lang NOT NULL, + name TEXT NOT NULL UNIQUE, + source BYTEA NOT NULL +); diff --git a/nexus/catalog/src/lib.rs b/nexus/catalog/src/lib.rs index ce3eb7e778..0d8b7ed6a6 100644 --- a/nexus/catalog/src/lib.rs +++ b/nexus/catalog/src/lib.rs @@ -100,6 +100,7 @@ impl Catalog { eventhub_group_config.encode_to_vec() } Config::ClickhouseConfig(clickhouse_config) => clickhouse_config.encode_to_vec(), + Config::KafkaConfig(kafka_config) => kafka_config.encode_to_vec(), } }; @@ -306,6 +307,11 @@ impl Catalog { pt::peerdb_peers::ClickhouseConfig::decode(options).with_context(err)?; Config::ClickhouseConfig(clickhouse_config) } + DbType::Kafka => { + let kafka_config = + pt::peerdb_peers::KafkaConfig::decode(options).with_context(err)?; + Config::KafkaConfig(kafka_config) + } }) } else { None @@ -319,12 +325,11 @@ impl Catalog { ) -> anyhow::Result { let peer_dbtype = self.get_peer_type_for_id(peer_id).await?; - let mut table_identifier_parts = table_identifier.split('.').collect::>(); - if table_identifier_parts.len() == 1 && (peer_dbtype != DbType::Bigquery) { - table_identifier_parts.insert(0, "public"); + if !table_identifier.contains('.') && peer_dbtype != DbType::Bigquery { + Ok(format!("public.{}", table_identifier)) + } else { + Ok(String::from(table_identifier)) } - - Ok(table_identifier_parts.join(".")) } pub async fn create_cdc_flow_job_entry(&self, job: &FlowJob) -> anyhow::Result<()> { diff --git a/nexus/flow-rs/src/grpc.rs b/nexus/flow-rs/src/grpc.rs index a962c4ec4f..b7569dbe45 100644 --- a/nexus/flow-rs/src/grpc.rs +++ b/nexus/flow-rs/src/grpc.rs @@ -161,7 +161,7 @@ impl FlowGrpcClient { snapshot_num_rows_per_partition: snapshot_num_rows_per_partition.unwrap_or(0), snapshot_max_parallel_workers: snapshot_max_parallel_workers.unwrap_or(0), snapshot_num_tables_in_parallel: snapshot_num_tables_in_parallel.unwrap_or(0), - snapshot_staging_path: job.snapshot_staging_path.clone().unwrap_or_default(), + snapshot_staging_path: job.snapshot_staging_path.clone(), cdc_staging_path: job.cdc_staging_path.clone().unwrap_or_default(), soft_delete: job.soft_delete, replication_slot_name: replication_slot_name.unwrap_or_default(), @@ -170,6 +170,7 @@ impl FlowGrpcClient { soft_delete_col_name: job.soft_delete_col_name.clone().unwrap_or_default(), synced_at_col_name: job.synced_at_col_name.clone().unwrap_or_default(), initial_snapshot_only: job.initial_snapshot_only, + script: job.script.clone(), ..Default::default() }; diff --git a/nexus/pt/src/flow_model.rs b/nexus/pt/src/flow_model.rs index 021af81bbf..2946dd1d30 100644 --- a/nexus/pt/src/flow_model.rs +++ b/nexus/pt/src/flow_model.rs @@ -23,7 +23,7 @@ pub struct FlowJob { pub snapshot_num_rows_per_partition: Option, pub snapshot_max_parallel_workers: Option, pub snapshot_num_tables_in_parallel: Option, - pub snapshot_staging_path: Option, + pub snapshot_staging_path: String, pub cdc_staging_path: Option, pub soft_delete: bool, pub replication_slot_name: Option, @@ -34,6 +34,7 @@ pub struct FlowJob { pub soft_delete_col_name: Option, pub synced_at_col_name: Option, pub initial_snapshot_only: bool, + pub script: String, } #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)] diff --git a/nexus/pt/src/lib.rs b/nexus/pt/src/lib.rs index 41b0566b2a..33da1e6382 100644 --- a/nexus/pt/src/lib.rs +++ b/nexus/pt/src/lib.rs @@ -25,7 +25,7 @@ impl From for DbType { PeerType::S3 => DbType::S3, PeerType::SQLServer => DbType::Sqlserver, PeerType::EventHubGroup => DbType::EventhubGroup, - PeerType::Kafka => todo!("Add Kafka support"), + PeerType::Kafka => DbType::Kafka, } } } diff --git a/protos/flow.proto b/protos/flow.proto index f33b0696db..502520e1ea 100644 --- a/protos/flow.proto +++ b/protos/flow.proto @@ -69,6 +69,8 @@ message FlowConnectionConfigs { bool soft_delete = 17; string soft_delete_col_name = 18; string synced_at_col_name = 19; + + string script = 20; } message RenameTableOption { diff --git a/protos/peers.proto b/protos/peers.proto index 063effc4da..12fc88bfb3 100644 --- a/protos/peers.proto +++ b/protos/peers.proto @@ -108,6 +108,15 @@ message SqlServerConfig { string database = 5; } +message KafkaConfig { + repeated string servers = 1; + string username = 2; + string password = 3; + string sasl = 4; + bool disable_tls = 5; + string partitioner = 6; +} + enum DBType { BIGQUERY = 0; SNOWFLAKE = 1; @@ -118,6 +127,7 @@ enum DBType { SQLSERVER = 6; EVENTHUB_GROUP = 7; CLICKHOUSE = 8; + KAFKA = 9; } message Peer { @@ -133,5 +143,6 @@ message Peer { SqlServerConfig sqlserver_config = 9; EventHubGroupConfig eventhub_group_config = 10; ClickhouseConfig clickhouse_config = 11; + KafkaConfig kafka_config = 12; } } diff --git a/ui/README.md b/ui/README.md index 1d3fd5e120..6947d3f03d 100644 --- a/ui/README.md +++ b/ui/README.md @@ -2,7 +2,7 @@ PeerDB Cloud Template ## Prerequisites -- [NodeJS](https://nodejs.org/en): `18.17.1` +- [NodeJS](https://nodejs.org/en): `LTS` ## Getting Started diff --git a/ui/app/api/peers/getTruePeer.ts b/ui/app/api/peers/getTruePeer.ts index 3cef249e48..93da206854 100644 --- a/ui/app/api/peers/getTruePeer.ts +++ b/ui/app/api/peers/getTruePeer.ts @@ -4,6 +4,7 @@ import { ClickhouseConfig, EventHubConfig, EventHubGroupConfig, + KafkaConfig, Peer, PostgresConfig, S3Config, @@ -19,13 +20,14 @@ export const getTruePeer = (peer: CatalogPeer) => { const options = peer.options; let config: | BigqueryConfig - | SnowflakeConfig - | PostgresConfig + | ClickhouseConfig | EventHubConfig - | S3Config - | SqlServerConfig | EventHubGroupConfig - | ClickhouseConfig; + | KafkaConfig + | PostgresConfig + | S3Config + | SnowflakeConfig + | SqlServerConfig; switch (peer.type) { case 0: config = BigqueryConfig.decode(options); @@ -59,6 +61,10 @@ export const getTruePeer = (peer: CatalogPeer) => { config = ClickhouseConfig.decode(options); newPeer.clickhouseConfig = config; break; + case 9: + config = KafkaConfig.decode(options); + newPeer.kafkaConfig = config; + break; default: return newPeer; } diff --git a/ui/app/api/peers/info/[peerName]/route.ts b/ui/app/api/peers/info/[peerName]/route.ts index 93b0c00647..61dc033efb 100644 --- a/ui/app/api/peers/info/[peerName]/route.ts +++ b/ui/app/api/peers/info/[peerName]/route.ts @@ -1,5 +1,6 @@ import prisma from '@/app/utils/prisma'; import { NextRequest, NextResponse } from 'next/server'; + import { getTruePeer } from '../../getTruePeer'; export async function GET( @@ -20,6 +21,7 @@ export async function GET( const sfConfig = peerConfig.snowflakeConfig; const ehConfig = peerConfig.eventhubConfig; const chConfig = peerConfig.clickhouseConfig; + const kaConfig = peerConfig.kafkaConfig; if (pgConfig) { pgConfig.password = '********'; pgConfig.transactionSnapshot = '********'; @@ -42,6 +44,9 @@ export async function GET( chConfig.password = '********'; chConfig.secretAccessKey = '********'; } + if (kaConfig) { + kaConfig.password = '********'; + } return NextResponse.json(peerConfig); } diff --git a/ui/app/api/peers/route.ts b/ui/app/api/peers/route.ts index 5d43442bd8..0691212af8 100644 --- a/ui/app/api/peers/route.ts +++ b/ui/app/api/peers/route.ts @@ -10,6 +10,7 @@ import { BigqueryConfig, ClickhouseConfig, DBType, + KafkaConfig, Peer, PostgresConfig, S3Config, @@ -63,6 +64,12 @@ const constructPeer = ( type: DBType.S3, s3Config: config as S3Config, }; + case 'KAFKA': + return { + name, + type: DBType.KAFKA, + kafkaConfig: config as KafkaConfig, + }; default: return; } diff --git a/ui/app/dto/PeersDTO.ts b/ui/app/dto/PeersDTO.ts index bbf5fbccde..3e7f5c0b41 100644 --- a/ui/app/dto/PeersDTO.ts +++ b/ui/app/dto/PeersDTO.ts @@ -1,6 +1,7 @@ import { BigqueryConfig, ClickhouseConfig, + KafkaConfig, PostgresConfig, S3Config, SnowflakeConfig, @@ -43,7 +44,8 @@ export type PeerConfig = | SnowflakeConfig | BigqueryConfig | ClickhouseConfig - | S3Config; + | S3Config + | KafkaConfig; export type CatalogPeer = { id: number; name: string; diff --git a/ui/app/mirrors/[mirrorId]/configValues.ts b/ui/app/mirrors/[mirrorId]/configValues.ts index 8d49f3090f..55b5a4c0b3 100644 --- a/ui/app/mirrors/[mirrorId]/configValues.ts +++ b/ui/app/mirrors/[mirrorId]/configValues.ts @@ -19,21 +19,21 @@ const MirrorValues = (mirrorConfig: FlowConnectionConfigs | undefined) => { label: 'Snapshot Parallel Tables', }, { - value: `${ - mirrorConfig?.cdcStagingPath?.length - ? mirrorConfig?.cdcStagingPath - : 'Local' - }`, + value: mirrorConfig?.cdcStagingPath || 'Local', label: 'CDC Staging Path', }, { - value: `${ - mirrorConfig?.snapshotStagingPath?.length - ? mirrorConfig?.snapshotStagingPath - : 'Local' - }`, + value: mirrorConfig?.snapshotStagingPath || 'Local', label: 'Snapshot Staging Path', }, + { + value: mirrorConfig?.snapshotStagingPath || 'Local', + label: 'Snapshot Staging Path', + }, + { + value: mirrorConfig?.script, + label: 'Script', + }, ]; }; export default MirrorValues; diff --git a/ui/app/mirrors/create/helpers/cdc.ts b/ui/app/mirrors/create/helpers/cdc.ts index 0d70e3fac1..5d63cdd69a 100644 --- a/ui/app/mirrors/create/helpers/cdc.ts +++ b/ui/app/mirrors/create/helpers/cdc.ts @@ -139,4 +139,14 @@ export const cdcSettings: MirrorSetting[] = [ type: 'switch', advanced: true, }, + { + label: 'Script', + stateHandler: (value, setter) => + setter((curr: CDCConfig) => ({ + ...curr, + script: (value as string) || '', + })), + tips: 'Associate PeerDB script with this mirror.', + advanced: true, + }, ]; diff --git a/ui/app/mirrors/create/helpers/common.ts b/ui/app/mirrors/create/helpers/common.ts index 34233f24fc..63dea81815 100644 --- a/ui/app/mirrors/create/helpers/common.ts +++ b/ui/app/mirrors/create/helpers/common.ts @@ -36,6 +36,7 @@ export const blankCDCSetting: FlowConnectionConfigs = { syncedAtColName: '', initialSnapshotOnly: false, idleTimeoutSeconds: 60, + script: '', }; export const blankQRepSetting = { diff --git a/ui/app/peers/create/[peerType]/handlers.ts b/ui/app/peers/create/[peerType]/handlers.ts index 423b996aec..42f84a492a 100644 --- a/ui/app/peers/create/[peerType]/handlers.ts +++ b/ui/app/peers/create/[peerType]/handlers.ts @@ -8,6 +8,7 @@ import { Dispatch, SetStateAction } from 'react'; import { bqSchema, chSchema, + kaSchema, peerNameSchema, pgSchema, s3Schema, @@ -57,6 +58,10 @@ const validateFields = ( const s3Config = s3Schema.safeParse(config); if (!s3Config.success) validationErr = s3Config.error.issues[0].message; break; + case 'KAFKA': + const kaConfig = kaSchema.safeParse(config); + if (!kaConfig.success) validationErr = kaConfig.error.issues[0].message; + break; default: validationErr = 'Unsupported peer type ' + type; } diff --git a/ui/app/peers/create/[peerType]/helpers/ch.ts b/ui/app/peers/create/[peerType]/helpers/ch.ts index bda5b8eb1e..29147e0620 100644 --- a/ui/app/peers/create/[peerType]/helpers/ch.ts +++ b/ui/app/peers/create/[peerType]/helpers/ch.ts @@ -45,6 +45,7 @@ export const clickhouseSetting: PeerSetting[] = [ setter((curr) => ({ ...curr, disableTls: value as boolean })), type: 'switch', tips: 'If you are using a non-TLS connection for Clickhouse server, check this box.', + optional: true, }, { label: 'S3 Path', diff --git a/ui/app/peers/create/[peerType]/helpers/common.ts b/ui/app/peers/create/[peerType]/helpers/common.ts index ba14dafb2f..e418fd9266 100644 --- a/ui/app/peers/create/[peerType]/helpers/common.ts +++ b/ui/app/peers/create/[peerType]/helpers/common.ts @@ -13,6 +13,8 @@ export interface PeerSetting { tips?: string; helpfulLink?: string; default?: string | number; + placeholder?: string; + options?: { value: string; label: string }[]; } export const getBlankSetting = (dbType: string): PeerConfig => { diff --git a/ui/app/peers/create/[peerType]/helpers/ka.ts b/ui/app/peers/create/[peerType]/helpers/ka.ts new file mode 100644 index 0000000000..5091d29e7e --- /dev/null +++ b/ui/app/peers/create/[peerType]/helpers/ka.ts @@ -0,0 +1,73 @@ +import { KafkaConfig } from '@/grpc_generated/peers'; +import { PeerSetting } from './common'; + +export const kaSetting: PeerSetting[] = [ + { + label: 'Servers', + stateHandler: (value, setter) => + setter((curr) => ({ ...curr, servers: (value as string).split(',') })), + tips: 'Brokers', + helpfulLink: + 'https://pkg.go.dev/github.com/twmb/franz-go/pkg/kgo#SeedBrokers', + }, + { + label: 'Username', + stateHandler: (value, setter) => + setter((curr) => ({ ...curr, username: value as string })), + optional: true, + }, + { + label: 'Password', + type: 'password', + stateHandler: (value, setter) => + setter((curr) => ({ ...curr, password: value as string })), + optional: true, + }, + { + label: 'SASL Mechanism', + stateHandler: (value, setter) => + setter((curr) => ({ ...curr, sasl: value as string })), + type: 'select', + placeholder: 'Select a mechanism', + helpfulLink: + 'https://docs.redpanda.com/current/manage/security/authentication/#scram', + options: [ + { value: 'PLAIN', label: 'PLAIN' }, + { value: 'SCRAM-SHA-256', label: 'SCRAM-SHA-256' }, + { value: 'SCRAM-SHA-512', label: 'SCRAM-SHA-512' }, + ], + }, + { + label: 'Partitioner', + stateHandler: (value, setter) => + setter((curr) => ({ ...curr, partitioner: value as string })), + type: 'select', + placeholder: 'Select a partitioner', + helpfulLink: + 'https://pkg.go.dev/github.com/twmb/franz-go/pkg/kgo#Partitioner', + options: [ + { value: 'LeastBackup', label: 'Least Backup' }, + { value: 'Manual', label: 'Manual' }, + { value: 'RoundRobin', label: 'Round Robin' }, + { value: 'StickyKey', label: 'Sticky Key' }, + { value: 'Sticky', label: 'Sticky' }, + ], + }, + { + label: 'Disable TLS?', + stateHandler: (value, setter) => + setter((curr) => ({ ...curr, disableTls: value as boolean })), + type: 'switch', + tips: 'If you are using a non-TLS connection for Kafka server, check this box.', + optional: true, + }, +]; + +export const blankKaSetting: KafkaConfig = { + servers: [], + username: '', + password: '', + sasl: 'PLAIN', + partitioner: '', + disableTls: false, +}; diff --git a/ui/app/peers/create/[peerType]/page.tsx b/ui/app/peers/create/[peerType]/page.tsx index 4aa958756a..bbb25b31ad 100644 --- a/ui/app/peers/create/[peerType]/page.tsx +++ b/ui/app/peers/create/[peerType]/page.tsx @@ -3,6 +3,7 @@ import { PeerConfig } from '@/app/dto/PeersDTO'; import GuideForDestinationSetup from '@/app/mirrors/create/cdc/guide'; import BigqueryForm from '@/components/PeerForms/BigqueryConfig'; import ClickhouseForm from '@/components/PeerForms/ClickhouseConfig'; +import KafkaForm from '@/components/PeerForms/KafkaConfig'; import PostgresForm from '@/components/PeerForms/PostgresForm'; import S3Form from '@/components/PeerForms/S3Form'; import SnowflakeForm from '@/components/PeerForms/SnowflakeForm'; @@ -81,6 +82,8 @@ export default function CreateConfig({ ); case 'S3': return ; + case 'KAFKA': + return ; default: return <>; } diff --git a/ui/app/peers/create/[peerType]/schema.ts b/ui/app/peers/create/[peerType]/schema.ts index 211acd69a7..117b8738fe 100644 --- a/ui/app/peers/create/[peerType]/schema.ts +++ b/ui/app/peers/create/[peerType]/schema.ts @@ -278,6 +278,33 @@ export const chSchema = z.object({ region: z .string({ invalid_type_error: 'Region must be a string' }) .optional(), + disableTls: z.boolean(), +}); + +export const kaSchema = z.object({ + servers: z + .array(z.string({ required_error: 'Server address must not be empty' })) + .min(1, { message: 'At least 1 server required' }), + username: z.string().optional(), + password: z.string().optional(), + sasl: z + .union([ + z.literal('PLAIN'), + z.literal('SCRAM-SHA-256'), + z.literal('SCRAM-SHA-512'), + ]) + .optional(), + partitioner: z + .union([ + z.literal('Default'), + z.literal('LeastBackup'), + z.literal('Manual'), + z.literal('RoundRobin'), + z.literal('StickyKey'), + z.literal('Sticky'), + ]) + .optional(), + disableTls: z.boolean().optional(), }); const urlSchema = z diff --git a/ui/components/PeerComponent.tsx b/ui/components/PeerComponent.tsx index 66851820ed..8505655c72 100644 --- a/ui/components/PeerComponent.tsx +++ b/ui/components/PeerComponent.tsx @@ -32,6 +32,9 @@ export const DBTypeToImageMapping = (peerType: DBType | string) => { case DBType.EVENTHUB_GROUP: case DBType.EVENTHUB: return '/svgs/ms.svg'; + case DBType.KAFKA: + case 'KAFKA': + return '/svgs/kafka.svg'; default: return '/svgs/pg.svg'; } diff --git a/ui/components/PeerForms/KafkaConfig.tsx b/ui/components/PeerForms/KafkaConfig.tsx new file mode 100644 index 0000000000..65df972ba5 --- /dev/null +++ b/ui/components/PeerForms/KafkaConfig.tsx @@ -0,0 +1,116 @@ +'use client'; +import { PeerSetter } from '@/app/dto/PeersDTO'; +import { kaSetting } from '@/app/peers/create/[peerType]/helpers/ka'; +import SelectTheme from '@/app/styles/select'; +import { Label } from '@/lib/Label'; +import { RowWithSelect, RowWithSwitch, RowWithTextField } from '@/lib/Layout'; +import { Switch } from '@/lib/Switch/Switch'; +import { TextField } from '@/lib/TextField'; +import { Tooltip } from '@/lib/Tooltip'; +import ReactSelect from 'react-select'; +import { InfoPopover } from '../InfoPopover'; +interface KafkaProps { + setter: PeerSetter; +} + +const KafkaForm = ({ setter }: KafkaProps) => { + return ( +
+ {kaSetting.map((setting, index) => { + return setting.type === 'switch' ? ( + + {setting.label}{' '} + {!setting.optional && ( + + + + )} + + } + action={ +
+ + setting.stateHandler(state, setter) + } + /> + {setting.tips && ( + + )} +
+ } + /> + ) : setting.type === 'select' ? ( + {setting.label}} + action={ + + val && setting.stateHandler(val.value, setter) + } + options={setting.options} + theme={SelectTheme} + /> + } + /> + ) : ( + + {setting.label}{' '} + {!setting.optional && ( + + + + )} + + } + action={ +
+ ) => + setting.stateHandler(e.target.value, setter) + } + /> + {setting.tips && ( + + )} +
+ } + /> + ); + })} +
+ ); +}; + +export default KafkaForm; diff --git a/ui/components/PeerTypeComponent.tsx b/ui/components/PeerTypeComponent.tsx index d315499a6d..2db4be9dd2 100644 --- a/ui/components/PeerTypeComponent.tsx +++ b/ui/components/PeerTypeComponent.tsx @@ -24,6 +24,8 @@ export const DBTypeToGoodText = (ptype: DBType) => { return 'MongoDB'; case DBType.CLICKHOUSE: return 'Clickhouse'; + case DBType.KAFKA: + return 'Kafka'; case DBType.UNRECOGNIZED: return 'Unrecognised'; } diff --git a/ui/components/SelectSource.tsx b/ui/components/SelectSource.tsx index e77d1b5e4d..eca7c37e61 100644 --- a/ui/components/SelectSource.tsx +++ b/ui/components/SelectSource.tsx @@ -34,7 +34,8 @@ export default function SelectSource({ value === 'SNOWFLAKE' || value === 'BIGQUERY' || value === 'S3' || - value === 'CLICKHOUSE') + value === 'CLICKHOUSE' || + value === 'KAFKA') ) .map((value) => ({ label: value, value })); diff --git a/ui/public/svgs/kafka.svg b/ui/public/svgs/kafka.svg new file mode 100644 index 0000000000..305d876447 --- /dev/null +++ b/ui/public/svgs/kafka.svg @@ -0,0 +1 @@ + From b0bdc86b57931dae8be096aef9303125954bdcd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sat, 23 Mar 2024 00:37:13 +0000 Subject: [PATCH 02/48] PubSub. Like Kafka, but with GCP auth (#1524) Shuffle some files around so lua.LState setup code can be moved to `connectors/utils`. Because it brought a dependency on `connectors/utils/catalog` which was then recursive. Moved `connectors/utils/catalog` to `peerdbenv`, & moved dependency in `shared` to `peerdbenv`, so that `shared` once again has no dependencies on other packages in repo. Required also moving `connectors/utils/postgres.go` to `shared/postgres.go`, since that file contains catalog related functionality, not postgres connector functionality --- e2e_cleanup/go.mod | 65 ++--- e2e_cleanup/go.sum | 170 ++++++------ e2e_cleanup/main.go | 47 +++- flow/activities/flowable.go | 2 +- flow/cmd/api.go | 6 +- flow/cmd/handler.go | 7 + flow/cmd/snapshot_worker.go | 6 +- flow/cmd/worker.go | 6 +- flow/connectors/bigquery/bigquery.go | 76 +---- flow/connectors/clickhouse/clickhouse.go | 3 +- flow/connectors/core.go | 4 + flow/connectors/external_metadata/store.go | 4 +- flow/connectors/kafka/kafka.go | 87 +----- flow/connectors/postgres/client.go | 3 +- flow/connectors/postgres/postgres.go | 6 +- .../postgres/postgres_schema_delta_test.go | 4 +- flow/connectors/postgres/qrep.go | 2 +- flow/connectors/postgres/qrep_bench_test.go | 4 +- .../postgres/qrep_partition_test.go | 4 +- .../postgres/qrep_query_executor_test.go | 4 +- flow/connectors/postgres/qrep_sql_sync.go | 2 +- flow/connectors/postgres/ssh_wrapped_pool.go | 3 +- flow/connectors/pubsub/pubsub.go | 262 ++++++++++++++++++ flow/connectors/utils/gcp.go | 115 ++++++++ flow/connectors/utils/lua.go | 74 +++++ flow/dynamicconf/dynamicconf.go | 4 +- flow/e2e/bigquery/peer_flow_bq_test.go | 4 +- flow/e2e/congen.go | 6 +- flow/e2e/kafka/kafka_test.go | 10 +- flow/e2e/postgres/peer_flow_pg_test.go | 3 +- flow/e2e/pubsub/pubsub_test.go | 239 ++++++++++++++++ flow/e2e/snowflake/peer_flow_sf_test.go | 4 +- flow/e2e/test_utils.go | 6 +- flow/go.mod | 1 + flow/go.sum | 2 + .../catalog/env.go => peerdbenv/catalog.go} | 17 +- flow/peerdbenv/config.go | 11 + flow/peerdbenv/env.go | 3 +- flow/pua/peerdb.go | 4 +- flow/shared/constants.go | 18 -- flow/{connectors/utils => shared}/postgres.go | 2 +- flow/shared/string.go | 7 + flow/workflows/cdc_flow.go | 2 +- flow/workflows/snapshot_flow.go | 3 +- nexus/analyzer/src/lib.rs | 79 +++++- nexus/catalog/src/lib.rs | 6 + protos/peers.proto | 19 ++ ui/app/api/peers/getTruePeer.ts | 6 + ui/app/api/peers/info/[peerName]/route.ts | 5 + ui/app/api/peers/route.ts | 7 + ui/app/dto/PeersDTO.ts | 4 +- ui/app/peers/create/[peerType]/handlers.ts | 5 + .../peers/create/[peerType]/helpers/common.ts | 6 + ui/app/peers/create/[peerType]/helpers/ka.ts | 2 +- ui/app/peers/create/[peerType]/helpers/ps.ts | 16 ++ ui/app/peers/create/[peerType]/page.tsx | 3 + ui/app/peers/create/[peerType]/schema.ts | 70 +++++ ui/app/peers/peersTable.tsx | 5 +- ui/components/PeerComponent.tsx | 3 + ui/components/PeerForms/BigqueryConfig.tsx | 2 +- ui/components/PeerForms/PubSubConfig.tsx | 92 ++++++ ui/components/PeerTypeComponent.tsx | 2 + ui/components/SelectSource.tsx | 3 +- ui/public/svgs/pubsub.svg | 29 ++ 64 files changed, 1311 insertions(+), 365 deletions(-) create mode 100644 flow/connectors/pubsub/pubsub.go create mode 100644 flow/connectors/utils/gcp.go create mode 100644 flow/connectors/utils/lua.go create mode 100644 flow/e2e/pubsub/pubsub_test.go rename flow/{connectors/utils/catalog/env.go => peerdbenv/catalog.go} (68%) rename flow/{connectors/utils => shared}/postgres.go (99%) create mode 100644 flow/shared/string.go create mode 100644 ui/app/peers/create/[peerType]/helpers/ps.ts create mode 100644 ui/components/PeerForms/PubSubConfig.tsx create mode 100644 ui/public/svgs/pubsub.svg diff --git a/e2e_cleanup/go.mod b/e2e_cleanup/go.mod index 524b7ff1cc..27625f98d9 100644 --- a/e2e_cleanup/go.mod +++ b/e2e_cleanup/go.mod @@ -4,35 +4,36 @@ go 1.22.0 require ( cloud.google.com/go/bigquery v1.59.1 + cloud.google.com/go/pubsub v1.37.0 github.com/snowflakedb/gosnowflake v1.8.0 github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a - google.golang.org/api v0.167.0 + google.golang.org/api v0.171.0 ) require ( - cloud.google.com/go v0.112.0 // indirect - cloud.google.com/go/compute v1.24.0 // indirect + cloud.google.com/go v0.112.1 // indirect + cloud.google.com/go/compute v1.25.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/iam v1.1.7 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.1 // indirect github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect github.com/apache/arrow/go/v14 v14.0.2 // indirect - github.com/aws/aws-sdk-go-v2 v1.25.2 // indirect + github.com/aws/aws-sdk-go-v2 v1.26.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.4 // indirect - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.6 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.9 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.2 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.51.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.4 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0 // indirect github.com/aws/smithy-go v1.20.1 // indirect github.com/danieljoos/wincred v1.2.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect @@ -44,12 +45,12 @@ require ( github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/flatbuffers v23.5.26+incompatible // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/flatbuffers v24.3.7+incompatible // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.1 // indirect + github.com/googleapis/gax-go/v2 v2.12.3 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/compress v1.17.7 // indirect @@ -65,22 +66,22 @@ require ( go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect - golang.org/x/crypto v0.19.0 // indirect - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.18.0 // indirect + golang.org/x/tools v0.19.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240221002015-b0ce06bbee7c // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect - google.golang.org/grpc v1.62.0 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/grpc v1.62.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect ) diff --git a/e2e_cleanup/go.sum b/e2e_cleanup/go.sum index b412b17e30..c25fbe13fd 100644 --- a/e2e_cleanup/go.sum +++ b/e2e_cleanup/go.sum @@ -1,34 +1,38 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= -cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.59.1 h1:CpT+/njKuKT3CEmswm6IbhNu9u35zt5dO4yPDLW+nG4= cloud.google.com/go/bigquery v1.59.1/go.mod h1:VP1UJYgevyTwsV7desjzNzDND5p6hZB+Z8gZJN1GQUc= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= +cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/datacatalog v1.19.3 h1:A0vKYCQdxQuV4Pi0LL9p39Vwvg4jH5yYveMv50gU5Tw= -cloud.google.com/go/datacatalog v1.19.3/go.mod h1:ra8V3UAsciBpJKQ+z9Whkxzxv7jmQg1hfODr3N3YPJ4= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/longrunning v0.5.5 h1:GOE6pZFdSrTb4KAiKnXsJBtlE6mEyaW44oKyMILWnOg= -cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s= -cloud.google.com/go/storage v1.37.0 h1:WI8CsaFO8Q9KjPVtsZ5Cmi0dXV25zMoX0FklT7c3Jm4= -cloud.google.com/go/storage v1.37.0/go.mod h1:i34TiT2IhiNDmcj65PqwCjcoUX7Z5pLzS8DEmoiFq1k= +cloud.google.com/go/datacatalog v1.20.0 h1:BGDsEjqpAo0Ka+b9yDLXnE5k+jU3lXGMh//NsEeDMIg= +cloud.google.com/go/datacatalog v1.20.0/go.mod h1:fSHaKjIroFpmRrYlwz9XBB2gJBpXufpnxyAKaT4w6L0= +cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= +cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= +cloud.google.com/go/kms v1.15.8 h1:szIeDCowID8th2i8XE4uRev5PMxQFqW+JjwYxL9h6xs= +cloud.google.com/go/kms v1.15.8/go.mod h1:WoUHcDjD9pluCg7pNds131awnH429QGvRM3N/4MyoVs= +cloud.google.com/go/longrunning v0.5.6 h1:xAe8+0YaWoCKr9t1+aWe+OeQgN/iJK1fEgZSXmjuEaE= +cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= +cloud.google.com/go/pubsub v1.37.0 h1:0uEEfaB1VIJzabPpwpZf44zWAKAme3zwKKxHk7vJQxQ= +cloud.google.com/go/pubsub v1.37.0/go.mod h1:YQOQr1uiUM092EXwKs56OPT650nwnawc+8/IjoUeGzQ= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 h1:c4k2FIYIh4xtwqrQwV0Ct1v5+ehlNXj5NI/MWVsiTkQ= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2/go.mod h1:5FDJtLEO/GxwNgUxbwrY3LP0pEoThTQJtk2oysdXHxM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 h1:n1DH8TPV4qqPTje2RcUBYwtrTWlabVp4n46+74X2pn4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0/go.mod h1:HDcZnuGbiyppErN6lB+idp4CKhjbc8gwjto6OPpyggM= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo= github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0 h1:IfFdxTUDiV58iZqPKgyWiz4X4fCxZeQ1pTQPImLYXpY= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0/go.mod h1:SUZc9YRRHfx2+FAQKNDGrssXehqLpxmwRv2mC/5ntj4= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.1 h1:fXPMAmuh0gDuRDey0atC8cXBuKIlqCzCkL8sm1n9Ov0= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.1/go.mod h1:SUZc9YRRHfx2+FAQKNDGrssXehqLpxmwRv2mC/5ntj4= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -36,42 +40,42 @@ github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvK github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/apache/arrow/go/v14 v14.0.2 h1:N8OkaJEOfI3mEZt07BIkvo4sC6XDbL+48MBPWO5IONw= github.com/apache/arrow/go/v14 v14.0.2/go.mod h1:u3fgh3EdgN/YQ8cVQRguVW3R+seMybFg8QBQ5LU+eBY= -github.com/aws/aws-sdk-go-v2 v1.25.2 h1:/uiG1avJRgLGiQM9X3qJM8+Qa6KRGK5rRPuXE0HUM+w= -github.com/aws/aws-sdk-go-v2 v1.25.2/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo= +github.com/aws/aws-sdk-go-v2 v1.26.0 h1:/Ce4OCiM3EkpW7Y+xUnfAFpchU78K7/Ug01sZni9PgA= +github.com/aws/aws-sdk-go-v2 v1.26.0/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo= -github.com/aws/aws-sdk-go-v2/config v1.27.4 h1:AhfWb5ZwimdsYTgP7Od8E9L1u4sKmDW2ZVeLcf2O42M= -github.com/aws/aws-sdk-go-v2/config v1.27.4/go.mod h1:zq2FFXK3A416kiukwpsd+rD4ny6JC7QSkp4QdN1Mp2g= -github.com/aws/aws-sdk-go-v2/credentials v1.17.4 h1:h5Vztbd8qLppiPwX+y0Q6WiwMZgpd9keKe2EAENgAuI= -github.com/aws/aws-sdk-go-v2/credentials v1.17.4/go.mod h1:+30tpwrkOgvkJL1rUZuRLoxcJwtI/OkeBLYnHxJtVe0= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 h1:AK0J8iYBFeUk2Ax7O8YpLtFsfhdOByh2QIkHmigpRYk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2/go.mod h1:iRlGzMix0SExQEviAyptRWRGdYNo3+ufW/lCzvKVTUc= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.6 h1:prcsGA3onmpc7ea1W/m+SMj4uOn5vZ63uJp805UhJJs= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.6/go.mod h1:7eQrvATnVFDY0WfMYhfKkSQ1YtZlClT71fAAlsA1s34= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 h1:bNo4LagzUKbjdxE0tIcR9pMzLR2U/Tgie1Hq1HQ3iH8= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2/go.mod h1:wRQv0nN6v9wDXuWThpovGQjqF1HFdcgWjporw14lS8k= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 h1:EtOU5jsPdIQNP+6Q2C5e3d65NKT1PeCiQk+9OdzO12Q= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2/go.mod h1:tyF5sKccmDz0Bv4NrstEr+/9YkSPJHrcO7UsUKf7pWM= +github.com/aws/aws-sdk-go-v2/config v1.27.9 h1:gRx/NwpNEFSk+yQlgmk1bmxxvQ5TyJ76CWXs9XScTqg= +github.com/aws/aws-sdk-go-v2/config v1.27.9/go.mod h1:dK1FQfpwpql83kbD873E9vz4FyAxuJtR22wzoXn3qq0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.9 h1:N8s0/7yW+h8qR8WaRlPQeJ6czVMNQVNtNdUqf6cItao= +github.com/aws/aws-sdk-go-v2/credentials v1.17.9/go.mod h1:446YhIdmSV0Jf/SLafGZalQo+xr2iw7/fzXGDPTU1yQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0 h1:af5YzcLf80tv4Em4jWVD75lpnOHSBkPUZxZfGkrI3HI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0/go.mod h1:nQ3how7DMnFMWiU1SpECohgC82fpn4cKZ875NDMmwtA= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.13 h1:F+PUZee9mlfpEJVZdgyewRumKekS9O3fftj8fEMt0rQ= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.13/go.mod h1:Rl7i2dEWGHGsBIJCpUxlRt7VwK/HyXxICxdvIRssQHE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 h1:0ScVK/4qZ8CIW0k8jOeFVsyS/sAiXpYxRBLolMkuLQM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4/go.mod h1:84KyjNZdHC6QZW08nfHI6yZgPd+qRgaWcYsyLUo3QY8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 h1:sHmMWWX5E7guWEFQ9SVo6A3S4xpPrWnd77a6y4WM6PU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4/go.mod h1:WjpDrhWisWOIoS9n3nk67A3Ll1vfULJ9Kq6h29HTD48= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.2 h1:en92G0Z7xlksoOylkUhuBSfJgijC7rHVLRdnIlHEs0E= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.2/go.mod h1:HgtQ/wN5G+8QSlK62lbOtNwQ3wTSByJ4wH2rCkPt+AE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.4 h1:SIkD6T4zGQ+1YIit22wi37CGNkrE7mXV1vNA5VpI3TI= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.4/go.mod h1:XfeqbsG0HNedNs0GT+ju4Bs+pFAwsrlzcRdMvdNVf5s= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.2 h1:zSdTXYLwuXDNPUS+V41i1SFDXG7V0ITp0D9UT9Cvl18= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.2/go.mod h1:v8m8k+qVy95nYi7d56uP1QImleIIY25BPiNJYzPBdFE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2 h1:5ffmXjPtwRExp1zc7gENLgCPyHFbhEPwVTkTiH9niSk= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2/go.mod h1:Ru7vg1iQ7cR4i7SZ/JTLYN9kaXtbL69UdgG0OQWQxW0= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.2 h1:1oY1AVEisRI4HNuFoLdRUB0hC63ylDAN6Me3MrfclEg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.2/go.mod h1:KZ03VgvZwSjkT7fOetQ/wF3MZUvYFirlI1H5NklUNsY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.51.1 h1:juZ+uGargZOrQGNxkVHr9HHR/0N+Yu8uekQnV7EAVRs= -github.com/aws/aws-sdk-go-v2/service/s3 v1.51.1/go.mod h1:SoR0c7Jnq8Tpmt0KSLXIavhjmaagRqQpe9r70W3POJg= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.1 h1:utEGkfdQ4L6YW/ietH7111ZYglLJvS+sLriHJ1NBJEQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.1/go.mod h1:RsYqzYr2F2oPDdpy+PdhephuZxTfjHQe7SOBcZGoAU8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1 h1:9/GylMS45hGGFCcMrUZDVayQE1jYSIN6da9jo7RAYIw= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1/go.mod h1:YjAPFn4kGFqKC54VsHs5fn5B6d+PCY2tziEa3U/GB5Y= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.1 h1:3I2cBEYgKhrWlwyZgfpSO2BpaMY1LHPqXYk/QGlu2ew= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.1/go.mod h1:uQ7YYKZt3adCRrdCBREm1CD3efFLOUNH77MrUCvx5oA= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.6 h1:NkHCgg0Ck86c5PTOzBZ0JRccI51suJDg5lgFtxBu1ek= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.6/go.mod h1:mjTpxjC8v4SeINTngrnKFgm2QUi+Jm+etTbCxh8W4uU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 h1:b+E7zIUHMmcB4Dckjpkapoy47W6C9QBv/zoUP+Hn8Kc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6/go.mod h1:S2fNV0rxrP78NhPbCZeQgY8H9jdDMeGtwcfZIRxzBqU= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.4 h1:uDj2K47EM1reAYU9jVlQ1M5YENI1u6a/TxJpf6AeOLA= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.4/go.mod h1:XKCODf4RKHppc96c2EZBGV/oCUC7OClxAo2MEyg4pIk= +github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0 h1:r3o2YsgW9zRcIP3Q0WCmttFVhTuugeKIvT5z9xDspc0= +github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0/go.mod h1:w2E4f8PUfNtyjfL6Iu+mWI96FGttE03z3UdNcUEC4tA= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 h1:mnbuWHOcM70/OFUlZZ5rcdfA8PflGXXiefU/O+1S3+8= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.3/go.mod h1:5HFu51Elk+4oRBZVxmHrSds5jFXmFj8C3w7DVF2gnrs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 h1:uLq0BKatTmDzWa/Nu4WO0M1AaQDaPpwTKAeByEc6WFM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3/go.mod h1:b+qdhjnxj8GSR6t5YfphOffeoQSQ1KmpoVVuBn+PWxs= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 h1:J/PpTf/hllOjx8Xu9DMflff3FajfLxqM5+tepvVXmxg= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.5/go.mod h1:0ih0Z83YDH/QeQ6Ori2yGE2XvWYv/Xm+cZc01LC6oK0= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -123,10 +127,10 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= -github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/flatbuffers v24.3.7+incompatible h1:BxGUkIQnOciBu33bd5BdvqY8Qvo0O/GR4SPhh7x9Ed0= +github.com/google/flatbuffers v24.3.7+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -145,8 +149,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.12.1 h1:9F8GV9r9ztXyAi00gsMQHNoF51xPZm8uj1dpYt2ZETM= -github.com/googleapis/gax-go/v2 v2.12.1/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -198,6 +202,8 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.einride.tech/aip v0.66.0 h1:XfV+NQX6L7EOYK11yoHHFtndeaWh3KbD9/cN/6iWEt8= +go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= @@ -208,25 +214,25 @@ go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= +go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc= +golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -236,11 +242,11 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -258,12 +264,12 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -279,16 +285,16 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.12.0 h1:xKuo6hzt+gMav00meVPUlXwSdoEJP46BR+wdxQEFK2o= gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY= -google.golang.org/api v0.167.0 h1:CKHrQD1BLRii6xdkatBDXyKzM0mkawt2QP+H3LtPmSE= -google.golang.org/api v0.167.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe/bSA= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= @@ -296,19 +302,19 @@ google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c h1:Zmyn5CV/jxzKnF+3d+xzbomACPwLQqVpLTpyXN5uTaQ= -google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240221002015-b0ce06bbee7c h1:9g7erC9qu44ks7UK4gDNlnk4kOxZG707xKm4jVniy6o= -google.golang.org/genproto/googleapis/api v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c h1:NUsgEN92SQQqzfA+YtqYNqYmB3DMMYLlIwUZAQFVFbo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237 h1:PgNlNSx2Nq2/j4juYzQBG0/Zdr+WP4z5N01Vk4VYBCY= +google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237/go.mod h1:9sVD8c25Af3p0rGs7S7LLsxWKFiJt/65LdSyqXBkX/Y= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= -google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -320,8 +326,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/e2e_cleanup/main.go b/e2e_cleanup/main.go index 1fe7ba6bac..b46d95529c 100644 --- a/e2e_cleanup/main.go +++ b/e2e_cleanup/main.go @@ -15,6 +15,7 @@ import ( "time" "cloud.google.com/go/bigquery" + "cloud.google.com/go/pubsub" "github.com/snowflakedb/gosnowflake" "github.com/youmark/pkcs8" "google.golang.org/api/iterator" @@ -59,6 +60,16 @@ func ParseJsonKeyVal[T any](path string) (T, error) { return result, err } +func handleIteratorError(err error) bool { + if err != nil { + if err == iterator.Done { + return true + } + panic(err) + } + return false +} + func CleanupBQ(ctx context.Context) { config, err := ParseJsonKeyVal[map[string]string](os.Getenv("TEST_BQ_CREDS")) if err != nil { @@ -86,11 +97,8 @@ func CleanupBQ(ctx context.Context) { datasetPrefix := config["dataset_id"] for { ds, err := datasets.Next() - if err != nil { - if err == iterator.Done { - return - } - panic(err) + if handleIteratorError(err) { + break } if strings.HasPrefix(ds.DatasetID, datasetPrefix) { @@ -106,6 +114,35 @@ func CleanupBQ(ctx context.Context) { } } } + + // now pubsub too, lack metadata to avoid deleting currently running tests + psclient, err := pubsub.NewClient(ctx, config["project_id"], option.WithCredentialsJSON(config_json)) + if err != nil { + panic(err) + } + defer psclient.Close() + + topics := psclient.Topics(ctx) + for { + topic, err := topics.Next() + if handleIteratorError(err) { + break + } + if strings.HasPrefix(topic.ID(), "e2e") { + topic.Delete(ctx) + } + } + + subscriptions := psclient.Subscriptions(ctx) + for { + subscription, err := subscriptions.Next() + if handleIteratorError(err) { + break + } + if strings.HasPrefix(subscription.ID(), "e2e") { + subscription.Delete(ctx) + } + } } func CleanupSF(ctx context.Context) { diff --git a/flow/activities/flowable.go b/flow/activities/flowable.go index 3d6e7815b7..1f7601b719 100644 --- a/flow/activities/flowable.go +++ b/flow/activities/flowable.go @@ -855,7 +855,7 @@ func (a *FlowableActivity) SendWALHeartbeat(ctx context.Context) error { func() { pgConfig := pgPeer.GetPostgresConfig() - peerConn, peerErr := pgx.Connect(ctx, utils.GetPGConnectionString(pgConfig)) + peerConn, peerErr := pgx.Connect(ctx, shared.GetPGConnectionString(pgConfig)) if peerErr != nil { logger.Error(fmt.Sprintf("error creating pool for postgres peer %v with host %v: %v", pgPeer.Name, pgConfig.Host, peerErr)) diff --git a/flow/cmd/api.go b/flow/cmd/api.go index 5803d42317..cf4d84b678 100644 --- a/flow/cmd/api.go +++ b/flow/cmd/api.go @@ -21,9 +21,9 @@ import ( "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/reflection" - utils "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" peerflow "github.com/PeerDB-io/peer-flow/workflows" ) @@ -119,12 +119,12 @@ func APIMain(ctx context.Context, args *APIServerParams) error { grpcServer := grpc.NewServer() - catalogConn, err := utils.GetCatalogConnectionPoolFromEnv(ctx) + catalogConn, err := peerdbenv.GetCatalogConnectionPoolFromEnv(ctx) if err != nil { return fmt.Errorf("unable to get catalog connection pool: %w", err) } - taskQueue := shared.GetPeerFlowTaskQueueName(shared.PeerFlowTaskQueue) + taskQueue := peerdbenv.PeerFlowTaskQueueName(shared.PeerFlowTaskQueue) flowHandler := NewFlowRequestHandler(tc, catalogConn, taskQueue) err = killExistingScheduleFlows(ctx, tc, args.TemporalNamespace, taskQueue) diff --git a/flow/cmd/handler.go b/flow/cmd/handler.go index f0264608bb..7c528d8333 100644 --- a/flow/cmd/handler.go +++ b/flow/cmd/handler.go @@ -576,6 +576,13 @@ func (h *FlowRequestHandler) CreatePeer( } kaConfig := kaConfigObject.KafkaConfig encodedConfig, encodingErr = proto.Marshal(kaConfig) + case protos.DBType_PUBSUB: + psConfigObject, ok := config.(*protos.Peer_PubsubConfig) + if !ok { + return wrongConfigResponse, nil + } + psConfig := psConfigObject.PubsubConfig + encodedConfig, encodingErr = proto.Marshal(psConfig) default: return wrongConfigResponse, nil } diff --git a/flow/cmd/snapshot_worker.go b/flow/cmd/snapshot_worker.go index b7418e9ceb..128759a474 100644 --- a/flow/cmd/snapshot_worker.go +++ b/flow/cmd/snapshot_worker.go @@ -12,8 +12,8 @@ import ( "github.com/PeerDB-io/peer-flow/activities" "github.com/PeerDB-io/peer-flow/alerting" - utils "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" peerflow "github.com/PeerDB-io/peer-flow/workflows" ) @@ -47,7 +47,7 @@ func SnapshotWorkerMain(opts *SnapshotWorkerOptions) (client.Client, worker.Work clientOptions.ConnectionOptions = connOptions } - conn, err := utils.GetCatalogConnectionPoolFromEnv(context.Background()) + conn, err := peerdbenv.GetCatalogConnectionPoolFromEnv(context.Background()) if err != nil { return nil, nil, fmt.Errorf("unable to create catalog connection pool: %w", err) } @@ -57,7 +57,7 @@ func SnapshotWorkerMain(opts *SnapshotWorkerOptions) (client.Client, worker.Work return nil, nil, fmt.Errorf("unable to create Temporal client: %w", err) } - taskQueue := shared.GetPeerFlowTaskQueueName(shared.SnapshotFlowTaskQueue) + taskQueue := peerdbenv.PeerFlowTaskQueueName(shared.SnapshotFlowTaskQueue) w := worker.New(c, taskQueue, worker.Options{ EnableSessionWorker: true, OnFatalError: func(err error) { diff --git a/flow/cmd/worker.go b/flow/cmd/worker.go index 8977108be7..a499a26e2d 100644 --- a/flow/cmd/worker.go +++ b/flow/cmd/worker.go @@ -16,8 +16,8 @@ import ( "github.com/PeerDB-io/peer-flow/activities" "github.com/PeerDB-io/peer-flow/alerting" "github.com/PeerDB-io/peer-flow/connectors" - utils "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" peerflow "github.com/PeerDB-io/peer-flow/workflows" ) @@ -98,7 +98,7 @@ func WorkerMain(opts *WorkerOptions) (client.Client, worker.Worker, error) { clientOptions.ConnectionOptions = connOptions } - conn, err := utils.GetCatalogConnectionPoolFromEnv(context.Background()) + conn, err := peerdbenv.GetCatalogConnectionPoolFromEnv(context.Background()) if err != nil { return nil, nil, fmt.Errorf("unable to create catalog connection pool: %w", err) } @@ -109,7 +109,7 @@ func WorkerMain(opts *WorkerOptions) (client.Client, worker.Worker, error) { } slog.Info("Created temporal client") - taskQueue := shared.GetPeerFlowTaskQueueName(shared.PeerFlowTaskQueue) + taskQueue := peerdbenv.PeerFlowTaskQueueName(shared.PeerFlowTaskQueue) w := worker.New(c, taskQueue, worker.Options{ EnableSessionWorker: true, OnFatalError: func(err error) { diff --git a/flow/connectors/bigquery/bigquery.go b/flow/connectors/bigquery/bigquery.go index db56cfd9fc..7dc1b3b77e 100644 --- a/flow/connectors/bigquery/bigquery.go +++ b/flow/connectors/bigquery/bigquery.go @@ -2,7 +2,6 @@ package connbigquery import ( "context" - "encoding/json" "errors" "fmt" "log/slog" @@ -17,16 +16,15 @@ import ( "go.temporal.io/sdk/activity" "go.temporal.io/sdk/log" "google.golang.org/api/iterator" - "google.golang.org/api/option" metadataStore "github.com/PeerDB-io/peer-flow/connectors/external_metadata" "github.com/PeerDB-io/peer-flow/connectors/utils" - cc "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/numeric" "github.com/PeerDB-io/peer-flow/model/qvalue" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" ) @@ -34,19 +32,6 @@ const ( SyncRecordsBatchSize = 1024 ) -type BigQueryServiceAccount struct { - Type string `json:"type"` - ProjectID string `json:"project_id"` - PrivateKeyID string `json:"private_key_id"` - PrivateKey string `json:"private_key"` - ClientEmail string `json:"client_email"` - ClientID string `json:"client_id"` - AuthURI string `json:"auth_uri"` - TokenURI string `json:"token_uri"` - AuthProviderX509CertURL string `json:"auth_provider_x509_cert_url"` - ClientX509CertURL string `json:"client_x509_cert_url"` -} - type BigQueryConnector struct { bqConfig *protos.BigqueryConfig client *bigquery.Client @@ -58,8 +43,8 @@ type BigQueryConnector struct { logger log.Logger } -func NewBigQueryServiceAccount(bqConfig *protos.BigqueryConfig) (*BigQueryServiceAccount, error) { - var serviceAccount BigQueryServiceAccount +func NewBigQueryServiceAccount(bqConfig *protos.BigqueryConfig) (*utils.GcpServiceAccount, error) { + var serviceAccount utils.GcpServiceAccount serviceAccount.Type = bqConfig.AuthType serviceAccount.ProjectID = bqConfig.ProjectId serviceAccount.PrivateKeyID = bqConfig.PrivateKeyId @@ -78,59 +63,6 @@ func NewBigQueryServiceAccount(bqConfig *protos.BigqueryConfig) (*BigQueryServic return &serviceAccount, nil } -// Validate validates a BigQueryServiceAccount, that none of the fields are empty. -func (bqsa *BigQueryServiceAccount) Validate() error { - v := reflect.ValueOf(*bqsa) - for i := range v.NumField() { - if v.Field(i).String() == "" { - return fmt.Errorf("field %s is empty", v.Type().Field(i).Name) - } - } - return nil -} - -// Return BigQueryServiceAccount as JSON byte array -func (bqsa *BigQueryServiceAccount) ToJSON() ([]byte, error) { - return json.Marshal(bqsa) -} - -// CreateBigQueryClient creates a new BigQuery client from a BigQueryServiceAccount. -func (bqsa *BigQueryServiceAccount) CreateBigQueryClient(ctx context.Context) (*bigquery.Client, error) { - bqsaJSON, err := bqsa.ToJSON() - if err != nil { - return nil, fmt.Errorf("failed to get json: %v", err) - } - - client, err := bigquery.NewClient( - ctx, - bqsa.ProjectID, - option.WithCredentialsJSON(bqsaJSON), - ) - if err != nil { - return nil, fmt.Errorf("failed to create BigQuery client: %v", err) - } - - return client, nil -} - -// CreateStorageClient creates a new Storage client from a BigQueryServiceAccount. -func (bqsa *BigQueryServiceAccount) CreateStorageClient(ctx context.Context) (*storage.Client, error) { - bqsaJSON, err := bqsa.ToJSON() - if err != nil { - return nil, fmt.Errorf("failed to get json: %v", err) - } - - client, err := storage.NewClient( - ctx, - option.WithCredentialsJSON(bqsaJSON), - ) - if err != nil { - return nil, fmt.Errorf("failed to create Storage client: %v", err) - } - - return client, nil -} - // ValidateCheck: // 1. Creates a table // 2. Inserts one row into the table @@ -212,7 +144,7 @@ func NewBigQueryConnector(ctx context.Context, config *protos.BigqueryConfig) (* return nil, fmt.Errorf("failed to create Storage client: %v", err) } - catalogPool, err := cc.GetCatalogConnectionPoolFromEnv(ctx) + catalogPool, err := peerdbenv.GetCatalogConnectionPoolFromEnv(ctx) if err != nil { return nil, fmt.Errorf("failed to create catalog connection pool: %v", err) } diff --git a/flow/connectors/clickhouse/clickhouse.go b/flow/connectors/clickhouse/clickhouse.go index a4e959b505..fbd9b75eaa 100644 --- a/flow/connectors/clickhouse/clickhouse.go +++ b/flow/connectors/clickhouse/clickhouse.go @@ -16,6 +16,7 @@ import ( "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" ) @@ -113,7 +114,7 @@ func NewClickhouseConnector( if clickhouseS3Creds.AccessKeyID == "" && clickhouseS3Creds.SecretAccessKey == "" && clickhouseS3Creds.Region == "" && clickhouseS3Creds.BucketPath == "" { - deploymentUID := shared.GetDeploymentUID() + deploymentUID := peerdbenv.PeerDBDeploymentUID() flowName, _ := ctx.Value(shared.FlowNameKey).(string) bucketPathSuffix := fmt.Sprintf("%s/%s", url.PathEscape(deploymentUID), url.PathEscape(flowName)) diff --git a/flow/connectors/core.go b/flow/connectors/core.go index 4251c1726a..3387cf963b 100644 --- a/flow/connectors/core.go +++ b/flow/connectors/core.go @@ -13,6 +13,7 @@ import ( conneventhub "github.com/PeerDB-io/peer-flow/connectors/eventhub" connkafka "github.com/PeerDB-io/peer-flow/connectors/kafka" connpostgres "github.com/PeerDB-io/peer-flow/connectors/postgres" + connpubsub "github.com/PeerDB-io/peer-flow/connectors/pubsub" conns3 "github.com/PeerDB-io/peer-flow/connectors/s3" connsnowflake "github.com/PeerDB-io/peer-flow/connectors/snowflake" connsqlserver "github.com/PeerDB-io/peer-flow/connectors/sqlserver" @@ -205,6 +206,8 @@ func GetConnector(ctx context.Context, config *protos.Peer) (Connector, error) { return connclickhouse.NewClickhouseConnector(ctx, inner.ClickhouseConfig) case *protos.Peer_KafkaConfig: return connkafka.NewKafkaConnector(ctx, inner.KafkaConfig) + case *protos.Peer_PubsubConfig: + return connpubsub.NewPubSubConnector(ctx, inner.PubsubConfig) default: return nil, ErrUnsupportedFunctionality } @@ -264,6 +267,7 @@ var ( _ CDCSyncConnector = &connsnowflake.SnowflakeConnector{} _ CDCSyncConnector = &conneventhub.EventHubConnector{} _ CDCSyncConnector = &connkafka.KafkaConnector{} + _ CDCSyncConnector = &connpubsub.PubSubConnector{} _ CDCSyncConnector = &conns3.S3Connector{} _ CDCSyncConnector = &connclickhouse.ClickhouseConnector{} diff --git a/flow/connectors/external_metadata/store.go b/flow/connectors/external_metadata/store.go index bbe986b497..49a4ed4784 100644 --- a/flow/connectors/external_metadata/store.go +++ b/flow/connectors/external_metadata/store.go @@ -12,9 +12,9 @@ import ( "go.temporal.io/sdk/log" "google.golang.org/protobuf/encoding/protojson" - cc "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/peerdbenv" ) const ( @@ -28,7 +28,7 @@ type PostgresMetadataStore struct { } func NewPostgresMetadataStore(ctx context.Context) (*PostgresMetadataStore, error) { - pool, err := cc.GetCatalogConnectionPoolFromEnv(ctx) + pool, err := peerdbenv.GetCatalogConnectionPoolFromEnv(ctx) if err != nil { return nil, fmt.Errorf("failed to create catalog connection pool: %w", err) } diff --git a/flow/connectors/kafka/kafka.go b/flow/connectors/kafka/kafka.go index b879e31def..cefe73ca4b 100644 --- a/flow/connectors/kafka/kafka.go +++ b/flow/connectors/kafka/kafka.go @@ -3,12 +3,10 @@ package connkafka import ( "context" "crypto/tls" - "errors" "fmt" "log/slog" "strings" "sync" - "unsafe" "github.com/twmb/franz-go/pkg/kgo" "github.com/twmb/franz-go/pkg/sasl/plain" @@ -17,13 +15,14 @@ import ( "github.com/yuin/gopher-lua" "go.temporal.io/sdk/log" - "github.com/PeerDB-io/gluaflatbuffers" metadataStore "github.com/PeerDB-io/peer-flow/connectors/external_metadata" + "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/pua" + "github.com/PeerDB-io/peer-flow/shared" ) type KafkaConnector struct { @@ -32,31 +31,6 @@ type KafkaConnector struct { logger log.Logger } -func unsafeFastStringToReadOnlyBytes(s string) []byte { - return unsafe.Slice(unsafe.StringData(s), len(s)) -} - -func LVAsReadOnlyBytes(ls *lua.LState, v lua.LValue) ([]byte, error) { - str, err := LVAsStringOrNil(ls, v) - if err != nil { - return nil, err - } else if str == "" { - return nil, nil - } else { - return unsafeFastStringToReadOnlyBytes(str), nil - } -} - -func LVAsStringOrNil(ls *lua.LState, v lua.LValue) (string, error) { - if lstr, ok := v.(lua.LString); ok { - return string(lstr), nil - } else if v == lua.LNil { - return "", nil - } else { - return "", fmt.Errorf("invalid bytes, must be nil or string: %s", v) - } -} - func NewKafkaConnector( ctx context.Context, config *protos.KafkaConfig, @@ -158,59 +132,21 @@ func (c *KafkaConnector) SyncFlowCleanup(ctx context.Context, jobName string) er return c.pgMetadata.DropMetadata(ctx, jobName) } -func loadScript(ctx context.Context, script string, printfn lua.LGFunction) (*lua.LState, error) { - if script == "" { - return nil, errors.New("kafka mirror must have script") - } - - ls := lua.NewState(lua.Options{SkipOpenLibs: true}) - ls.SetContext(ctx) - for _, pair := range []struct { - n string - f lua.LGFunction - }{ - {lua.LoadLibName, lua.OpenPackage}, // Must be first - {lua.BaseLibName, lua.OpenBase}, - {lua.TabLibName, lua.OpenTable}, - {lua.StringLibName, lua.OpenString}, - {lua.MathLibName, lua.OpenMath}, - } { - ls.Push(ls.NewFunction(pair.f)) - ls.Push(lua.LString(pair.n)) - err := ls.PCall(1, 0, nil) - if err != nil { - return nil, fmt.Errorf("failed to initialize Lua runtime: %w", err) - } - } - ls.PreloadModule("flatbuffers", gluaflatbuffers.Loader) - pua.RegisterTypes(ls) - ls.Env.RawSetString("print", ls.NewFunction(printfn)) - err := ls.GPCall(pua.LoadPeerdbScript, lua.LString(script)) - if err != nil { - return nil, fmt.Errorf("error loading script %s: %w", script, err) - } - err = ls.PCall(0, 0, nil) - if err != nil { - return nil, fmt.Errorf("error executing script %s: %w", script, err) - } - return ls, nil -} - func lvalueToKafkaRecord(ls *lua.LState, value lua.LValue) (*kgo.Record, error) { var kr *kgo.Record switch v := value.(type) { case lua.LString: kr = kgo.StringRecord(string(v)) case *lua.LTable: - key, err := LVAsReadOnlyBytes(ls, ls.GetField(v, "key")) + key, err := utils.LVAsReadOnlyBytes(ls, ls.GetField(v, "key")) if err != nil { return nil, fmt.Errorf("invalid key, %w", err) } - value, err := LVAsReadOnlyBytes(ls, ls.GetField(v, "value")) + value, err := utils.LVAsReadOnlyBytes(ls, ls.GetField(v, "value")) if err != nil { return nil, fmt.Errorf("invalid value, %w", err) } - topic, err := LVAsStringOrNil(ls, ls.GetField(v, "topic")) + topic, err := utils.LVAsStringOrNil(ls, ls.GetField(v, "topic")) if err != nil { return nil, fmt.Errorf("invalid topic, %w", err) } @@ -225,9 +161,9 @@ func lvalueToKafkaRecord(ls *lua.LState, value lua.LValue) (*kgo.Record, error) if headers, ok := lheaders.(*lua.LTable); ok { headers.ForEach(func(k, v lua.LValue) { kstr := k.String() - vbytes, err := LVAsReadOnlyBytes(ls, v) + vbytes, err := utils.LVAsReadOnlyBytes(ls, v) if err != nil { - vbytes = unsafeFastStringToReadOnlyBytes(err.Error()) + vbytes = shared.UnsafeFastStringToReadOnlyBytes(err.Error()) } kr.Headers = append(kr.Headers, kgo.RecordHeader{ Key: kstr, @@ -257,7 +193,7 @@ func (c *KafkaConnector) SyncRecords(ctx context.Context, req *model.SyncRecords numRecords := int64(0) tableNameRowsMapping := make(map[string]uint32) - ls, err := loadScript(wgCtx, req.Script, func(ls *lua.LState) int { + ls, err := utils.LoadScript(wgCtx, req.Script, func(ls *lua.LState) int { top := ls.GetTop() ss := make([]string, top) for i := range top { @@ -307,6 +243,9 @@ func (c *KafkaConnector) SyncRecords(ctx context.Context, req *model.SyncRecords ls.SetTop(0) } + if err := c.client.Flush(ctx); err != nil { + return nil, fmt.Errorf("could not flush transaction: %w", err) + } waitChan := make(chan struct{}) go func() { wg.Wait() @@ -318,10 +257,6 @@ func (c *KafkaConnector) SyncRecords(ctx context.Context, req *model.SyncRecords case <-waitChan: } - if err := c.client.Flush(ctx); err != nil { - return nil, fmt.Errorf("could not flush transaction: %w", err) - } - lastCheckpoint := req.Records.GetLastCheckpoint() err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) if err != nil { diff --git a/flow/connectors/postgres/client.go b/flow/connectors/postgres/client.go index f667107bb2..54df692986 100644 --- a/flow/connectors/postgres/client.go +++ b/flow/connectors/postgres/client.go @@ -16,6 +16,7 @@ import ( "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/numeric" + "github.com/PeerDB-io/peer-flow/shared" ) type PGVersion int @@ -424,7 +425,7 @@ func (c *PostgresConnector) createSlotAndPublication( func (c *PostgresConnector) createMetadataSchema(ctx context.Context) error { _, err := c.conn.Exec(ctx, fmt.Sprintf(createSchemaSQL, c.metadataSchema)) - if err != nil && !utils.IsUniqueError(err) { + if err != nil && !shared.IsUniqueError(err) { return fmt.Errorf("error while creating internal schema: %w", err) } return nil diff --git a/flow/connectors/postgres/postgres.go b/flow/connectors/postgres/postgres.go index c57154bd7c..82cbd9dd6d 100644 --- a/flow/connectors/postgres/postgres.go +++ b/flow/connectors/postgres/postgres.go @@ -54,7 +54,7 @@ type ReplState struct { } func NewPostgresConnector(ctx context.Context, pgConfig *protos.PostgresConfig) (*PostgresConnector, error) { - connectionString := utils.GetPGConnectionString(pgConfig) + connectionString := shared.GetPGConnectionString(pgConfig) // create a separate connection pool for non-replication queries as replication connections cannot // be used for extended query protocol, i.e. prepared statements @@ -82,7 +82,7 @@ func NewPostgresConnector(ctx context.Context, pgConfig *protos.PostgresConfig) replConfig.Config.RuntimeParams["replication"] = "database" replConfig.Config.RuntimeParams["bytea_output"] = "hex" - customTypeMap, err := utils.GetCustomDataTypes(ctx, conn) + customTypeMap, err := shared.GetCustomDataTypes(ctx, conn) if err != nil { return nil, fmt.Errorf("failed to get custom type map: %w", err) } @@ -272,7 +272,7 @@ func (c *PostgresConnector) SetupMetadataTables(ctx context.Context) error { _, err = c.conn.Exec(ctx, fmt.Sprintf(createMirrorJobsTableSQL, c.metadataSchema, mirrorJobsTableIdentifier)) - if err != nil && !utils.IsUniqueError(err) { + if err != nil && !shared.IsUniqueError(err) { return fmt.Errorf("error creating table %s: %w", mirrorJobsTableIdentifier, err) } diff --git a/flow/connectors/postgres/postgres_schema_delta_test.go b/flow/connectors/postgres/postgres_schema_delta_test.go index e5603b02d9..c71c77c25c 100644 --- a/flow/connectors/postgres/postgres_schema_delta_test.go +++ b/flow/connectors/postgres/postgres_schema_delta_test.go @@ -9,10 +9,10 @@ import ( "github.com/jackc/pgx/v5" "github.com/stretchr/testify/require" - "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/e2eshared" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model/qvalue" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" ) @@ -25,7 +25,7 @@ type PostgresSchemaDeltaTestSuite struct { func SetupSuite(t *testing.T) PostgresSchemaDeltaTestSuite { t.Helper() - connector, err := NewPostgresConnector(context.Background(), utils.GetCatalogPostgresConfigFromEnv()) + connector, err := NewPostgresConnector(context.Background(), peerdbenv.GetCatalogPostgresConfigFromEnv()) require.NoError(t, err) setupTx, err := connector.conn.Begin(context.Background()) diff --git a/flow/connectors/postgres/qrep.go b/flow/connectors/postgres/qrep.go index ce9521ff4c..0544c16d3c 100644 --- a/flow/connectors/postgres/qrep.go +++ b/flow/connectors/postgres/qrep.go @@ -483,7 +483,7 @@ func (c *PostgresConnector) SetupQRepMetadataTables(ctx context.Context, config )`, metadataTableIdentifier.Sanitize()) // execute create table query _, err = c.conn.Exec(ctx, createQRepMetadataTableSQL) - if err != nil && !utils.IsUniqueError(err) { + if err != nil && !shared.IsUniqueError(err) { return fmt.Errorf("failed to create table %s: %w", qRepMetadataTableName, err) } c.logger.Info("Setup metadata table.") diff --git a/flow/connectors/postgres/qrep_bench_test.go b/flow/connectors/postgres/qrep_bench_test.go index f5882bf299..252b7520eb 100644 --- a/flow/connectors/postgres/qrep_bench_test.go +++ b/flow/connectors/postgres/qrep_bench_test.go @@ -4,14 +4,14 @@ import ( "context" "testing" - "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" + "github.com/PeerDB-io/peer-flow/peerdbenv" ) func BenchmarkQRepQueryExecutor(b *testing.B) { query := "SELECT * FROM bench.large_table" ctx := context.Background() - connector, err := NewPostgresConnector(ctx, utils.GetCatalogPostgresConfigFromEnv()) + connector, err := NewPostgresConnector(ctx, peerdbenv.GetCatalogPostgresConfigFromEnv()) if err != nil { b.Fatalf("failed to create connection: %v", err) } diff --git a/flow/connectors/postgres/qrep_partition_test.go b/flow/connectors/postgres/qrep_partition_test.go index 0512c68415..bcafbe2f76 100644 --- a/flow/connectors/postgres/qrep_partition_test.go +++ b/flow/connectors/postgres/qrep_partition_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "go.temporal.io/sdk/log" - "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" ) @@ -64,7 +64,7 @@ func newTestCaseForCTID(schema string, name string, rows uint32, expectedNum int } func TestGetQRepPartitions(t *testing.T) { - connStr := utils.GetCatalogConnectionStringFromEnv() + connStr := peerdbenv.GetCatalogConnectionStringFromEnv() // Setup the DB config, err := pgx.ParseConfig(connStr) diff --git a/flow/connectors/postgres/qrep_query_executor_test.go b/flow/connectors/postgres/qrep_query_executor_test.go index c2bc037372..cdb37b0349 100644 --- a/flow/connectors/postgres/qrep_query_executor_test.go +++ b/flow/connectors/postgres/qrep_query_executor_test.go @@ -11,13 +11,13 @@ import ( "github.com/jackc/pgx/v5" "github.com/shopspring/decimal" - "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" + "github.com/PeerDB-io/peer-flow/peerdbenv" ) func setupDB(t *testing.T) (*PostgresConnector, string) { t.Helper() - connector, err := NewPostgresConnector(context.Background(), utils.GetCatalogPostgresConfigFromEnv()) + connector, err := NewPostgresConnector(context.Background(), peerdbenv.GetCatalogPostgresConfigFromEnv()) if err != nil { t.Fatalf("unable to create connector: %v", err) } diff --git a/flow/connectors/postgres/qrep_sql_sync.go b/flow/connectors/postgres/qrep_sql_sync.go index 16ed755553..a6ccc5e224 100644 --- a/flow/connectors/postgres/qrep_sql_sync.go +++ b/flow/connectors/postgres/qrep_sql_sync.go @@ -59,7 +59,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( } defer txConn.Close(ctx) - err = utils.RegisterHStore(ctx, txConn) + err = shared.RegisterHStore(ctx, txConn) if err != nil { return 0, fmt.Errorf("failed to register hstore: %w", err) } diff --git a/flow/connectors/postgres/ssh_wrapped_pool.go b/flow/connectors/postgres/ssh_wrapped_pool.go index bfb19a48f3..ccfb6c6488 100644 --- a/flow/connectors/postgres/ssh_wrapped_pool.go +++ b/flow/connectors/postgres/ssh_wrapped_pool.go @@ -14,6 +14,7 @@ import ( "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/shared" ) type SSHTunnel struct { @@ -78,7 +79,7 @@ func (tunnel *SSHTunnel) NewPostgresConnFromPostgresConfig( ctx context.Context, pgConfig *protos.PostgresConfig, ) (*pgx.Conn, error) { - connectionString := utils.GetPGConnectionString(pgConfig) + connectionString := shared.GetPGConnectionString(pgConfig) connConfig, err := pgx.ParseConfig(connectionString) if err != nil { diff --git a/flow/connectors/pubsub/pubsub.go b/flow/connectors/pubsub/pubsub.go new file mode 100644 index 0000000000..6b51bb246a --- /dev/null +++ b/flow/connectors/pubsub/pubsub.go @@ -0,0 +1,262 @@ +package connpubsub + +import ( + "context" + "fmt" + "strings" + "sync" + + "cloud.google.com/go/pubsub" + "github.com/yuin/gopher-lua" + "go.temporal.io/sdk/log" + + metadataStore "github.com/PeerDB-io/peer-flow/connectors/external_metadata" + "github.com/PeerDB-io/peer-flow/connectors/utils" + "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/pua" + "github.com/PeerDB-io/peer-flow/shared" +) + +type PubSubConnector struct { + client *pubsub.Client + pgMetadata *metadataStore.PostgresMetadataStore + logger log.Logger +} + +func NewPubSubConnector( + ctx context.Context, + config *protos.PubSubConfig, +) (*PubSubConnector, error) { + sa := utils.GcpServiceAccountFromProto(config.ServiceAccount) + client, err := sa.CreatePubSubClient(ctx) + if err != nil { + return nil, fmt.Errorf("failed to create pubsub client: %w", err) + } + + pgMetadata, err := metadataStore.NewPostgresMetadataStore(ctx) + if err != nil { + return nil, err + } + + return &PubSubConnector{ + client: client, + pgMetadata: pgMetadata, + logger: logger.LoggerFromCtx(ctx), + }, nil +} + +func (c *PubSubConnector) Close() error { + if c != nil { + c.client.Close() + } + return nil +} + +func (c *PubSubConnector) ConnectionActive(ctx context.Context) error { + topic := c.client.Topic("test") + _, err := topic.Exists(ctx) + return err +} + +func (c *PubSubConnector) CreateRawTable(ctx context.Context, req *protos.CreateRawTableInput) (*protos.CreateRawTableOutput, error) { + return &protos.CreateRawTableOutput{TableIdentifier: "n/a"}, nil +} + +func (c *PubSubConnector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { + return c.pgMetadata.GetLastBatchID(ctx, jobName) +} + +func (c *PubSubConnector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { + return c.pgMetadata.FetchLastOffset(ctx, jobName) +} + +func (c *PubSubConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { + return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) +} + +func (c *PubSubConnector) NeedsSetupMetadataTables(_ context.Context) bool { + return false +} + +func (c *PubSubConnector) SetupMetadataTables(_ context.Context) error { + return nil +} + +func (c *PubSubConnector) ReplayTableSchemaDeltas(_ context.Context, flowJobName string, schemaDeltas []*protos.TableSchemaDelta) error { + return nil +} + +func (c *PubSubConnector) SyncFlowCleanup(ctx context.Context, jobName string) error { + return c.pgMetadata.DropMetadata(ctx, jobName) +} + +func lvalueToPubSubMessage(ls *lua.LState, value lua.LValue) (string, *pubsub.Message, error) { + var topic string + var msg *pubsub.Message + switch v := value.(type) { + case lua.LString: + msg = &pubsub.Message{ + Data: shared.UnsafeFastStringToReadOnlyBytes(string(v)), + } + case *lua.LTable: + key, err := utils.LVAsStringOrNil(ls, ls.GetField(v, "key")) + if err != nil { + return "", nil, fmt.Errorf("invalid key, %w", err) + } + value, err := utils.LVAsReadOnlyBytes(ls, ls.GetField(v, "value")) + if err != nil { + return "", nil, fmt.Errorf("invalid value, %w", err) + } + topic, err = utils.LVAsStringOrNil(ls, ls.GetField(v, "topic")) + if err != nil { + return "", nil, fmt.Errorf("invalid topic, %w", err) + } + msg = &pubsub.Message{ + OrderingKey: key, + Data: value, + } + lheaders := ls.GetField(v, "headers") + if headers, ok := lheaders.(*lua.LTable); ok { + msg.Attributes = make(map[string]string) + headers.ForEach(func(k, v lua.LValue) { + msg.Attributes[k.String()] = v.String() + }) + } else if lua.LVAsBool(lheaders) { + return "", nil, fmt.Errorf("invalid headers, must be nil or table: %s", lheaders) + } + case *lua.LNilType: + default: + return "", nil, fmt.Errorf("script returned invalid value: %s", value) + } + return topic, msg, nil +} + +func (c *PubSubConnector) SyncRecords(ctx context.Context, req *model.SyncRecordsRequest) (*model.SyncResponse, error) { + numRecords := int64(0) + tableNameRowsMapping := make(map[string]uint32) + + ls, err := utils.LoadScript(ctx, req.Script, func(ls *lua.LState) int { + top := ls.GetTop() + ss := make([]string, top) + for i := range top { + ss[i] = ls.ToStringMeta(ls.Get(i + 1)).String() + } + _ = c.pgMetadata.LogFlowInfo(ctx, req.FlowJobName, strings.Join(ss, "\t")) + return 0 + }) + if err != nil { + return nil, err + } + defer ls.Close() + + lfn := ls.Env.RawGetString("onRecord") + fn, ok := lfn.(*lua.LFunction) + if !ok { + return nil, fmt.Errorf("script should define `onRecord` as function, not %s", lfn) + } + + var wg sync.WaitGroup + wgCtx, wgErr := context.WithCancelCause(ctx) + publish := make(chan *pubsub.PublishResult, 60) + go func() { + var curpub *pubsub.PublishResult + for { + select { + case curpub, ok = <-publish: + if !ok { + return + } + case <-ctx.Done(): + wgErr(ctx.Err()) + return + } + _, err := curpub.Get(ctx) + if err != nil { + wgErr(err) + return + } + wg.Done() + } + }() + + topiccache := make(map[string]*pubsub.Topic) + for record := range req.Records.GetRecords() { + if err := ctx.Err(); err != nil { + return nil, err + } + ls.Push(fn) + ls.Push(pua.LuaRecord.New(ls, record)) + err := ls.PCall(1, -1, nil) + if err != nil { + return nil, fmt.Errorf("script failed: %w", err) + } + args := ls.GetTop() + for i := range args { + topic, msg, err := lvalueToPubSubMessage(ls, ls.Get(i-args)) + if err != nil { + return nil, err + } + if msg != nil { + if topic == "" { + topic = record.GetDestinationTableName() + } + topicClient, ok := topiccache[topic] + if !ok { + topicClient = c.client.Topic(topic) + exists, err := topicClient.Exists(ctx) + if err != nil { + return nil, fmt.Errorf("error checking if topic exists: %w", err) + } + if !exists { + topicClient, err = c.client.CreateTopic(ctx, topic) + if err != nil { + return nil, fmt.Errorf("error creating topic: %w", err) + } + } + topiccache[topic] = topicClient + } + + pubresult := topicClient.Publish(ctx, msg) + wg.Add(1) + publish <- pubresult + tableNameRowsMapping[topic] += 1 + } + } + numRecords += 1 + ls.SetTop(0) + } + + close(publish) + for _, topicClient := range topiccache { + if err := ctx.Err(); err != nil { + return nil, err + } + topicClient.Stop() + } + waitChan := make(chan struct{}) + go func() { + wg.Wait() + close(waitChan) + }() + select { + case <-wgCtx.Done(): + return nil, wgCtx.Err() + case <-waitChan: + } + + lastCheckpoint := req.Records.GetLastCheckpoint() + err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) + if err != nil { + return nil, err + } + + return &model.SyncResponse{ + CurrentSyncBatchID: req.SyncBatchID, + LastSyncedCheckpointID: lastCheckpoint, + NumRecordsSynced: numRecords, + TableNameRowsMapping: tableNameRowsMapping, + TableSchemaDeltas: req.Records.SchemaDeltas, + }, nil +} diff --git a/flow/connectors/utils/gcp.go b/flow/connectors/utils/gcp.go new file mode 100644 index 0000000000..09aa19c8a7 --- /dev/null +++ b/flow/connectors/utils/gcp.go @@ -0,0 +1,115 @@ +package utils + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + + "cloud.google.com/go/bigquery" + "cloud.google.com/go/pubsub" + "cloud.google.com/go/storage" + "google.golang.org/api/option" + + "github.com/PeerDB-io/peer-flow/generated/protos" +) + +type GcpServiceAccount struct { + Type string `json:"type"` + ProjectID string `json:"project_id"` + PrivateKeyID string `json:"private_key_id"` + PrivateKey string `json:"private_key"` + ClientEmail string `json:"client_email"` + ClientID string `json:"client_id"` + AuthURI string `json:"auth_uri"` + TokenURI string `json:"token_uri"` + AuthProviderX509CertURL string `json:"auth_provider_x509_cert_url"` + ClientX509CertURL string `json:"client_x509_cert_url"` +} + +func GcpServiceAccountFromProto(sa *protos.GcpServiceAccount) *GcpServiceAccount { + return &GcpServiceAccount{ + Type: sa.AuthType, + ProjectID: sa.ProjectId, + PrivateKeyID: sa.PrivateKeyId, + PrivateKey: sa.PrivateKey, + ClientEmail: sa.ClientEmail, + ClientID: sa.ClientId, + AuthURI: sa.AuthUri, + TokenURI: sa.TokenUri, + AuthProviderX509CertURL: sa.AuthProviderX509CertUrl, + ClientX509CertURL: sa.ClientX509CertUrl, + } +} + +// Validates a GcpServiceAccount, that none of the fields are empty. +func (sa *GcpServiceAccount) Validate() error { + v := reflect.ValueOf(*sa) + for i := range v.NumField() { + if v.Field(i).String() == "" { + return fmt.Errorf("field %s is empty", v.Type().Field(i).Name) + } + } + return nil +} + +// Return GcpServiceAccount as JSON byte array +func (sa *GcpServiceAccount) ToJSON() ([]byte, error) { + return json.Marshal(sa) +} + +// CreateBigQueryClient creates a new BigQuery client from a GcpServiceAccount. +func (sa *GcpServiceAccount) CreateBigQueryClient(ctx context.Context) (*bigquery.Client, error) { + saJSON, err := sa.ToJSON() + if err != nil { + return nil, fmt.Errorf("failed to get json: %v", err) + } + + client, err := bigquery.NewClient( + ctx, + sa.ProjectID, + option.WithCredentialsJSON(saJSON), + ) + if err != nil { + return nil, fmt.Errorf("failed to create BigQuery client: %v", err) + } + + return client, nil +} + +// CreateStorageClient creates a new Storage client from a GcpServiceAccount. +func (sa *GcpServiceAccount) CreateStorageClient(ctx context.Context) (*storage.Client, error) { + saJSON, err := sa.ToJSON() + if err != nil { + return nil, fmt.Errorf("failed to get json: %v", err) + } + + client, err := storage.NewClient( + ctx, + option.WithCredentialsJSON(saJSON), + ) + if err != nil { + return nil, fmt.Errorf("failed to create Storage client: %v", err) + } + + return client, nil +} + +// CreatePubSubClient creates a new PubSub client from a GcpServiceAccount. +func (sa *GcpServiceAccount) CreatePubSubClient(ctx context.Context) (*pubsub.Client, error) { + saJSON, err := sa.ToJSON() + if err != nil { + return nil, fmt.Errorf("failed to get json: %v", err) + } + + client, err := pubsub.NewClient( + ctx, + sa.ProjectID, + option.WithCredentialsJSON(saJSON), + ) + if err != nil { + return nil, fmt.Errorf("failed to create BigQuery client: %v", err) + } + + return client, nil +} diff --git a/flow/connectors/utils/lua.go b/flow/connectors/utils/lua.go new file mode 100644 index 0000000000..2acd8821b9 --- /dev/null +++ b/flow/connectors/utils/lua.go @@ -0,0 +1,74 @@ +package utils + +import ( + "context" + "errors" + "fmt" + + "github.com/yuin/gopher-lua" + + "github.com/PeerDB-io/gluaflatbuffers" + "github.com/PeerDB-io/peer-flow/pua" + "github.com/PeerDB-io/peer-flow/shared" +) + +var errEmptyScript = errors.New("mirror must have script") + +func LVAsReadOnlyBytes(ls *lua.LState, v lua.LValue) ([]byte, error) { + str, err := LVAsStringOrNil(ls, v) + if err != nil { + return nil, err + } else if str == "" { + return nil, nil + } else { + return shared.UnsafeFastStringToReadOnlyBytes(str), nil + } +} + +func LVAsStringOrNil(ls *lua.LState, v lua.LValue) (string, error) { + if lstr, ok := v.(lua.LString); ok { + return string(lstr), nil + } else if v == lua.LNil { + return "", nil + } else { + return "", fmt.Errorf("invalid bytes, must be nil or string: %s", v) + } +} + +func LoadScript(ctx context.Context, script string, printfn lua.LGFunction) (*lua.LState, error) { + if script == "" { + return nil, errEmptyScript + } + + ls := lua.NewState(lua.Options{SkipOpenLibs: true}) + ls.SetContext(ctx) + for _, pair := range []struct { + n string + f lua.LGFunction + }{ + {lua.LoadLibName, lua.OpenPackage}, // Must be first + {lua.BaseLibName, lua.OpenBase}, + {lua.TabLibName, lua.OpenTable}, + {lua.StringLibName, lua.OpenString}, + {lua.MathLibName, lua.OpenMath}, + } { + ls.Push(ls.NewFunction(pair.f)) + ls.Push(lua.LString(pair.n)) + err := ls.PCall(1, 0, nil) + if err != nil { + return nil, fmt.Errorf("failed to initialize Lua runtime: %w", err) + } + } + ls.PreloadModule("flatbuffers", gluaflatbuffers.Loader) + pua.RegisterTypes(ls) + ls.Env.RawSetString("print", ls.NewFunction(printfn)) + err := ls.GPCall(pua.LoadPeerdbScript, lua.LString(script)) + if err != nil { + return nil, fmt.Errorf("error loading script %s: %w", script, err) + } + err = ls.PCall(0, 0, nil) + if err != nil { + return nil, fmt.Errorf("error executing script %s: %w", script, err) + } + return ls, nil +} diff --git a/flow/dynamicconf/dynamicconf.go b/flow/dynamicconf/dynamicconf.go index 5225c400b1..080ae4ec00 100644 --- a/flow/dynamicconf/dynamicconf.go +++ b/flow/dynamicconf/dynamicconf.go @@ -8,8 +8,8 @@ import ( "github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgxpool" - utils "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/peerdbenv" ) func dynamicConfKeyExists(ctx context.Context, conn *pgxpool.Pool, key string) bool { @@ -25,7 +25,7 @@ func dynamicConfKeyExists(ctx context.Context, conn *pgxpool.Pool, key string) b } func dynamicConfUint32(ctx context.Context, key string, defaultValue uint32) uint32 { - conn, err := utils.GetCatalogConnectionPoolFromEnv(ctx) + conn, err := peerdbenv.GetCatalogConnectionPoolFromEnv(ctx) if err != nil { logger.LoggerFromCtx(ctx).Error("Failed to get catalog connection pool: %v", err) return defaultValue diff --git a/flow/e2e/bigquery/peer_flow_bq_test.go b/flow/e2e/bigquery/peer_flow_bq_test.go index c5c4170fbd..51ba631e60 100644 --- a/flow/e2e/bigquery/peer_flow_bq_test.go +++ b/flow/e2e/bigquery/peer_flow_bq_test.go @@ -12,11 +12,11 @@ import ( "github.com/jackc/pgx/v5/pgconn" "github.com/stretchr/testify/require" - "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/e2e" "github.com/PeerDB-io/peer-flow/e2eshared" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model/qvalue" + "github.com/PeerDB-io/peer-flow/shared" peerflow "github.com/PeerDB-io/peer-flow/workflows" ) @@ -388,7 +388,7 @@ func (s PeerFlowE2ETestSuiteBQ) Test_Types_BQ() { createMoodEnum := "CREATE TYPE mood AS ENUM ('happy', 'sad', 'angry');" var pgErr *pgconn.PgError _, enumErr := s.Conn().Exec(context.Background(), createMoodEnum) - if errors.As(enumErr, &pgErr) && pgErr.Code != pgerrcode.DuplicateObject && !utils.IsUniqueError(pgErr) { + if errors.As(enumErr, &pgErr) && pgErr.Code != pgerrcode.DuplicateObject && !shared.IsUniqueError(pgErr) { require.NoError(s.t, enumErr) } diff --git a/flow/e2e/congen.go b/flow/e2e/congen.go index 2fd3c180e5..6d19b48d4e 100644 --- a/flow/e2e/congen.go +++ b/flow/e2e/congen.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/require" connpostgres "github.com/PeerDB-io/peer-flow/connectors/postgres" - "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/peerdbenv" ) func cleanPostgres(conn *pgx.Conn, suffix string) error { @@ -106,7 +106,7 @@ func setupPostgresSchema(t *testing.T, conn *pgx.Conn, suffix string) error { func SetupPostgres(t *testing.T, suffix string) (*connpostgres.PostgresConnector, error) { t.Helper() - connector, err := connpostgres.NewPostgresConnector(context.Background(), utils.GetCatalogPostgresConfigFromEnv()) + connector, err := connpostgres.NewPostgresConnector(context.Background(), peerdbenv.GetCatalogPostgresConfigFromEnv()) if err != nil { return nil, fmt.Errorf("failed to create postgres connection: %w", err) } @@ -155,7 +155,7 @@ func GeneratePostgresPeer() *protos.Peer { Name: "test_postgres_peer", Type: protos.DBType_POSTGRES, Config: &protos.Peer_PostgresConfig{ - PostgresConfig: utils.GetCatalogPostgresConfigFromEnv(), + PostgresConfig: peerdbenv.GetCatalogPostgresConfigFromEnv(), }, } } diff --git a/flow/e2e/kafka/kafka_test.go b/flow/e2e/kafka/kafka_test.go index f35e0f568a..f055393545 100644 --- a/flow/e2e/kafka/kafka_test.go +++ b/flow/e2e/kafka/kafka_test.go @@ -95,9 +95,10 @@ func (s KafkaSuite) TestSimple() { ('e2e_kasimple', 'lua', 'function onRecord(r) return r.row and r.row.val end') on conflict do nothing`) require.NoError(s.t, err) + flowName := e2e.AddSuffix(s, "kasimple") connectionGen := e2e.FlowConnectionGenerationConfig{ - FlowJobName: e2e.AddSuffix(s, "kasimple"), - TableNameMapping: map[string]string{srcTableName: "katest"}, + FlowJobName: flowName, + TableNameMapping: map[string]string{srcTableName: flowName}, Destination: s.Peer(), } flowConnConfig := connectionGen.GenerateFlowConnectionConfigs() @@ -115,17 +116,18 @@ func (s KafkaSuite) TestSimple() { e2e.EnvWaitFor(s.t, env, 3*time.Minute, "normalize insert", func() bool { kafka, err := kgo.NewClient( kgo.SeedBrokers("localhost:9092"), - kgo.ConsumeTopics("katest"), + kgo.ConsumeTopics(flowName), ) if err != nil { return false } + defer kafka.Close() ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() fetches := kafka.PollFetches(ctx) fetches.EachTopic(func(ft kgo.FetchTopic) { - require.Equal(s.t, "katest", ft.Topic) + require.Equal(s.t, flowName, ft.Topic) ft.EachRecord(func(r *kgo.Record) { require.Equal(s.t, "testval", string(r.Value)) }) diff --git a/flow/e2e/postgres/peer_flow_pg_test.go b/flow/e2e/postgres/peer_flow_pg_test.go index eeec5e373d..74413a949b 100644 --- a/flow/e2e/postgres/peer_flow_pg_test.go +++ b/flow/e2e/postgres/peer_flow_pg_test.go @@ -13,7 +13,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/e2e" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" @@ -160,7 +159,7 @@ func (s PeerFlowE2ETestSuitePG) Test_Enums_PG() { createMoodEnum := "CREATE TYPE mood AS ENUM ('happy', 'sad', 'angry');" var pgErr *pgconn.PgError _, enumErr := s.Conn().Exec(context.Background(), createMoodEnum) - if errors.As(enumErr, &pgErr) && pgErr.Code != pgerrcode.DuplicateObject && !utils.IsUniqueError(enumErr) { + if errors.As(enumErr, &pgErr) && pgErr.Code != pgerrcode.DuplicateObject && !shared.IsUniqueError(enumErr) { require.NoError(s.t, enumErr) } _, err := s.Conn().Exec(context.Background(), fmt.Sprintf(` diff --git a/flow/e2e/pubsub/pubsub_test.go b/flow/e2e/pubsub/pubsub_test.go new file mode 100644 index 0000000000..c989f33aee --- /dev/null +++ b/flow/e2e/pubsub/pubsub_test.go @@ -0,0 +1,239 @@ +package e2e_kafka + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "strings" + "testing" + "time" + + "cloud.google.com/go/pubsub" + "github.com/jackc/pgx/v5" + "github.com/stretchr/testify/require" + + peer_bq "github.com/PeerDB-io/peer-flow/connectors/bigquery" + connpostgres "github.com/PeerDB-io/peer-flow/connectors/postgres" + "github.com/PeerDB-io/peer-flow/connectors/utils" + "github.com/PeerDB-io/peer-flow/e2e" + "github.com/PeerDB-io/peer-flow/e2eshared" + "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/shared" + peerflow "github.com/PeerDB-io/peer-flow/workflows" +) + +type PubSubSuite struct { + t *testing.T + conn *connpostgres.PostgresConnector + suffix string +} + +func (s PubSubSuite) T() *testing.T { + return s.t +} + +func (s PubSubSuite) Connector() *connpostgres.PostgresConnector { + return s.conn +} + +func (s PubSubSuite) Conn() *pgx.Conn { + return s.Connector().Conn() +} + +func (s PubSubSuite) Suffix() string { + return s.suffix +} + +func ServiceAccount() (*utils.GcpServiceAccount, error) { + jsonPath := os.Getenv("TEST_BQ_CREDS") + if jsonPath == "" { + return nil, errors.New("TEST_BQ_CREDS env var not set") + } + + content, err := e2eshared.ReadFileToBytes(jsonPath) + if err != nil { + return nil, fmt.Errorf("failed to read file: %w", err) + } + + var config *protos.BigqueryConfig + err = json.Unmarshal(content, &config) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal json: %w", err) + } + + return peer_bq.NewBigQueryServiceAccount(config) +} + +func (s PubSubSuite) Peer(name string, sa *utils.GcpServiceAccount) *protos.Peer { + return &protos.Peer{ + Name: e2e.AddSuffix(s, name), + Type: protos.DBType_PUBSUB, + Config: &protos.Peer_PubsubConfig{ + PubsubConfig: &protos.PubSubConfig{ + ServiceAccount: &protos.GcpServiceAccount{ + AuthType: sa.Type, + ProjectId: sa.ProjectID, + PrivateKeyId: sa.PrivateKeyID, + PrivateKey: sa.PrivateKey, + ClientEmail: sa.ClientEmail, + ClientId: sa.ClientID, + AuthUri: sa.AuthURI, + TokenUri: sa.TokenURI, + AuthProviderX509CertUrl: sa.AuthProviderX509CertURL, + ClientX509CertUrl: sa.ClientX509CertURL, + }, + }, + }, + } +} + +func (s PubSubSuite) DestinationTable(table string) string { + return table +} + +func (s PubSubSuite) Teardown() { + e2e.TearDownPostgres(s) +} + +func SetupSuite(t *testing.T) PubSubSuite { + t.Helper() + + suffix := "ps_" + strings.ToLower(shared.RandomString(8)) + conn, err := e2e.SetupPostgres(t, suffix) + require.NoError(t, err, "failed to setup postgres") + + return PubSubSuite{ + t: t, + conn: conn, + suffix: suffix, + } +} + +func Test_PubSub(t *testing.T) { + e2eshared.RunSuite(t, SetupSuite) +} + +func (s PubSubSuite) TestCreateTopic() { + srcTableName := e2e.AttachSchema(s, "pscreate") + + _, err := s.Conn().Exec(context.Background(), fmt.Sprintf(` + CREATE TABLE IF NOT EXISTS %s ( + id SERIAL PRIMARY KEY, + val text + ); + `, srcTableName)) + require.NoError(s.t, err) + + sa, err := ServiceAccount() + require.NoError(s.t, err) + + _, err = s.Conn().Exec(context.Background(), `insert into public.scripts (name, lang, source) values + ('e2e_pscreate', 'lua', 'function onRecord(r) return r.row and r.row.val end') on conflict do nothing`) + require.NoError(s.t, err) + + flowName := e2e.AddSuffix(s, "e2epscreate") + connectionGen := e2e.FlowConnectionGenerationConfig{ + FlowJobName: flowName, + TableNameMapping: map[string]string{srcTableName: flowName}, + Destination: s.Peer(flowName, sa), + } + flowConnConfig := connectionGen.GenerateFlowConnectionConfigs() + flowConnConfig.Script = "e2e_pscreate" + + tc := e2e.NewTemporalClient(s.t) + env := e2e.ExecutePeerflow(tc, peerflow.CDCFlowWorkflow, flowConnConfig, nil) + e2e.SetupCDCFlowStatusQuery(s.t, env, connectionGen) + + _, err = s.Conn().Exec(context.Background(), fmt.Sprintf(` + INSERT INTO %s (id, val) VALUES (1, 'testval') + `, srcTableName)) + require.NoError(s.t, err) + + e2e.EnvWaitFor(s.t, env, 3*time.Minute, "create topic", func() bool { + psclient, err := sa.CreatePubSubClient(context.Background()) + defer func() { + _ = psclient.Close() + }() + require.NoError(s.t, err) + topic := psclient.Topic(flowName) + exists, err := topic.Exists(context.Background()) + s.t.Log("WWWW exists", exists) + require.NoError(s.t, err) + return exists + }) + + env.Cancel() + e2e.RequireEnvCanceled(s.t, env) +} + +func (s PubSubSuite) TestSimple() { + srcTableName := e2e.AttachSchema(s, "pssimple") + + _, err := s.Conn().Exec(context.Background(), fmt.Sprintf(` + CREATE TABLE IF NOT EXISTS %s ( + id SERIAL PRIMARY KEY, + val text + ); + `, srcTableName)) + require.NoError(s.t, err) + + sa, err := ServiceAccount() + require.NoError(s.t, err) + + _, err = s.Conn().Exec(context.Background(), `insert into public.scripts (name, lang, source) values + ('e2e_pssimple', 'lua', 'function onRecord(r) return r.row and r.row.val end') on conflict do nothing`) + require.NoError(s.t, err) + + flowName := e2e.AddSuffix(s, "e2epssimple") + connectionGen := e2e.FlowConnectionGenerationConfig{ + FlowJobName: flowName, + TableNameMapping: map[string]string{srcTableName: flowName}, + Destination: s.Peer(flowName, sa), + } + flowConnConfig := connectionGen.GenerateFlowConnectionConfigs() + flowConnConfig.Script = "e2e_pssimple" + + psclient, err := sa.CreatePubSubClient(context.Background()) + require.NoError(s.t, err) + defer psclient.Close() + topic, err := psclient.CreateTopic(context.Background(), flowName) + require.NoError(s.t, err) + sub, err := psclient.CreateSubscription(context.Background(), flowName, pubsub.SubscriptionConfig{ + Topic: topic, + RetentionDuration: 10 * time.Minute, + ExpirationPolicy: 24 * time.Hour, + }) + require.NoError(s.t, err) + + tc := e2e.NewTemporalClient(s.t) + env := e2e.ExecutePeerflow(tc, peerflow.CDCFlowWorkflow, flowConnConfig, nil) + e2e.SetupCDCFlowStatusQuery(s.t, env, connectionGen) + + _, err = s.Conn().Exec(context.Background(), fmt.Sprintf(` + INSERT INTO %s (id, val) VALUES (1, 'testval') + `, srcTableName)) + require.NoError(s.t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) + defer cancel() + + msgs := make(chan *pubsub.Message) + go func() { + _ = sub.Receive(ctx, func(_ context.Context, m *pubsub.Message) { + msgs <- m + }) + }() + select { + case msg := <-msgs: + require.NotNil(s.t, msg) + require.Equal(s.t, "testval", string(msg.Data)) + case <-ctx.Done(): + s.t.Log("UNEXPECTED TIMEOUT PubSub subscription waiting on message") + s.t.Fail() + } + + env.Cancel() + e2e.RequireEnvCanceled(s.t, env) +} diff --git a/flow/e2e/snowflake/peer_flow_sf_test.go b/flow/e2e/snowflake/peer_flow_sf_test.go index 27e6156245..f75730658b 100644 --- a/flow/e2e/snowflake/peer_flow_sf_test.go +++ b/flow/e2e/snowflake/peer_flow_sf_test.go @@ -11,10 +11,10 @@ import ( "github.com/jackc/pgx/v5/pgconn" "github.com/stretchr/testify/require" - "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/e2e" "github.com/PeerDB-io/peer-flow/e2eshared" "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/shared" peerflow "github.com/PeerDB-io/peer-flow/workflows" ) @@ -389,7 +389,7 @@ func (s PeerFlowE2ETestSuiteSF) Test_Types_SF() { createMoodEnum := "CREATE TYPE mood AS ENUM ('happy', 'sad', 'angry');" var pgErr *pgconn.PgError _, enumErr := s.Conn().Exec(context.Background(), createMoodEnum) - if errors.As(enumErr, &pgErr) && pgErr.Code != pgerrcode.DuplicateObject && !utils.IsUniqueError(pgErr) { + if errors.As(enumErr, &pgErr) && pgErr.Code != pgerrcode.DuplicateObject && !shared.IsUniqueError(pgErr) { require.NoError(s.t, enumErr) } _, err := s.Conn().Exec(context.Background(), fmt.Sprintf(` diff --git a/flow/e2e/test_utils.go b/flow/e2e/test_utils.go index d2bcef6acb..f653c4732e 100644 --- a/flow/e2e/test_utils.go +++ b/flow/e2e/test_utils.go @@ -25,12 +25,12 @@ import ( "github.com/PeerDB-io/peer-flow/connectors" connpostgres "github.com/PeerDB-io/peer-flow/connectors/postgres" connsnowflake "github.com/PeerDB-io/peer-flow/connectors/snowflake" - "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/e2eshared" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/qvalue" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" peerflow "github.com/PeerDB-io/peer-flow/workflows" ) @@ -280,7 +280,7 @@ func CreateTableForQRep(conn *pgx.Conn, suffix string, tableName string) error { tblFieldStr := strings.Join(tblFields, ",") var pgErr *pgconn.PgError _, enumErr := conn.Exec(context.Background(), createMoodEnum) - if errors.As(enumErr, &pgErr) && pgErr.Code != pgerrcode.DuplicateObject && !utils.IsUniqueError(pgErr) { + if errors.As(enumErr, &pgErr) && pgErr.Code != pgerrcode.DuplicateObject && !shared.IsUniqueError(pgErr) { return enumErr } _, err := conn.Exec(context.Background(), fmt.Sprintf(` @@ -568,7 +568,7 @@ func ExecutePeerflow(tc client.Client, wf interface{}, args ...interface{}) Work } func ExecuteWorkflow(tc client.Client, taskQueueID shared.TaskQueueID, wf interface{}, args ...interface{}) WorkflowRun { - taskQueue := shared.GetPeerFlowTaskQueueName(taskQueueID) + taskQueue := peerdbenv.PeerFlowTaskQueueName(taskQueueID) wr, err := tc.ExecuteWorkflow( context.Background(), diff --git a/flow/go.mod b/flow/go.mod index 5a5fb83094..ad4d89786f 100644 --- a/flow/go.mod +++ b/flow/go.mod @@ -5,6 +5,7 @@ go 1.22.0 require ( cloud.google.com/go v0.112.1 cloud.google.com/go/bigquery v1.59.1 + cloud.google.com/go/pubsub v1.37.0 cloud.google.com/go/storage v1.39.1 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs v1.0.4 diff --git a/flow/go.sum b/flow/go.sum index aacfa2da10..98ed8f42cc 100644 --- a/flow/go.sum +++ b/flow/go.sum @@ -13,6 +13,8 @@ cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/longrunning v0.5.5 h1:GOE6pZFdSrTb4KAiKnXsJBtlE6mEyaW44oKyMILWnOg= cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s= +cloud.google.com/go/pubsub v1.37.0 h1:0uEEfaB1VIJzabPpwpZf44zWAKAme3zwKKxHk7vJQxQ= +cloud.google.com/go/pubsub v1.37.0/go.mod h1:YQOQr1uiUM092EXwKs56OPT650nwnawc+8/IjoUeGzQ= cloud.google.com/go/storage v1.39.1 h1:MvraqHKhogCOTXTlct/9C3K3+Uy2jBmFYb3/Sp6dVtY= cloud.google.com/go/storage v1.39.1/go.mod h1:xK6xZmxZmo+fyP7+DEF6FhNc24/JAe95OLyOHCXFH1o= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= diff --git a/flow/connectors/utils/catalog/env.go b/flow/peerdbenv/catalog.go similarity index 68% rename from flow/connectors/utils/catalog/env.go rename to flow/peerdbenv/catalog.go index 5e2cdc109c..1014e83060 100644 --- a/flow/connectors/utils/catalog/env.go +++ b/flow/peerdbenv/catalog.go @@ -1,4 +1,4 @@ -package utils +package peerdbenv import ( "context" @@ -7,9 +7,8 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/generated/protos" - "github.com/PeerDB-io/peer-flow/peerdbenv" + "github.com/PeerDB-io/peer-flow/shared" ) var ( @@ -39,15 +38,15 @@ func GetCatalogConnectionPoolFromEnv(ctx context.Context) (*pgxpool.Pool, error) } func GetCatalogConnectionStringFromEnv() string { - return utils.GetPGConnectionString(GetCatalogPostgresConfigFromEnv()) + return shared.GetPGConnectionString(GetCatalogPostgresConfigFromEnv()) } func GetCatalogPostgresConfigFromEnv() *protos.PostgresConfig { return &protos.PostgresConfig{ - Host: peerdbenv.PeerDBCatalogHost(), - Port: uint32(peerdbenv.PeerDBCatalogPort()), - User: peerdbenv.PeerDBCatalogUser(), - Password: peerdbenv.PeerDBCatalogPassword(), - Database: peerdbenv.PeerDBCatalogDatabase(), + Host: PeerDBCatalogHost(), + Port: uint32(PeerDBCatalogPort()), + User: PeerDBCatalogUser(), + Password: PeerDBCatalogPassword(), + Database: PeerDBCatalogDatabase(), } } diff --git a/flow/peerdbenv/config.go b/flow/peerdbenv/config.go index 1d0eacc01a..3f447e4ea8 100644 --- a/flow/peerdbenv/config.go +++ b/flow/peerdbenv/config.go @@ -1,7 +1,10 @@ package peerdbenv import ( + "fmt" "time" + + "github.com/PeerDB-io/peer-flow/shared" ) // This file contains functions to get the values of various peerdb environment @@ -18,6 +21,14 @@ func PeerDBDeploymentUID() string { return getEnvString("PEERDB_DEPLOYMENT_UID", "") } +func PeerFlowTaskQueueName(taskQueueID shared.TaskQueueID) string { + deploymentUID := PeerDBDeploymentUID() + if deploymentUID == "" { + return string(taskQueueID) + } + return fmt.Sprintf("%s-%s", deploymentUID, taskQueueID) +} + // PEERDB_CDC_CHANNEL_BUFFER_SIZE func PeerDBCDCChannelBufferSize() int { return getEnvInt("PEERDB_CDC_CHANNEL_BUFFER_SIZE", 1<<18) diff --git a/flow/peerdbenv/env.go b/flow/peerdbenv/env.go index 862ae07eb3..b4c4b8d0ac 100644 --- a/flow/peerdbenv/env.go +++ b/flow/peerdbenv/env.go @@ -2,6 +2,7 @@ package peerdbenv import ( "os" + "reflect" "strconv" "golang.org/x/exp/constraints" @@ -32,7 +33,7 @@ func getEnvUint[T constraints.Unsigned](name string, defaultValue T) T { } // widest bit size, truncate later - i, err := strconv.ParseUint(val, 10, 64) + i, err := strconv.ParseUint(val, 10, int(reflect.TypeFor[T]().Size()*8)) if err != nil { return defaultValue } diff --git a/flow/pua/peerdb.go b/flow/pua/peerdb.go index c8f9f8884c..b1746d75c3 100644 --- a/flow/pua/peerdb.go +++ b/flow/pua/peerdb.go @@ -13,9 +13,9 @@ import ( "github.com/PeerDB-io/glua64" "github.com/PeerDB-io/gluabit32" - "github.com/PeerDB-io/peer-flow/connectors/utils/catalog" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/qvalue" + "github.com/PeerDB-io/peer-flow/peerdbenv" ) var ( @@ -77,7 +77,7 @@ func RegisterTypes(ls *lua.LState) { func LoadPeerdbScript(ls *lua.LState) int { ctx := ls.Context() name := ls.CheckString(1) - pool, err := utils.GetCatalogConnectionPoolFromEnv(ctx) + pool, err := peerdbenv.GetCatalogConnectionPoolFromEnv(ctx) if err != nil { ls.RaiseError("Connection failed loading %s: %s", name, err.Error()) return 0 diff --git a/flow/shared/constants.go b/flow/shared/constants.go index e6e982c321..3e694ecd91 100644 --- a/flow/shared/constants.go +++ b/flow/shared/constants.go @@ -1,11 +1,5 @@ package shared -import ( - "fmt" - - "github.com/PeerDB-io/peer-flow/peerdbenv" -) - type ( ContextKey string TaskQueueID string @@ -34,15 +28,3 @@ const ( ) const FetchAndChannelSize = 256 * 1024 - -func GetPeerFlowTaskQueueName(taskQueueID TaskQueueID) string { - deploymentUID := peerdbenv.PeerDBDeploymentUID() - if deploymentUID == "" { - return string(taskQueueID) - } - return fmt.Sprintf("%s-%s", deploymentUID, taskQueueID) -} - -func GetDeploymentUID() string { - return peerdbenv.PeerDBDeploymentUID() -} diff --git a/flow/connectors/utils/postgres.go b/flow/shared/postgres.go similarity index 99% rename from flow/connectors/utils/postgres.go rename to flow/shared/postgres.go index 0a606c1feb..2467efedc7 100644 --- a/flow/connectors/utils/postgres.go +++ b/flow/shared/postgres.go @@ -1,4 +1,4 @@ -package utils +package shared import ( "context" diff --git a/flow/shared/string.go b/flow/shared/string.go new file mode 100644 index 0000000000..6f3a5c7f29 --- /dev/null +++ b/flow/shared/string.go @@ -0,0 +1,7 @@ +package shared + +import "unsafe" + +func UnsafeFastStringToReadOnlyBytes(s string) []byte { + return unsafe.Slice(unsafe.StringData(s), len(s)) +} diff --git a/flow/workflows/cdc_flow.go b/flow/workflows/cdc_flow.go index 2bcd21773b..d011acd690 100644 --- a/flow/workflows/cdc_flow.go +++ b/flow/workflows/cdc_flow.go @@ -304,7 +304,7 @@ func CDCFlowWorkflow( // next part of the setup is to snapshot-initial-copy and setup replication slots. snapshotFlowID := GetChildWorkflowID("snapshot-flow", cfg.FlowJobName, originalRunID) - taskQueue := shared.GetPeerFlowTaskQueueName(shared.SnapshotFlowTaskQueue) + taskQueue := peerdbenv.PeerFlowTaskQueueName(shared.SnapshotFlowTaskQueue) childSnapshotFlowOpts := workflow.ChildWorkflowOptions{ WorkflowID: snapshotFlowID, ParentClosePolicy: enums.PARENT_CLOSE_POLICY_REQUEST_CANCEL, diff --git a/flow/workflows/snapshot_flow.go b/flow/workflows/snapshot_flow.go index 8ec844cc4b..3c966b4f3f 100644 --- a/flow/workflows/snapshot_flow.go +++ b/flow/workflows/snapshot_flow.go @@ -17,6 +17,7 @@ import ( connpostgres "github.com/PeerDB-io/peer-flow/connectors/postgres" "github.com/PeerDB-io/peer-flow/connectors/utils" "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" ) @@ -122,7 +123,7 @@ func (s *SnapshotFlowExecution) cloneTable( s.logger.Info(fmt.Sprintf("Obtained child id %s for source table %s and destination table %s", childWorkflowID, srcName, dstName), cloneLog) - taskQueue := shared.GetPeerFlowTaskQueueName(shared.PeerFlowTaskQueue) + taskQueue := peerdbenv.PeerFlowTaskQueueName(shared.PeerFlowTaskQueue) childCtx := workflow.WithChildOptions(ctx, workflow.ChildWorkflowOptions{ WorkflowID: childWorkflowID, WorkflowTaskTimeout: 5 * time.Minute, diff --git a/nexus/analyzer/src/lib.rs b/nexus/analyzer/src/lib.rs index da8cab94d4..0c16269cd4 100644 --- a/nexus/analyzer/src/lib.rs +++ b/nexus/analyzer/src/lib.rs @@ -10,8 +10,9 @@ use anyhow::Context; use pt::{ flow_model::{FlowJob, FlowJobTableMapping, QRepFlowJob}, peerdb_peers::{ - peer::Config, BigqueryConfig, ClickhouseConfig, DbType, EventHubConfig, KafkaConfig, - MongoConfig, Peer, PostgresConfig, S3Config, SnowflakeConfig, SqlServerConfig, + peer::Config, BigqueryConfig, ClickhouseConfig, DbType, EventHubConfig, GcpServiceAccount, + KafkaConfig, MongoConfig, Peer, PostgresConfig, PubSubConfig, S3Config, SnowflakeConfig, + SqlServerConfig, }, }; use qrep::process_options; @@ -248,12 +249,11 @@ impl<'a> StatementAnalyzer for PeerDDLAnalyzer<'a> { Some(sqlparser::ast::Value::Number(n, _)) => Some(n.parse::()?), _ => None, }; - let snapshot_staging_path = match raw_options - .remove("snapshot_staging_path") - { - Some(sqlparser::ast::Value::SingleQuotedString(s)) => s.clone(), - _ => String::new(), - }; + let snapshot_staging_path = + match raw_options.remove("snapshot_staging_path") { + Some(sqlparser::ast::Value::SingleQuotedString(s)) => s.clone(), + _ => String::new(), + }; let snapshot_max_parallel_workers: Option = match raw_options .remove("snapshot_max_parallel_workers") @@ -827,11 +827,7 @@ fn parse_db_options( .split(',') .map(String::from) .collect::>(), - username: opts - .get("user") - .cloned() - .unwrap_or_default() - .to_string(), + username: opts.get("user").cloned().unwrap_or_default().to_string(), password: opts .get("password") .cloned() @@ -854,5 +850,62 @@ fn parse_db_options( }; Config::KafkaConfig(kafka_config) } + DbType::Pubsub => { + let pem_str = opts + .get("private_key") + .ok_or_else(|| anyhow::anyhow!("missing private_key option for bigquery"))?; + pem::parse(pem_str.as_bytes()) + .map_err(|err| anyhow::anyhow!("unable to parse private_key: {:?}", err))?; + let ps_config = PubSubConfig { + service_account: Some(GcpServiceAccount { + auth_type: opts + .get("type") + .ok_or_else(|| anyhow::anyhow!("missing type option for bigquery"))? + .to_string(), + project_id: opts + .get("project_id") + .ok_or_else(|| anyhow::anyhow!("missing project_id in peer options"))? + .to_string(), + private_key_id: opts + .get("private_key_id") + .ok_or_else(|| { + anyhow::anyhow!("missing private_key_id option for bigquery") + })? + .to_string(), + private_key: pem_str.to_string(), + client_email: opts + .get("client_email") + .ok_or_else(|| anyhow::anyhow!("missing client_email option for bigquery"))? + .to_string(), + client_id: opts + .get("client_id") + .ok_or_else(|| anyhow::anyhow!("missing client_id option for bigquery"))? + .to_string(), + auth_uri: opts + .get("auth_uri") + .ok_or_else(|| anyhow::anyhow!("missing auth_uri option for bigquery"))? + .to_string(), + token_uri: opts + .get("token_uri") + .ok_or_else(|| anyhow::anyhow!("missing token_uri option for bigquery"))? + .to_string(), + auth_provider_x509_cert_url: opts + .get("auth_provider_x509_cert_url") + .ok_or_else(|| { + anyhow::anyhow!( + "missing auth_provider_x509_cert_url option for bigquery" + ) + })? + .to_string(), + client_x509_cert_url: opts + .get("client_x509_cert_url") + .ok_or_else(|| { + anyhow::anyhow!("missing client_x509_cert_url option for bigquery") + })? + .to_string(), + }), + }; + Config::PubsubConfig(ps_config) + } })) } diff --git a/nexus/catalog/src/lib.rs b/nexus/catalog/src/lib.rs index 0d8b7ed6a6..79a17a98b1 100644 --- a/nexus/catalog/src/lib.rs +++ b/nexus/catalog/src/lib.rs @@ -101,6 +101,7 @@ impl Catalog { } Config::ClickhouseConfig(clickhouse_config) => clickhouse_config.encode_to_vec(), Config::KafkaConfig(kafka_config) => kafka_config.encode_to_vec(), + Config::PubsubConfig(pubsub_config) => pubsub_config.encode_to_vec(), } }; @@ -312,6 +313,11 @@ impl Catalog { pt::peerdb_peers::KafkaConfig::decode(options).with_context(err)?; Config::KafkaConfig(kafka_config) } + DbType::Pubsub => { + let pubsub_config = + pt::peerdb_peers::PubSubConfig::decode(options).with_context(err)?; + Config::PubsubConfig(pubsub_config) + } }) } else { None diff --git a/protos/peers.proto b/protos/peers.proto index 12fc88bfb3..4fa1978568 100644 --- a/protos/peers.proto +++ b/protos/peers.proto @@ -25,6 +25,19 @@ message SnowflakeConfig { optional string metadata_schema = 11; } +message GcpServiceAccount { + string auth_type = 1; + string project_id = 2; + string private_key_id = 3; + string private_key = 4; + string client_email = 5; + string client_id = 6; + string auth_uri = 7; + string token_uri = 8; + string auth_provider_x509_cert_url = 9; + string client_x509_cert_url = 10; +} + message BigqueryConfig { string auth_type = 1; string project_id = 2; @@ -39,6 +52,10 @@ message BigqueryConfig { string dataset_id = 11; } +message PubSubConfig { + GcpServiceAccount service_account = 1; +} + message MongoConfig { string username = 1; string password = 2; @@ -128,6 +145,7 @@ enum DBType { EVENTHUB_GROUP = 7; CLICKHOUSE = 8; KAFKA = 9; + PUBSUB = 10; } message Peer { @@ -144,5 +162,6 @@ message Peer { EventHubGroupConfig eventhub_group_config = 10; ClickhouseConfig clickhouse_config = 11; KafkaConfig kafka_config = 12; + PubSubConfig pubsub_config = 13; } } diff --git a/ui/app/api/peers/getTruePeer.ts b/ui/app/api/peers/getTruePeer.ts index 93da206854..4c29ffd280 100644 --- a/ui/app/api/peers/getTruePeer.ts +++ b/ui/app/api/peers/getTruePeer.ts @@ -7,6 +7,7 @@ import { KafkaConfig, Peer, PostgresConfig, + PubSubConfig, S3Config, SnowflakeConfig, SqlServerConfig, @@ -25,6 +26,7 @@ export const getTruePeer = (peer: CatalogPeer) => { | EventHubGroupConfig | KafkaConfig | PostgresConfig + | PubSubConfig | S3Config | SnowflakeConfig | SqlServerConfig; @@ -65,6 +67,10 @@ export const getTruePeer = (peer: CatalogPeer) => { config = KafkaConfig.decode(options); newPeer.kafkaConfig = config; break; + case 10: + config = PubSubConfig.decode(options); + newPeer.pubsubConfig = config; + break; default: return newPeer; } diff --git a/ui/app/api/peers/info/[peerName]/route.ts b/ui/app/api/peers/info/[peerName]/route.ts index 61dc033efb..1a1cb6cde3 100644 --- a/ui/app/api/peers/info/[peerName]/route.ts +++ b/ui/app/api/peers/info/[peerName]/route.ts @@ -22,6 +22,7 @@ export async function GET( const ehConfig = peerConfig.eventhubConfig; const chConfig = peerConfig.clickhouseConfig; const kaConfig = peerConfig.kafkaConfig; + const psConfig = peerConfig.pubsubConfig; if (pgConfig) { pgConfig.password = '********'; pgConfig.transactionSnapshot = '********'; @@ -47,6 +48,10 @@ export async function GET( if (kaConfig) { kaConfig.password = '********'; } + if (psConfig?.serviceAccount) { + psConfig.serviceAccount.privateKey = '********'; + psConfig.serviceAccount.privateKeyId = '********'; + } return NextResponse.json(peerConfig); } diff --git a/ui/app/api/peers/route.ts b/ui/app/api/peers/route.ts index 0691212af8..398d834e74 100644 --- a/ui/app/api/peers/route.ts +++ b/ui/app/api/peers/route.ts @@ -13,6 +13,7 @@ import { KafkaConfig, Peer, PostgresConfig, + PubSubConfig, S3Config, SnowflakeConfig, } from '@/grpc_generated/peers'; @@ -70,6 +71,12 @@ const constructPeer = ( type: DBType.KAFKA, kafkaConfig: config as KafkaConfig, }; + case 'PUBSUB': + return { + name, + type: DBType.PUBSUB, + pubsubConfig: config as PubSubConfig, + }; default: return; } diff --git a/ui/app/dto/PeersDTO.ts b/ui/app/dto/PeersDTO.ts index 3e7f5c0b41..3035ea86cb 100644 --- a/ui/app/dto/PeersDTO.ts +++ b/ui/app/dto/PeersDTO.ts @@ -3,6 +3,7 @@ import { ClickhouseConfig, KafkaConfig, PostgresConfig, + PubSubConfig, S3Config, SnowflakeConfig, } from '@/grpc_generated/peers'; @@ -45,7 +46,8 @@ export type PeerConfig = | BigqueryConfig | ClickhouseConfig | S3Config - | KafkaConfig; + | KafkaConfig + | PubSubConfig; export type CatalogPeer = { id: number; name: string; diff --git a/ui/app/peers/create/[peerType]/handlers.ts b/ui/app/peers/create/[peerType]/handlers.ts index 42f84a492a..bc0f071491 100644 --- a/ui/app/peers/create/[peerType]/handlers.ts +++ b/ui/app/peers/create/[peerType]/handlers.ts @@ -11,6 +11,7 @@ import { kaSchema, peerNameSchema, pgSchema, + psSchema, s3Schema, sfSchema, } from './schema'; @@ -62,6 +63,10 @@ const validateFields = ( const kaConfig = kaSchema.safeParse(config); if (!kaConfig.success) validationErr = kaConfig.error.issues[0].message; break; + case 'PUBSUB': + const psConfig = psSchema.safeParse(config); + if (!psConfig.success) validationErr = psConfig.error.issues[0].message; + break; default: validationErr = 'Unsupported peer type ' + type; } diff --git a/ui/app/peers/create/[peerType]/helpers/common.ts b/ui/app/peers/create/[peerType]/helpers/common.ts index e418fd9266..2dac029c00 100644 --- a/ui/app/peers/create/[peerType]/helpers/common.ts +++ b/ui/app/peers/create/[peerType]/helpers/common.ts @@ -1,7 +1,9 @@ import { PeerConfig, PeerSetter } from '@/app/dto/PeersDTO'; import { blankBigquerySetting } from './bq'; import { blankClickhouseSetting } from './ch'; +import { blankKafkaSetting } from './ka'; import { blankPostgresSetting } from './pg'; +import { blankPubSubSetting } from './ps'; import { blankS3Setting } from './s3'; import { blankSnowflakeSetting } from './sf'; @@ -27,6 +29,10 @@ export const getBlankSetting = (dbType: string): PeerConfig => { return blankBigquerySetting; case 'CLICKHOUSE': return blankClickhouseSetting; + case 'PUBSUB': + return blankPubSubSetting; + case 'KAFKA': + return blankKafkaSetting; case 'S3': return blankS3Setting; default: diff --git a/ui/app/peers/create/[peerType]/helpers/ka.ts b/ui/app/peers/create/[peerType]/helpers/ka.ts index 5091d29e7e..193ebaba4d 100644 --- a/ui/app/peers/create/[peerType]/helpers/ka.ts +++ b/ui/app/peers/create/[peerType]/helpers/ka.ts @@ -63,7 +63,7 @@ export const kaSetting: PeerSetting[] = [ }, ]; -export const blankKaSetting: KafkaConfig = { +export const blankKafkaSetting: KafkaConfig = { servers: [], username: '', password: '', diff --git a/ui/app/peers/create/[peerType]/helpers/ps.ts b/ui/app/peers/create/[peerType]/helpers/ps.ts new file mode 100644 index 0000000000..88399d0942 --- /dev/null +++ b/ui/app/peers/create/[peerType]/helpers/ps.ts @@ -0,0 +1,16 @@ +import { PubSubConfig } from '@/grpc_generated/peers'; + +export const blankPubSubSetting: PubSubConfig = { + serviceAccount: { + authType: 'service_account', + projectId: '', + privateKeyId: '', + privateKey: '', + clientEmail: '', + clientId: '', + authUri: '', + tokenUri: '', + authProviderX509CertUrl: '', + clientX509CertUrl: '', + }, +}; diff --git a/ui/app/peers/create/[peerType]/page.tsx b/ui/app/peers/create/[peerType]/page.tsx index bbb25b31ad..ffb4495db4 100644 --- a/ui/app/peers/create/[peerType]/page.tsx +++ b/ui/app/peers/create/[peerType]/page.tsx @@ -5,6 +5,7 @@ import BigqueryForm from '@/components/PeerForms/BigqueryConfig'; import ClickhouseForm from '@/components/PeerForms/ClickhouseConfig'; import KafkaForm from '@/components/PeerForms/KafkaConfig'; import PostgresForm from '@/components/PeerForms/PostgresForm'; +import PubSubForm from '@/components/PeerForms/PubSubConfig'; import S3Form from '@/components/PeerForms/S3Form'; import SnowflakeForm from '@/components/PeerForms/SnowflakeForm'; @@ -84,6 +85,8 @@ export default function CreateConfig({ return ; case 'KAFKA': return ; + case 'PUBSUB': + return ; default: return <>; } diff --git a/ui/app/peers/create/[peerType]/schema.ts b/ui/app/peers/create/[peerType]/schema.ts index 117b8738fe..687c5e2174 100644 --- a/ui/app/peers/create/[peerType]/schema.ts +++ b/ui/app/peers/create/[peerType]/schema.ts @@ -351,3 +351,73 @@ export const s3Schema = z.object({ }) .optional(), }); + +export const psSchema = z.object({ + serviceAccount: z.object({ + authType: z + .string({ + required_error: 'Auth Type is required', + invalid_type_error: 'Auth Type must be a string', + }) + .min(1, { message: 'Auth Type must be non-empty' }) + .max(255, 'Auth Type must be less than 255 characters'), + projectId: z + .string({ + required_error: 'Project ID is required', + invalid_type_error: 'Project ID must be a string', + }) + .min(1, { message: 'Project ID must be non-empty' }), + privateKeyId: z + .string({ + required_error: 'Private Key ID is required', + invalid_type_error: 'Private Key ID must be a string', + }) + .min(1, { message: 'Private Key must be non-empty' }), + privateKey: z + .string({ + required_error: 'Private Key is required', + invalid_type_error: 'Private Key must be a string', + }) + .min(1, { message: 'Private Key must be non-empty' }), + clientId: z + .string({ + required_error: 'Client ID is required', + invalid_type_error: 'Client ID must be a string', + }) + .min(1, { message: 'Client ID must be non-empty' }), + clientEmail: z + .string({ + required_error: 'Client Email is required', + invalid_type_error: 'Client Email must be a string', + }) + .min(1, { message: 'Client Email must be non-empty' }), + authUri: z + .string({ + required_error: 'Auth URI is required', + invalid_type_error: 'Auth URI must be a string', + }) + .url({ message: 'Invalid auth URI' }) + .min(1, { message: 'Auth URI must be non-empty' }), + tokenUri: z + .string({ + required_error: 'Token URI is required', + invalid_type_error: 'Token URI must be a string', + }) + .url({ message: 'Invalid token URI' }) + .min(1, { message: 'Token URI must be non-empty' }), + authProviderX509CertUrl: z + .string({ + invalid_type_error: 'Auth Cert URL must be a string', + required_error: 'Auth Cert URL is required', + }) + .url({ message: 'Invalid auth cert URL' }) + .min(1, { message: 'Auth Cert URL must be non-empty' }), + clientX509CertUrl: z + .string({ + invalid_type_error: 'Client Cert URL must be a string', + required_error: 'Client Cert URL is required', + }) + .url({ message: 'Invalid client cert URL' }) + .min(1, { message: 'Client Cert URL must be non-empty' }), + }), +}); diff --git a/ui/app/peers/peersTable.tsx b/ui/app/peers/peersTable.tsx index a592d232f3..6a3c77d149 100644 --- a/ui/app/peers/peersTable.tsx +++ b/ui/app/peers/peersTable.tsx @@ -56,8 +56,9 @@ function PeersTable({ peers }: { peers: Peer[] }) { const availableTypes: { value: DBType | undefined; label: string }[] = Array.from( new Map( // Map filters out duplicates - peers.flatMap((peer) => [ - [peer.type, { value: peer.type, label: DBTypeToGoodText(peer.type) }], + peers.map((peer) => [ + peer.type, + { value: peer.type, label: DBTypeToGoodText(peer.type) }, ]) ).values() ); diff --git a/ui/components/PeerComponent.tsx b/ui/components/PeerComponent.tsx index 8505655c72..78c8db0d2d 100644 --- a/ui/components/PeerComponent.tsx +++ b/ui/components/PeerComponent.tsx @@ -35,6 +35,9 @@ export const DBTypeToImageMapping = (peerType: DBType | string) => { case DBType.KAFKA: case 'KAFKA': return '/svgs/kafka.svg'; + case DBType.PUBSUB: + case 'PUBSUB': + return '/svgs/pubsub.svg'; default: return '/svgs/pg.svg'; } diff --git a/ui/components/PeerForms/BigqueryConfig.tsx b/ui/components/PeerForms/BigqueryConfig.tsx index 9b423de320..eebf7f60dd 100644 --- a/ui/components/PeerForms/BigqueryConfig.tsx +++ b/ui/components/PeerForms/BigqueryConfig.tsx @@ -29,7 +29,7 @@ export default function BigqueryForm(props: BQProps) { return; } const bqConfig: BigqueryConfig = { - authType: bqJson.type, + authType: bqJson.type ?? bqJson.auth_type, projectId: bqJson.project_id, privateKeyId: bqJson.private_key_id, privateKey: bqJson.private_key, diff --git a/ui/components/PeerForms/PubSubConfig.tsx b/ui/components/PeerForms/PubSubConfig.tsx new file mode 100644 index 0000000000..089f9eb0f7 --- /dev/null +++ b/ui/components/PeerForms/PubSubConfig.tsx @@ -0,0 +1,92 @@ +'use client'; +import { PeerSetter } from '@/app/dto/PeersDTO'; +import { blankPubSubSetting } from '@/app/peers/create/[peerType]/helpers/ps'; +import { PubSubConfig } from '@/grpc_generated/peers'; +import { Label } from '@/lib/Label'; +import { RowWithTextField } from '@/lib/Layout'; +import { TextField } from '@/lib/TextField'; +import { Tooltip } from '@/lib/Tooltip'; +import Link from 'next/link'; +import { useState } from 'react'; + +interface PSProps { + setter: PeerSetter; +} +export default function PubSubForm(props: PSProps) { + const [datasetID, setDatasetID] = useState(''); + const handleJSONFile = (file: File) => { + if (file) { + const reader = new FileReader(); + reader.readAsText(file); + reader.onload = () => { + // Read the file as JSON + let psJson; + try { + psJson = JSON.parse(reader.result as string); + } catch (err) { + props.setter(blankPubSubSetting); + return; + } + const psConfig: PubSubConfig = { + serviceAccount: { + authType: psJson.type ?? psJson.auth_type, + projectId: psJson.project_id, + privateKeyId: psJson.private_key_id, + privateKey: psJson.private_key, + clientEmail: psJson.client_email, + clientId: psJson.client_id, + authUri: psJson.auth_uri, + tokenUri: psJson.token_uri, + authProviderX509CertUrl: psJson.auth_provider_x509_cert_url, + clientX509CertUrl: psJson.client_x509_cert_url, + }, + }; + props.setter(psConfig); + }; + reader.onerror = (error) => { + console.log(error); + }; + } + }; + + return ( + <> + + + Creating a service account file + + + Service Account JSON + + + + + } + action={ + ) => + e.target.files && handleJSONFile(e.target.files[0]) + } + /> + } + /> + + ); +} diff --git a/ui/components/PeerTypeComponent.tsx b/ui/components/PeerTypeComponent.tsx index 2db4be9dd2..e1642cb001 100644 --- a/ui/components/PeerTypeComponent.tsx +++ b/ui/components/PeerTypeComponent.tsx @@ -26,6 +26,8 @@ export const DBTypeToGoodText = (ptype: DBType) => { return 'Clickhouse'; case DBType.KAFKA: return 'Kafka'; + case DBType.PUBSUB: + return 'PubSub'; case DBType.UNRECOGNIZED: return 'Unrecognised'; } diff --git a/ui/components/SelectSource.tsx b/ui/components/SelectSource.tsx index eca7c37e61..4459d3643c 100644 --- a/ui/components/SelectSource.tsx +++ b/ui/components/SelectSource.tsx @@ -35,7 +35,8 @@ export default function SelectSource({ value === 'BIGQUERY' || value === 'S3' || value === 'CLICKHOUSE' || - value === 'KAFKA') + value === 'KAFKA' || + value === 'PUBSUB') ) .map((value) => ({ label: value, value })); diff --git a/ui/public/svgs/pubsub.svg b/ui/public/svgs/pubsub.svg new file mode 100644 index 0000000000..c3686f6e7b --- /dev/null +++ b/ui/public/svgs/pubsub.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + Icon_24px_Pub-Sub_Color + + + + + + + + + + + + + + + \ No newline at end of file From 5ea25234b622520beb41af896ddc9b91929809c1 Mon Sep 17 00:00:00 2001 From: Kevin Biju <52661649+heavycrystal@users.noreply.github.com> Date: Mon, 25 Mar 2024 01:33:12 +0530 Subject: [PATCH 03/48] revert SET LOCAL in replconn hold (#1530) was a bug, `SET LOCAL` has no effect outside transactions, can cause replication connections to close --- flow/connectors/postgres/client.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/flow/connectors/postgres/client.go b/flow/connectors/postgres/client.go index 54df692986..012b78a998 100644 --- a/flow/connectors/postgres/client.go +++ b/flow/connectors/postgres/client.go @@ -370,12 +370,13 @@ func (c *PostgresConnector) createSlotAndPublication( c.logger.Warn(fmt.Sprintf("Creating replication slot '%s'", slot)) - _, err = conn.Exec(ctx, "SET LOCAL idle_in_transaction_session_timeout=0") + // THIS IS NOT IN A TX! + _, err = conn.Exec(ctx, "SET idle_in_transaction_session_timeout=0") if err != nil { return fmt.Errorf("[slot] error setting idle_in_transaction_session_timeout: %w", err) } - _, err = conn.Exec(ctx, "SET LOCAL lock_timeout=0") + _, err = conn.Exec(ctx, "SET lock_timeout=0") if err != nil { return fmt.Errorf("[slot] error setting lock_timeout: %w", err) } From 9c493b5fa238f43350cabfd2e8e4836b22117d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Mar 2024 12:40:31 +0000 Subject: [PATCH 04/48] Update buf.build plugins (#1529) --- buf.gen.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/buf.gen.yaml b/buf.gen.yaml index 3c209554be..b2c702c6e6 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -6,30 +6,30 @@ managed: except: - buf.build/googleapis/googleapis plugins: - - plugin: buf.build/protocolbuffers/go:v1.31.0 + - plugin: buf.build/protocolbuffers/go:v1.33.0 out: flow/generated/protos opt: paths=source_relative - plugin: buf.build/grpc/go:v1.3.0 out: flow/generated/protos opt: - paths=source_relative - - plugin: buf.build/community/neoeinstein-prost:v0.2.3 + - plugin: buf.build/community/neoeinstein-prost:v0.3.1 out: nexus/pt/src/gen opt: - compile_well_known_types - extern_path=.google.protobuf=::pbjson_types - - plugin: buf.build/community/neoeinstein-tonic:v0.3.0 + - plugin: buf.build/community/neoeinstein-tonic:v0.4.0 out: nexus/pt/src/gen - - plugin: buf.build/community/neoeinstein-prost-serde:v0.2.3 + - plugin: buf.build/community/neoeinstein-prost-serde:v0.3.0 out: nexus/pt/src/gen opt: - ignore_unknown_fields=true - - plugin: buf.build/community/stephenh-ts-proto:v1.156.8 + - plugin: buf.build/community/stephenh-ts-proto:v1.167.9 out: ui/grpc_generated opt: - esModuleInterop=true - outputServices=grpc-js - - plugin: buf.build/grpc-ecosystem/gateway:v2.18.0 + - plugin: buf.build/grpc-ecosystem/gateway:v2.19.1 out: flow/generated/protos opt: - paths=source_relative From 4272ff982404b4e79d9e2c54f3ef36ec0d67dfff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Mar 2024 12:58:28 +0000 Subject: [PATCH 05/48] rust 1.77, also update rust dependencies (#1523) Hold back on a few dependencies while waiting for other dependencies to also update: * base64 0.22 * reqwest 0.12 * rustls 0.23 * yup-oauth2 8.3.3 --- nexus/Cargo.lock | 166 +++++++++++++++++--------------- nexus/peer-bigquery/Cargo.toml | 2 +- stacks/peerdb-server.Dockerfile | 2 +- 3 files changed, 88 insertions(+), 82 deletions(-) diff --git a/nexus/Cargo.lock b/nexus/Cargo.lock index 366c0242c1..67b3076c38 100644 --- a/nexus/Cargo.lock +++ b/nexus/Cargo.lock @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "ar" @@ -164,13 +164,13 @@ dependencies = [ [[package]] name = "async-recursion" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "30c5ef0ede93efbf733c1a727f3b6b5a1060bbedd5600183e66f6e4be4af0ec5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -192,18 +192,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -302,9 +302,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bitvec" @@ -356,7 +356,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", "syn_derive", ] @@ -396,9 +396,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cargo-deb" @@ -512,9 +512,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.2" +version = "4.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" +checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813" dependencies = [ "clap_builder", "clap_derive", @@ -534,14 +534,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -752,7 +752,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -968,7 +968,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -1070,9 +1070,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" dependencies = [ "bytes", "fnv", @@ -1121,6 +1121,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -1347,9 +1353,9 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "9.2.0" +version = "9.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" +checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" dependencies = [ "base64", "js-sys", @@ -1658,7 +1664,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2580e33f2292d34be285c5bc3dba5259542b083cfad6037b6d70345f24dcb735" dependencies = [ - "heck", + "heck 0.4.1", "itertools 0.11.0", "prost", "prost-types", @@ -1950,7 +1956,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2100,7 +2106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2137,9 +2143,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -2161,7 +2167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", - "heck", + "heck 0.4.1", "itertools 0.11.0", "log", "multimap", @@ -2171,7 +2177,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.52", + "syn 2.0.53", "tempfile", "which", ] @@ -2186,7 +2192,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2335,7 +2341,7 @@ dependencies = [ "log", "regex", "serde", - "siphasher 1.0.0", + "siphasher 1.0.1", "thiserror", "time", "tokio", @@ -2355,7 +2361,7 @@ dependencies = [ "quote", "refinery-core", "regex", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2413,9 +2419,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.25" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "async-compression", "base64", @@ -2544,11 +2550,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -2604,9 +2610,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "868e20fada228fefaf6b652e00cc73623d54f8171e7352c18bb281571f2d92da" [[package]] name = "rustls-webpki" @@ -2759,7 +2765,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2878,9 +2884,9 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "siphasher" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ac45299ccbd390721be55b412d41931911f654fa99e2cb8bfb57184b2061fe" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" @@ -2893,9 +2899,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -2945,7 +2951,7 @@ source = "git+https://github.com/peerdb-io/sqlparser-rs.git#9fbfb423db7fc0949dea dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -2984,9 +2990,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" dependencies = [ "proc-macro2", "quote", @@ -3002,7 +3008,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -3013,20 +3019,20 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "system-configuration" -version = "0.6.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 2.4.2", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ "core-foundation-sys", "libc", @@ -3062,22 +3068,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -3176,7 +3182,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -3243,9 +3249,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -3268,14 +3274,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.10" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.6", + "toml_edit 0.22.9", ] [[package]] @@ -3300,9 +3306,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.6" +version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ "indexmap 2.2.5", "serde", @@ -3454,7 +3460,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] @@ -3592,9 +3598,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "getrandom", "serde", @@ -3682,7 +3688,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", "wasm-bindgen-shared", ] @@ -3716,7 +3722,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4056,7 +4062,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.53", ] [[package]] diff --git a/nexus/peer-bigquery/Cargo.toml b/nexus/peer-bigquery/Cargo.toml index 9bc6ac49a3..4e265221dd 100644 --- a/nexus/peer-bigquery/Cargo.toml +++ b/nexus/peer-bigquery/Cargo.toml @@ -25,4 +25,4 @@ tokio = { version = "1.0", features = ["full"] } gcp-bigquery-client = "0.18" uuid = { version = "1.0", features = ["serde", "v4"] } value = { path = "../value" } -yup-oauth2 = "8" +yup-oauth2 = "=8.3.2" diff --git a/stacks/peerdb-server.Dockerfile b/stacks/peerdb-server.Dockerfile index af3f573899..1dbfb77b37 100644 --- a/stacks/peerdb-server.Dockerfile +++ b/stacks/peerdb-server.Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM lukemathwalker/cargo-chef:latest-rust-1.76-slim-bookworm as chef +FROM lukemathwalker/cargo-chef:latest-rust-1.77-slim-bookworm as chef WORKDIR /root FROM chef as planner From 2b6c9adef967f1a3c37269be5a89cf082d9f1be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Mar 2024 13:19:38 +0000 Subject: [PATCH 06/48] pt: reexport prost (#1526) server wasn't using prost, catalog uses reexported prost --- nexus/Cargo.lock | 3 --- nexus/catalog/Cargo.toml | 1 - nexus/catalog/src/lib.rs | 2 +- nexus/flow-rs/Cargo.toml | 1 - nexus/flow-rs/src/grpc.rs | 1 + nexus/pt/src/lib.rs | 3 +++ nexus/server/Cargo.toml | 1 - 7 files changed, 5 insertions(+), 7 deletions(-) diff --git a/nexus/Cargo.lock b/nexus/Cargo.lock index 67b3076c38..1af28dab14 100644 --- a/nexus/Cargo.lock +++ b/nexus/Cargo.lock @@ -448,7 +448,6 @@ dependencies = [ "peer-postgres", "pgwire", "postgres-connection", - "prost", "pt", "refinery", "serde_json", @@ -886,7 +885,6 @@ dependencies = [ "catalog", "pt", "serde_json", - "tonic 0.11.0", "tonic-health", "tracing", ] @@ -1845,7 +1843,6 @@ dependencies = [ "peerdb-parser", "pgwire", "postgres", - "prost", "pt", "rand", "serde_json", diff --git a/nexus/catalog/Cargo.toml b/nexus/catalog/Cargo.toml index 0f9372b19c..da622a1cb4 100644 --- a/nexus/catalog/Cargo.toml +++ b/nexus/catalog/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" anyhow = "1" async-trait = "0.1" chrono.workspace = true -prost = "0.12" peer-cursor = { path = "../peer-cursor" } peer-postgres = { path = "../peer-postgres" } pgwire.workspace = true diff --git a/nexus/catalog/src/lib.rs b/nexus/catalog/src/lib.rs index 79a17a98b1..80e67aa507 100644 --- a/nexus/catalog/src/lib.rs +++ b/nexus/catalog/src/lib.rs @@ -5,11 +5,11 @@ use peer_cursor::{QueryExecutor, QueryOutput, Schema}; use peer_postgres::{self, ast}; use pgwire::error::PgWireResult; use postgres_connection::{connect_postgres, get_pg_connection_string}; -use prost::Message; use pt::{ flow_model::{FlowJob, QRepFlowJob}, peerdb_peers::PostgresConfig, peerdb_peers::{peer::Config, DbType, Peer}, + prost::Message, }; use serde_json::Value; use sqlparser::ast::Statement; diff --git a/nexus/flow-rs/Cargo.toml b/nexus/flow-rs/Cargo.toml index ff784b77d5..c46c0ee842 100644 --- a/nexus/flow-rs/Cargo.toml +++ b/nexus/flow-rs/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" serde_json = "1.0" anyhow = "1.0" tracing = "0.1" -tonic = "0.11" tonic-health = "0.11" pt = { path = "../pt" } catalog = { path = "../catalog" } diff --git a/nexus/flow-rs/src/grpc.rs b/nexus/flow-rs/src/grpc.rs index b7569dbe45..9c25337974 100644 --- a/nexus/flow-rs/src/grpc.rs +++ b/nexus/flow-rs/src/grpc.rs @@ -3,6 +3,7 @@ use pt::{ flow_model::{FlowJob, QRepFlowJob}, peerdb_flow::{QRepWriteMode, QRepWriteType}, peerdb_route, + tonic, }; use serde_json::Value; use tonic_health::pb::health_client; diff --git a/nexus/pt/src/lib.rs b/nexus/pt/src/lib.rs index 33da1e6382..48a558ec0c 100644 --- a/nexus/pt/src/lib.rs +++ b/nexus/pt/src/lib.rs @@ -14,6 +14,9 @@ pub mod peerdb_peers; #[path ="./gen/peerdb_route.rs"] pub mod peerdb_route; +pub use prost; +pub use tonic; + impl From for DbType { fn from(peer_type: PeerType) -> Self { match peer_type { diff --git a/nexus/server/Cargo.toml b/nexus/server/Cargo.toml index e9d484e975..8c87a2480d 100644 --- a/nexus/server/Cargo.toml +++ b/nexus/server/Cargo.toml @@ -48,7 +48,6 @@ peer-postgres = { path = "../peer-postgres" } peer-snowflake = { path = "../peer-snowflake" } peerdb-parser = { path = "../parser" } pgwire.workspace = true -prost = "0.12" pt = { path = "../pt" } sqlparser = { workspace = true, features = ["visitor"] } serde_json = "1.0" From 157ef0ff3b1d91ae67863ec48b31e745a50d62c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Mar 2024 14:52:38 +0000 Subject: [PATCH 07/48] Update go/js dependencies (#1532) Updates from a retracted dependency: https://github.com/prometheus/common/issues/605 & updates gluabit32 to 1.0.2 since I botched 1.0.0/1.0.1 somehow learning how to package go repos --- flow/go.mod | 64 +- flow/go.sum | 140 +-- flow/pua/peerdb.go | 2 +- ui/package-lock.json | 2559 ++++++++++++++++++++++++------------------ ui/package.json | 28 +- 5 files changed, 1556 insertions(+), 1237 deletions(-) diff --git a/flow/go.mod b/flow/go.mod index ad4d89786f..d97bd4fe74 100644 --- a/flow/go.mod +++ b/flow/go.mod @@ -10,22 +10,22 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs v1.0.4 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/eventhub/armeventhub v1.2.0 - github.com/ClickHouse/clickhouse-go/v2 v2.21.1 + github.com/ClickHouse/clickhouse-go/v2 v2.22.4 github.com/PeerDB-io/glua64 v1.0.1 - github.com/PeerDB-io/gluabit32 v1.0.0 + github.com/PeerDB-io/gluabit32 v1.0.2 github.com/PeerDB-io/gluaflatbuffers v1.0.1 - github.com/aws/aws-sdk-go-v2 v1.25.3 - github.com/aws/aws-sdk-go-v2/config v1.27.7 - github.com/aws/aws-sdk-go-v2/credentials v1.17.7 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.9 - github.com/aws/aws-sdk-go-v2/service/s3 v1.51.4 - github.com/aws/aws-sdk-go-v2/service/ses v1.22.2 - github.com/aws/aws-sdk-go-v2/service/sns v1.29.2 + github.com/aws/aws-sdk-go-v2 v1.26.0 + github.com/aws/aws-sdk-go-v2/config v1.27.9 + github.com/aws/aws-sdk-go-v2/credentials v1.17.9 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.13 + github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0 + github.com/aws/aws-sdk-go-v2/service/ses v1.22.3 + github.com/aws/aws-sdk-go-v2/service/sns v1.29.3 github.com/cockroachdb/pebble v1.1.0 github.com/google/uuid v1.6.0 github.com/grafana/pyroscope-go v1.1.1 github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 - github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa + github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 github.com/jackc/pglogrepl v0.0.0-20240307033717-828fbfe908e9 github.com/jackc/pgx/v5 v5.5.5 github.com/jmoiron/sqlx v1.3.5 @@ -41,17 +41,17 @@ require ( github.com/stretchr/testify v1.9.0 github.com/twmb/franz-go v1.16.1 github.com/twmb/franz-go/plugin/kslog v1.0.0 - github.com/twpayne/go-geos v0.17.0 + github.com/twpayne/go-geos v0.17.1 github.com/urfave/cli/v3 v3.0.0-alpha9 github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a github.com/yuin/gopher-lua v1.1.1 - go.temporal.io/api v1.29.1 + go.temporal.io/api v1.30.1 go.temporal.io/sdk v1.26.0 go.uber.org/automaxprocs v1.5.3 golang.org/x/crypto v0.21.0 golang.org/x/sync v0.6.0 - google.golang.org/api v0.169.0 - google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7 + google.golang.org/api v0.171.0 + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 google.golang.org/grpc v1.62.1 google.golang.org/protobuf v1.33.0 ) @@ -63,11 +63,11 @@ require ( github.com/DataDog/zstd v1.5.5 // indirect github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect github.com/apache/arrow/go/v14 v14.0.2 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.3 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.20.2 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.28.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cockroachdb/errors v1.11.1 // indirect @@ -93,7 +93,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.19.0 // indirect github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.50.0 // indirect + github.com/prometheus/common v0.51.1 // indirect github.com/prometheus/procfs v0.13.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/segmentio/asm v1.2.0 // indirect @@ -108,9 +108,9 @@ require ( ) require ( - cloud.google.com/go/compute v1.25.0 // indirect + cloud.google.com/go/compute v1.25.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/iam v1.1.7 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.1 // indirect @@ -118,13 +118,13 @@ require ( github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect github.com/andybalholm/brotli v1.1.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.4 // indirect github.com/aws/smithy-go v1.20.1 github.com/davecgh/go-spew v1.1.1 // indirect github.com/djherbis/buffer v1.2.0 @@ -143,7 +143,7 @@ require ( github.com/google/flatbuffers v24.3.7+incompatible // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.3 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.7 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/jackc/pgio v1.0.0 // indirect @@ -159,10 +159,10 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/robfig/cron v1.2.0 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect + github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 + golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 golang.org/x/mod v0.16.0 // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect @@ -172,7 +172,7 @@ require ( golang.org/x/tools v0.19.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 // indirect + google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/flow/go.sum b/flow/go.sum index 98ed8f42cc..3553892eb1 100644 --- a/flow/go.sum +++ b/flow/go.sum @@ -3,16 +3,18 @@ cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.59.1 h1:CpT+/njKuKT3CEmswm6IbhNu9u35zt5dO4yPDLW+nG4= cloud.google.com/go/bigquery v1.59.1/go.mod h1:VP1UJYgevyTwsV7desjzNzDND5p6hZB+Z8gZJN1GQUc= -cloud.google.com/go/compute v1.25.0 h1:H1/4SqSUhjPFE7L5ddzHOfY2bCAvjwNRZPNl6Ni5oYU= -cloud.google.com/go/compute v1.25.0/go.mod h1:GR7F0ZPZH8EhChlMo9FkLd7eUTwEymjqQagxzilIxIE= +cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/datacatalog v1.19.3 h1:A0vKYCQdxQuV4Pi0LL9p39Vwvg4jH5yYveMv50gU5Tw= -cloud.google.com/go/datacatalog v1.19.3/go.mod h1:ra8V3UAsciBpJKQ+z9Whkxzxv7jmQg1hfODr3N3YPJ4= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/longrunning v0.5.5 h1:GOE6pZFdSrTb4KAiKnXsJBtlE6mEyaW44oKyMILWnOg= -cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s= +cloud.google.com/go/datacatalog v1.20.0 h1:BGDsEjqpAo0Ka+b9yDLXnE5k+jU3lXGMh//NsEeDMIg= +cloud.google.com/go/datacatalog v1.20.0/go.mod h1:fSHaKjIroFpmRrYlwz9XBB2gJBpXufpnxyAKaT4w6L0= +cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= +cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= +cloud.google.com/go/kms v1.15.8 h1:szIeDCowID8th2i8XE4uRev5PMxQFqW+JjwYxL9h6xs= +cloud.google.com/go/kms v1.15.8/go.mod h1:WoUHcDjD9pluCg7pNds131awnH429QGvRM3N/4MyoVs= +cloud.google.com/go/longrunning v0.5.6 h1:xAe8+0YaWoCKr9t1+aWe+OeQgN/iJK1fEgZSXmjuEaE= +cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= cloud.google.com/go/pubsub v1.37.0 h1:0uEEfaB1VIJzabPpwpZf44zWAKAme3zwKKxHk7vJQxQ= cloud.google.com/go/pubsub v1.37.0/go.mod h1:YQOQr1uiUM092EXwKs56OPT650nwnawc+8/IjoUeGzQ= cloud.google.com/go/storage v1.39.1 h1:MvraqHKhogCOTXTlct/9C3K3+Uy2jBmFYb3/Sp6dVtY= @@ -50,16 +52,16 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4= github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg= -github.com/ClickHouse/clickhouse-go/v2 v2.21.1 h1:x8wZEMOHDh4K8kLQBtGMeIIguejiaj8/bUiF2VzG6n4= -github.com/ClickHouse/clickhouse-go/v2 v2.21.1/go.mod h1:hTWNkV9mkQwiQ/df0rbN17VXF05UTResY4krnjbzVZA= +github.com/ClickHouse/clickhouse-go/v2 v2.22.4 h1:3cUjBGM992wUI40BKHLeCX60wT9Kzpm6b6r/4zUgxo4= +github.com/ClickHouse/clickhouse-go/v2 v2.22.4/go.mod h1:tBhdF3f3RdP7sS59+oBAtTyhWpy0024ZxDMhgxra0QE= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/PeerDB-io/glua64 v1.0.1 h1:biXLlFF/L5pnJCwDon7hkWkuQPozC8NjKS3J7Wzi69I= github.com/PeerDB-io/glua64 v1.0.1/go.mod h1:UHmAhniv61bJPMhQvxkpC7jXbn353dSbQviu83bgQVg= -github.com/PeerDB-io/gluabit32 v1.0.0 h1:jn88j22LqiqDoS47LUnvk29hsFQE6yW0imSsHHiYsV8= -github.com/PeerDB-io/gluabit32 v1.0.0/go.mod h1:tsHStN1XG5uGVWEA8d/RameB7el3PE3sVkvk8e3+FJg= +github.com/PeerDB-io/gluabit32 v1.0.2 h1:AGI1Z7dwDVotakpuOOuyTX4/QGi5HUYsipL/VfodmO4= +github.com/PeerDB-io/gluabit32 v1.0.2/go.mod h1:tsHStN1XG5uGVWEA8d/RameB7el3PE3sVkvk8e3+FJg= github.com/PeerDB-io/gluaflatbuffers v1.0.1 h1:Oxlv0VlMYoQ05Q5n/k4hXAsvtDnuVNC99JBUf927br0= github.com/PeerDB-io/gluaflatbuffers v1.0.1/go.mod h1:unZOM4Mm2Sn+aAFuVjoJDZ2Dji7jlDWrt4Hvq79as2g= github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= @@ -70,46 +72,46 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1 github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/apache/arrow/go/v14 v14.0.2 h1:N8OkaJEOfI3mEZt07BIkvo4sC6XDbL+48MBPWO5IONw= github.com/apache/arrow/go/v14 v14.0.2/go.mod h1:u3fgh3EdgN/YQ8cVQRguVW3R+seMybFg8QBQ5LU+eBY= -github.com/aws/aws-sdk-go-v2 v1.25.3 h1:xYiLpZTQs1mzvz5PaI6uR0Wh57ippuEthxS4iK5v0n0= -github.com/aws/aws-sdk-go-v2 v1.25.3/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I= +github.com/aws/aws-sdk-go-v2 v1.26.0 h1:/Ce4OCiM3EkpW7Y+xUnfAFpchU78K7/Ug01sZni9PgA= +github.com/aws/aws-sdk-go-v2 v1.26.0/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo= -github.com/aws/aws-sdk-go-v2/config v1.27.7 h1:JSfb5nOQF01iOgxFI5OIKWwDiEXWTyTgg1Mm1mHi0A4= -github.com/aws/aws-sdk-go-v2/config v1.27.7/go.mod h1:PH0/cNpoMO+B04qET699o5W92Ca79fVtbUnvMIZro4I= -github.com/aws/aws-sdk-go-v2/credentials v1.17.7 h1:WJd+ubWKoBeRh7A5iNMnxEOs982SyVKOJD+K8HIezu4= -github.com/aws/aws-sdk-go-v2/credentials v1.17.7/go.mod h1:UQi7LMR0Vhvs+44w5ec8Q+VS+cd10cjwgHwiVkE0YGU= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.3 h1:p+y7FvkK2dxS+FEwRIDHDe//ZX+jDhP8HHE50ppj4iI= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.3/go.mod h1:/fYB+FZbDlwlAiynK9KDXlzZl3ANI9JkD0Uhz5FjNT4= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.9 h1:vXY/Hq1XdxHBIYgBUmug/AbMyIe1AKulPYS2/VE1X70= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.9/go.mod h1:GyJJTZoHVuENM4TeJEl5Ffs4W9m19u+4wKJcDi/GZ4A= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3 h1:ifbIbHZyGl1alsAhPIYsHOg5MuApgqOvVeI8wIugXfs= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3/go.mod h1:oQZXg3c6SNeY6OZrDY+xHcF4VGIEoNotX2B4PrDeoJI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3 h1:Qvodo9gHG9F3E8SfYOspPeBt0bjSbsevK8WhRAUHcoY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3/go.mod h1:vCKrdLXtybdf/uQd/YfVR2r5pcbNuEYKzMQpcxmeSJw= +github.com/aws/aws-sdk-go-v2/config v1.27.9 h1:gRx/NwpNEFSk+yQlgmk1bmxxvQ5TyJ76CWXs9XScTqg= +github.com/aws/aws-sdk-go-v2/config v1.27.9/go.mod h1:dK1FQfpwpql83kbD873E9vz4FyAxuJtR22wzoXn3qq0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.9 h1:N8s0/7yW+h8qR8WaRlPQeJ6czVMNQVNtNdUqf6cItao= +github.com/aws/aws-sdk-go-v2/credentials v1.17.9/go.mod h1:446YhIdmSV0Jf/SLafGZalQo+xr2iw7/fzXGDPTU1yQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0 h1:af5YzcLf80tv4Em4jWVD75lpnOHSBkPUZxZfGkrI3HI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.0/go.mod h1:nQ3how7DMnFMWiU1SpECohgC82fpn4cKZ875NDMmwtA= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.13 h1:F+PUZee9mlfpEJVZdgyewRumKekS9O3fftj8fEMt0rQ= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.13/go.mod h1:Rl7i2dEWGHGsBIJCpUxlRt7VwK/HyXxICxdvIRssQHE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 h1:0ScVK/4qZ8CIW0k8jOeFVsyS/sAiXpYxRBLolMkuLQM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4/go.mod h1:84KyjNZdHC6QZW08nfHI6yZgPd+qRgaWcYsyLUo3QY8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 h1:sHmMWWX5E7guWEFQ9SVo6A3S4xpPrWnd77a6y4WM6PU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4/go.mod h1:WjpDrhWisWOIoS9n3nk67A3Ll1vfULJ9Kq6h29HTD48= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.3 h1:mDnFOE2sVkyphMWtTH+stv0eW3k0OTx94K63xpxHty4= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.3/go.mod h1:V8MuRVcCRt5h1S+Fwu8KbC7l/gBGo3yBAyUbJM2IJOk= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.4 h1:SIkD6T4zGQ+1YIit22wi37CGNkrE7mXV1vNA5VpI3TI= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.4/go.mod h1:XfeqbsG0HNedNs0GT+ju4Bs+pFAwsrlzcRdMvdNVf5s= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.5 h1:mbWNpfRUTT6bnacmvOTKXZjR/HycibdWzNpfbrbLDIs= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.5/go.mod h1:FCOPWGjsshkkICJIn9hq9xr6dLKtyaWpuUojiN3W1/8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.5 h1:K/NXvIftOlX+oGgWGIa3jDyYLDNsdVhsjHmsBH2GLAQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.5/go.mod h1:cl9HGLV66EnCmMNzq4sYOti+/xo8w34CsgzVtm2GgsY= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.3 h1:4t+QEX7BsXz98W8W1lNvMAG+NX8qHz2CjLBxQKku40g= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.3/go.mod h1:oFcjjUq5Hm09N9rpxTdeMeLeQcxS7mIkBkL8qUKng+A= -github.com/aws/aws-sdk-go-v2/service/s3 v1.51.4 h1:lW5xUzOPGAMY7HPuNF4FdyBwRc3UJ/e8KsapbesVeNU= -github.com/aws/aws-sdk-go-v2/service/s3 v1.51.4/go.mod h1:MGTaf3x/+z7ZGugCGvepnx2DS6+caCYYqKhzVoLNYPk= -github.com/aws/aws-sdk-go-v2/service/ses v1.22.2 h1:cW5JtW23Lio3KDJ4l3jqRiOcCPKxJg7ooRA1SpIiuMo= -github.com/aws/aws-sdk-go-v2/service/ses v1.22.2/go.mod h1:MLj/NROJoperecxBME2zMN/O8Zrm0wv+6ah1Uqwpa1E= -github.com/aws/aws-sdk-go-v2/service/sns v1.29.2 h1:kHm1SYs/NkxZpKINc4zOXOLJHVMzKtU4d7FlAMtDm50= -github.com/aws/aws-sdk-go-v2/service/sns v1.29.2/go.mod h1:ZIs7/BaYel9NODoYa8PW39o15SFAXDEb4DxOG2It15U= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.2 h1:XOPfar83RIRPEzfihnp+U6udOveKZJvPQ76SKWrLRHc= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.2/go.mod h1:Vv9Xyk1KMHXrR3vNQe8W5LMFdTjSeWk0gBZBzvf3Qa0= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.2 h1:pi0Skl6mNl2w8qWZXcdOyg197Zsf4G97U7Sso9JXGZE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.2/go.mod h1:JYzLoEVeLXk+L4tn1+rrkfhkxl6mLDEVaDSvGq9og90= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.4 h1:Ppup1nVNAOWbBOrcoOxaxPeEnSFB2RnnQdguhXpmeQk= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.4/go.mod h1:+K1rNPVyGxkRuv9NNiaZ4YhBFuyw2MMA9SlIJ1Zlpz8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.6 h1:NkHCgg0Ck86c5PTOzBZ0JRccI51suJDg5lgFtxBu1ek= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.6/go.mod h1:mjTpxjC8v4SeINTngrnKFgm2QUi+Jm+etTbCxh8W4uU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6 h1:b+E7zIUHMmcB4Dckjpkapoy47W6C9QBv/zoUP+Hn8Kc= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.6/go.mod h1:S2fNV0rxrP78NhPbCZeQgY8H9jdDMeGtwcfZIRxzBqU= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.4 h1:uDj2K47EM1reAYU9jVlQ1M5YENI1u6a/TxJpf6AeOLA= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.4/go.mod h1:XKCODf4RKHppc96c2EZBGV/oCUC7OClxAo2MEyg4pIk= +github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0 h1:r3o2YsgW9zRcIP3Q0WCmttFVhTuugeKIvT5z9xDspc0= +github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0/go.mod h1:w2E4f8PUfNtyjfL6Iu+mWI96FGttE03z3UdNcUEC4tA= +github.com/aws/aws-sdk-go-v2/service/ses v1.22.3 h1:65Xnv/Z/DZI96vw9CglXVEe8hxnCT1RgSLWysLZyQD8= +github.com/aws/aws-sdk-go-v2/service/ses v1.22.3/go.mod h1:XunveQX39pjU8KZYiklMfXwx9g4ygB8hC/MEQpROOYg= +github.com/aws/aws-sdk-go-v2/service/sns v1.29.3 h1:R2MIMza/lZex1wIawXmo6S+suwFv/JcxOFSJPpsSVBY= +github.com/aws/aws-sdk-go-v2/service/sns v1.29.3/go.mod h1:tr9l7BHYU/SvlJAL9CH56XZNcOBb/d24j3RrXkzzaTA= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.3 h1:mnbuWHOcM70/OFUlZZ5rcdfA8PflGXXiefU/O+1S3+8= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.3/go.mod h1:5HFu51Elk+4oRBZVxmHrSds5jFXmFj8C3w7DVF2gnrs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3 h1:uLq0BKatTmDzWa/Nu4WO0M1AaQDaPpwTKAeByEc6WFM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.3/go.mod h1:b+qdhjnxj8GSR6t5YfphOffeoQSQ1KmpoVVuBn+PWxs= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.5 h1:J/PpTf/hllOjx8Xu9DMflff3FajfLxqM5+tepvVXmxg= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.5/go.mod h1:0ih0Z83YDH/QeQ6Ori2yGE2XvWYv/Xm+cZc01LC6oK0= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -240,8 +242,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -257,8 +259,8 @@ github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8 github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6hFJUX53drDT4UsSW3DEhKn0ifuHw= -github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= +github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 h1:Dj0L5fhJ9F82ZJyVOmBx6msDp/kfd1t9GRfny/mfJA0= +github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pglogrepl v0.0.0-20240307033717-828fbfe908e9 h1:86CQbMauoZdLS0HDLcEHYo6rErjiCBjVvcxGsioIn7s= @@ -337,8 +339,8 @@ github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdU github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/common v0.50.0 h1:YSZE6aa9+luNa2da6/Tik0q0A5AbR+U003TItK57CPQ= -github.com/prometheus/common v0.50.0/go.mod h1:wHFBCEVWVmHMUpg7pYcOm2QUR/ocQdYSJVQJKnHc3xQ= +github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw= +github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= @@ -381,15 +383,15 @@ github.com/twmb/franz-go/pkg/kmsg v1.7.0 h1:a457IbvezYfA5UkiBvyV3zj0Is3y1i8EJgqj github.com/twmb/franz-go/pkg/kmsg v1.7.0/go.mod h1:se9Mjdt0Nwzc9lnjJ0HyDtLyBnaBDAd7pCje47OhSyw= github.com/twmb/franz-go/plugin/kslog v1.0.0 h1:I64oEmF+0PDvmyLgwrlOtg4mfpSE9GwlcLxM4af2t60= github.com/twmb/franz-go/plugin/kslog v1.0.0/go.mod h1:8pMjK3OJJJNNYddBSbnXZkIK5dCKFIk9GcVVCDgvnQc= -github.com/twpayne/go-geos v0.17.0 h1:158IwlZxA5Q1qWpBrP90dG3B8mQ5yb5RA4SPhR2CJ2E= -github.com/twpayne/go-geos v0.17.0/go.mod h1:OgP9eXBQBbU1Qi2IR3kF608WTd9YtRXZP0FugQ0POi0= +github.com/twpayne/go-geos v0.17.1 h1:VhncXde+Z8ISsU3JJFiAq9BAEpNtEYtHgP3cBYk6URg= +github.com/twpayne/go-geos v0.17.1/go.mod h1:5HP97VQHTM/eadbtOG+HAaLdY54etTmeDmTV4yzvTOY= github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo= github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI= -github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= @@ -403,6 +405,8 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.einride.tech/aip v0.66.0 h1:XfV+NQX6L7EOYK11yoHHFtndeaWh3KbD9/cN/6iWEt8= +go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M= go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= @@ -418,8 +422,8 @@ go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucg go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.temporal.io/api v1.29.1 h1:L722DCy3xCzpTe3Rvh1sFC9kcSaMJXqvodCF+swHGtQ= -go.temporal.io/api v1.29.1/go.mod h1:wZtsUJ3PySASGWbpXBWYVKJ4aHB2ZODEn/xNcTr9HRs= +go.temporal.io/api v1.30.1 h1:73UCTi+8l+Qy3GdDypW2FB5rj995A3Pi0mXkSu/qedw= +go.temporal.io/api v1.30.1/go.mod h1:xI9UdP3s07881dgWzG8idIBAnZq3/aop+O682EIDoT0= go.temporal.io/sdk v1.26.0 h1:QAi7irgKvJI+5cKmvy+1lkdCDJJDDNpIQAoXdr3dcyM= go.temporal.io/sdk v1.26.0/go.mod h1:rcAf1YWlbWgMsjJEuz7XiQd6UYxTQDOk2AqRRIDwq/U= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -437,8 +441,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc= +golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -528,8 +532,8 @@ golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSm golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.12.0 h1:xKuo6hzt+gMav00meVPUlXwSdoEJP46BR+wdxQEFK2o= gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY= -google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= -google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= @@ -538,12 +542,12 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 h1:ImUcDPHjTrAqNhlOkSocDLfG9rrNHH7w7uoKWPaWZ8s= -google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7/go.mod h1:/3XmxOjePkvmKrHuBy4zNFw7IzxJXtAgdpXi8Ll990U= -google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7 h1:oqta3O3AnlWbmIE3bFnWbu4bRxZjfbWCp0cKSuZh01E= -google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7/go.mod h1:VQW3tUculP/D4B+xVCo+VgSq8As6wA9ZjHl//pmk+6s= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 h1:8EeVk1VKMD+GD/neyEHGmz7pFblqPjHoi+PGQIlLx2s= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237 h1:PgNlNSx2Nq2/j4juYzQBG0/Zdr+WP4z5N01Vk4VYBCY= +google.golang.org/genproto v0.0.0-20240318140521-94a12d6c2237/go.mod h1:9sVD8c25Af3p0rGs7S7LLsxWKFiJt/65LdSyqXBkX/Y= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/flow/pua/peerdb.go b/flow/pua/peerdb.go index b1746d75c3..60a3d8687c 100644 --- a/flow/pua/peerdb.go +++ b/flow/pua/peerdb.go @@ -37,7 +37,7 @@ func RegisterTypes(ls *lua.LState) { loaders := ls.G.Registry.RawGetString("_LOADERS").(*lua.LTable) loaders.RawSetInt(2, ls.NewFunction(LoadPeerdbScript)) - ls.PreloadModule("bit32", bit32.Loader) + ls.PreloadModule("bit32", gluabit32.Loader) mt := LuaRecord.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaRecordIndex)) diff --git a/ui/package-lock.json b/ui/package-lock.json index 8809b6ec95..99e98ec366 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -27,16 +27,16 @@ "@radix-ui/react-toggle-group": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", "@tremor/react": "^3.14.1", - "@types/node": "^20.11.28", - "@types/react": "^18.2.66", + "@types/node": "^20.11.30", + "@types/react": "^18.2.70", "@types/react-dom": "^18.2.22", "classnames": "^2.5.1", "long": "^5.2.3", "lucide-react": "^0.354.0", - "material-symbols": "^0.17.0", + "material-symbols": "^0.17.1", "moment": "^2.30.1", "moment-timezone": "^0.5.45", - "next": "^14.1.3", + "next": "^14.1.4", "next-auth": "^4.24.7", "prop-types": "^15.8.1", "protobufjs": "^7.2.6", @@ -51,32 +51,32 @@ "zod": "^3.22.4" }, "devDependencies": { - "@storybook/addon-essentials": "^8.0.0", - "@storybook/addon-interactions": "^8.0.0", - "@storybook/addon-links": "^8.0.0", + "@storybook/addon-essentials": "^8.0.4", + "@storybook/addon-interactions": "^8.0.4", + "@storybook/addon-links": "^8.0.4", "@storybook/addon-styling": "^1.3.7", "@storybook/blocks": "^8.0.0", - "@storybook/nextjs": "^8.0.0", + "@storybook/nextjs": "^8.0.4", "@storybook/react": "^8.0.0", "@storybook/testing-library": "^0.2.2", - "autoprefixer": "^10.4.18", + "autoprefixer": "^10.4.19", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", - "eslint-config-next": "^14.1.3", + "eslint-config-next": "^14.1.4", "eslint-config-prettier": "^9.1.0", "eslint-plugin-storybook": "^0.8.0", "gh-pages": "^6.1.1", "less": "^4.2.0", - "postcss": "^8.4.35", + "postcss": "^8.4.38", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", "prisma": "^5.11.0", - "storybook": "^8.0.0", + "storybook": "^8.0.4", "string-width": "^7.1.0", "tailwindcss": "^3.4.1", "tailwindcss-animate": "^1.0.7", - "typescript": "^5.4.2", - "webpack": "^5.90.3" + "typescript": "^5.4.3", + "webpack": "^5.91.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -88,6 +88,12 @@ "node": ">=0.10.0" } }, + "node_modules/@adobe/css-tools": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", + "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==", + "dev": true + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -125,41 +131,41 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", + "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", - "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", + "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.1", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.0", - "@babel/parser": "^7.24.0", + "@babel/helpers": "^7.24.1", + "@babel/parser": "^7.24.1", "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.0", + "@babel/traverse": "^7.24.1", "@babel/types": "^7.24.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -176,14 +182,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", "dev": true, "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -231,9 +237,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz", - "integrity": "sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", + "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", @@ -241,7 +247,7 @@ "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -333,11 +339,11 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -401,13 +407,13 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { @@ -454,9 +460,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", "engines": { "node": ">=6.9.0" } @@ -493,13 +499,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", - "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", + "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", "dev": true, "dependencies": { "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.0", + "@babel/traverse": "^7.24.1", "@babel/types": "^7.24.0" }, "engines": { @@ -507,22 +513,23 @@ } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", - "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -532,12 +539,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", + "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -547,14 +554,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", + "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" + "@babel/plugin-transform-optional-chaining": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -564,13 +571,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", + "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -667,12 +674,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", - "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.1.tgz", + "integrity": "sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -682,12 +689,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", + "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -697,12 +704,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", + "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -736,12 +743,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", + "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -853,12 +860,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", + "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -884,12 +891,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", + "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -899,13 +906,13 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", - "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", + "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-remap-async-to-generator": "^7.22.20", "@babel/plugin-syntax-async-generators": "^7.8.4" }, @@ -917,13 +924,13 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", + "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-module-imports": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-remap-async-to-generator": "^7.22.20" }, "engines": { @@ -934,12 +941,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", + "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -949,12 +956,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz", + "integrity": "sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -964,13 +971,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", + "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -980,13 +987,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz", + "integrity": "sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -997,17 +1004,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", + "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, @@ -1019,13 +1026,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", + "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/template": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1035,12 +1042,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1050,13 +1057,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", + "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1066,12 +1073,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", + "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1081,12 +1088,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", + "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -1097,13 +1104,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", + "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", "dev": true, "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1113,12 +1120,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", + "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -1129,13 +1136,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", - "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.1.tgz", + "integrity": "sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-flow": "^7.23.3" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-flow": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1145,12 +1152,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", + "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { @@ -1161,14 +1168,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", + "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1178,12 +1185,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", + "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -1194,12 +1201,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", + "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1209,12 +1216,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", + "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -1225,12 +1232,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", + "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1240,13 +1247,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", + "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1256,13 +1263,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", + "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-simple-access": "^7.22.5" }, "engines": { @@ -1273,14 +1280,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", - "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", + "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { @@ -1291,13 +1298,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", + "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1323,12 +1330,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", + "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1338,12 +1345,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", + "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -1354,12 +1361,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", + "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -1370,16 +1377,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz", - "integrity": "sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", + "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.23.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" + "@babel/plugin-transform-parameters": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1389,13 +1395,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", + "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1405,12 +1411,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", + "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -1421,12 +1427,12 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", + "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -1438,12 +1444,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1453,13 +1459,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1469,14 +1475,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1487,12 +1493,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", + "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1502,12 +1508,12 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", - "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz", + "integrity": "sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1551,13 +1557,13 @@ } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", - "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz", + "integrity": "sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1567,12 +1573,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", + "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1583,12 +1589,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", + "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1598,16 +1604,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.0.tgz", - "integrity": "sha512-zc0GA5IitLKJrSfXlXmp8KDqLrnGECK7YRfQBmEKg1NmBOQ7e+KuclBEKJgzifQeUYLdNiAw4B4bjyvzWVLiSA==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz", + "integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-module-imports": "^7.24.3", "@babel/helper-plugin-utils": "^7.24.0", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, "engines": { @@ -1618,12 +1624,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", + "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1633,12 +1639,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", + "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { @@ -1649,12 +1655,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", + "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1664,12 +1670,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", + "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1679,12 +1685,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", + "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1694,15 +1700,15 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", - "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.1.tgz", + "integrity": "sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.23.3" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-typescript": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1712,12 +1718,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", + "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1727,13 +1733,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", + "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1743,13 +1749,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", + "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1759,13 +1765,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", + "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1775,26 +1781,26 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz", - "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.3.tgz", + "integrity": "sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.23.5", + "@babel/compat-data": "^7.24.1", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-assertions": "^7.24.1", + "@babel/plugin-syntax-import-attributes": "^7.24.1", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -1806,58 +1812,58 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.9", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.9", - "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-arrow-functions": "^7.24.1", + "@babel/plugin-transform-async-generator-functions": "^7.24.3", + "@babel/plugin-transform-async-to-generator": "^7.24.1", + "@babel/plugin-transform-block-scoped-functions": "^7.24.1", + "@babel/plugin-transform-block-scoping": "^7.24.1", + "@babel/plugin-transform-class-properties": "^7.24.1", + "@babel/plugin-transform-class-static-block": "^7.24.1", + "@babel/plugin-transform-classes": "^7.24.1", + "@babel/plugin-transform-computed-properties": "^7.24.1", + "@babel/plugin-transform-destructuring": "^7.24.1", + "@babel/plugin-transform-dotall-regex": "^7.24.1", + "@babel/plugin-transform-duplicate-keys": "^7.24.1", + "@babel/plugin-transform-dynamic-import": "^7.24.1", + "@babel/plugin-transform-exponentiation-operator": "^7.24.1", + "@babel/plugin-transform-export-namespace-from": "^7.24.1", + "@babel/plugin-transform-for-of": "^7.24.1", + "@babel/plugin-transform-function-name": "^7.24.1", + "@babel/plugin-transform-json-strings": "^7.24.1", + "@babel/plugin-transform-literals": "^7.24.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", + "@babel/plugin-transform-member-expression-literals": "^7.24.1", + "@babel/plugin-transform-modules-amd": "^7.24.1", + "@babel/plugin-transform-modules-commonjs": "^7.24.1", + "@babel/plugin-transform-modules-systemjs": "^7.24.1", + "@babel/plugin-transform-modules-umd": "^7.24.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.24.0", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/plugin-transform-new-target": "^7.24.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", + "@babel/plugin-transform-numeric-separator": "^7.24.1", + "@babel/plugin-transform-object-rest-spread": "^7.24.1", + "@babel/plugin-transform-object-super": "^7.24.1", + "@babel/plugin-transform-optional-catch-binding": "^7.24.1", + "@babel/plugin-transform-optional-chaining": "^7.24.1", + "@babel/plugin-transform-parameters": "^7.24.1", + "@babel/plugin-transform-private-methods": "^7.24.1", + "@babel/plugin-transform-private-property-in-object": "^7.24.1", + "@babel/plugin-transform-property-literals": "^7.24.1", + "@babel/plugin-transform-regenerator": "^7.24.1", + "@babel/plugin-transform-reserved-words": "^7.24.1", + "@babel/plugin-transform-shorthand-properties": "^7.24.1", + "@babel/plugin-transform-spread": "^7.24.1", + "@babel/plugin-transform-sticky-regex": "^7.24.1", + "@babel/plugin-transform-template-literals": "^7.24.1", + "@babel/plugin-transform-typeof-symbol": "^7.24.1", + "@babel/plugin-transform-unicode-escapes": "^7.24.1", + "@babel/plugin-transform-unicode-property-regex": "^7.24.1", + "@babel/plugin-transform-unicode-regex": "^7.24.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, @@ -1869,14 +1875,14 @@ } }, "node_modules/@babel/preset-flow": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.0.tgz", - "integrity": "sha512-cum/nSi82cDaSJ21I4PgLTVlj0OXovFk6GRguJYe/IKg6y6JHLTbJhybtX4k35WT9wdeJfEVjycTixMhBHd0Dg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.1.tgz", + "integrity": "sha512-sWCV2G9pcqZf+JHyv/RyqEIpFypxdCSxWIxQjpdaQxenNog7cN1pr76hg8u0Fz8Qgg0H4ETkGcJnXL8d4j0PPA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-transform-flow-strip-types": "^7.23.3" + "@babel/plugin-transform-flow-strip-types": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1900,17 +1906,17 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", - "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.1.tgz", + "integrity": "sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-transform-react-display-name": "^7.23.3", - "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-transform-react-display-name": "^7.24.1", + "@babel/plugin-transform-react-jsx": "^7.23.4", "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.23.3" + "@babel/plugin-transform-react-pure-annotations": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1920,16 +1926,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", - "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz", + "integrity": "sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-typescript": "^7.23.3" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-syntax-jsx": "^7.24.1", + "@babel/plugin-transform-modules-commonjs": "^7.24.1", + "@babel/plugin-transform-typescript": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -2082,9 +2088,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", - "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2107,18 +2113,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", - "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.0", + "@babel/parser": "^7.24.1", "@babel/types": "^7.24.0", "debug": "^4.3.1", "globals": "^11.1.0" @@ -2963,72 +2969,16 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jridgewell/gen-mapping": { @@ -3200,23 +3150,23 @@ } }, "node_modules/@next/env": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.3.tgz", - "integrity": "sha512-VhgXTvrgeBRxNPjyfBsDIMvgsKDxjlpw4IAUsHCX8Gjl1vtHUYRT3+xfQ/wwvLPDd/6kqfLqk9Pt4+7gysuCKQ==" + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.4.tgz", + "integrity": "sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ==" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.3.tgz", - "integrity": "sha512-VCnZI2cy77Yaj3L7Uhs3+44ikMM1VD/fBMwvTBb3hIaTIuqa+DmG4dhUDq+MASu3yx97KhgsVJbsas0XuiKyww==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.4.tgz", + "integrity": "sha512-n4zYNLSyCo0Ln5b7qxqQeQ34OZKXwgbdcx6kmkQbywr+0k6M3Vinft0T72R6CDAcDrne2IAgSud4uWCzFgc5HA==", "dev": true, "dependencies": { "glob": "10.3.10" } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.3.tgz", - "integrity": "sha512-LALu0yIBPRiG9ANrD5ncB3pjpO0Gli9ZLhxdOu6ZUNf3x1r3ea1rd9Q+4xxUkGrUXLqKVK9/lDkpYIJaCJ6AHQ==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.4.tgz", + "integrity": "sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg==", "cpu": [ "arm64" ], @@ -3229,9 +3179,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.3.tgz", - "integrity": "sha512-E/9WQeXxkqw2dfcn5UcjApFgUq73jqNKaE5bysDm58hEUdUGedVrnRhblhJM7HbCZNhtVl0j+6TXsK0PuzXTCg==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.4.tgz", + "integrity": "sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ==", "cpu": [ "x64" ], @@ -3244,9 +3194,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.3.tgz", - "integrity": "sha512-USArX9B+3rZSXYLFvgy0NVWQgqh6LHWDmMt38O4lmiJNQcwazeI6xRvSsliDLKt+78KChVacNiwvOMbl6g6BBw==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.4.tgz", + "integrity": "sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA==", "cpu": [ "arm64" ], @@ -3259,9 +3209,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.3.tgz", - "integrity": "sha512-esk1RkRBLSIEp1qaQXv1+s6ZdYzuVCnDAZySpa62iFTMGTisCyNQmqyCTL9P+cLJ4N9FKCI3ojtSfsyPHJDQNw==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.4.tgz", + "integrity": "sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==", "cpu": [ "arm64" ], @@ -3274,9 +3224,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.3.tgz", - "integrity": "sha512-8uOgRlYEYiKo0L8YGeS+3TudHVDWDjPVDUcST+z+dUzgBbTEwSSIaSgF/vkcC1T/iwl4QX9iuUyUdQEl0Kxalg==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.4.tgz", + "integrity": "sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==", "cpu": [ "x64" ], @@ -3289,9 +3239,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.3.tgz", - "integrity": "sha512-DX2zqz05ziElLoxskgHasaJBREC5Y9TJcbR2LYqu4r7naff25B4iXkfXWfcp69uD75/0URmmoSgT8JclJtrBoQ==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.4.tgz", + "integrity": "sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==", "cpu": [ "x64" ], @@ -3304,9 +3254,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.3.tgz", - "integrity": "sha512-HjssFsCdsD4GHstXSQxsi2l70F/5FsRTRQp8xNgmQs15SxUfUJRvSI9qKny/jLkY3gLgiCR3+6A7wzzK0DBlfA==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.4.tgz", + "integrity": "sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==", "cpu": [ "arm64" ], @@ -3319,9 +3269,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.3.tgz", - "integrity": "sha512-DRuxD5axfDM1/Ue4VahwSxl1O5rn61hX8/sF0HY8y0iCbpqdxw3rB3QasdHn/LJ6Wb2y5DoWzXcz3L1Cr+Thrw==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.4.tgz", + "integrity": "sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw==", "cpu": [ "ia32" ], @@ -3334,9 +3284,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.3.tgz", - "integrity": "sha512-uC2DaDoWH7h1P/aJ4Fok3Xiw6P0Lo4ez7NbowW2VGNXw/Xv6tOuLUcxhBYZxsSUJtpeknCi8/fvnSpyCFp4Rcg==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.4.tgz", + "integrity": "sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w==", "cpu": [ "x64" ], @@ -4794,9 +4744,15 @@ } }, "node_modules/@rushstack/eslint-patch": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz", - "integrity": "sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.8.0.tgz", + "integrity": "sha512-0HejFckBN2W+ucM6cUOlwsByTKt9/+0tWhqUffNIcHqCXkthY/mZ7AuYPK/2IIaGWhdl0h+tICDO0ssLMd6XMQ==", + "dev": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, "node_modules/@sindresorhus/merge-streams": { @@ -4812,12 +4768,12 @@ } }, "node_modules/@storybook/addon-actions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.0.0.tgz", - "integrity": "sha512-QXfnEWZt5k35cPYsLvxq505XrCgXujc4UEkky1lBtSMI9SLzlXZg3fC/lW0c0hiu2c0+zI+y4fj5vTE9AZJdjw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.0.4.tgz", + "integrity": "sha512-EyCWo+8T11/TJGYNL/AXtW4yaB+q1v2E9mixbumryCLxpTl2NtaeGZ4e0dlwfIMuw/7RWgHk2uIypcIPR/UANQ==", "dev": true, "dependencies": { - "@storybook/core-events": "8.0.0", + "@storybook/core-events": "8.0.4", "@storybook/global": "^5.0.0", "@types/uuid": "^9.0.1", "dequal": "^2.0.2", @@ -4830,9 +4786,9 @@ } }, "node_modules/@storybook/addon-backgrounds": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.0.0.tgz", - "integrity": "sha512-hJLrtJa3paAL1DdArdqRFSPWji7s2kJlPh8mUhDpMHy0AOWrcslUanHWVmmgYpnBsYBgQcldt6eRIROtqgpSeA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.0.4.tgz", + "integrity": "sha512-fef0KD2GhJx2zpicOf8iL7k2LiIsNzEbGaQpIIjoy4DMqM1hIfNCt3DGTLH7LN5O8G+NVCLS1xmQg7RLvIVSCA==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -4845,12 +4801,12 @@ } }, "node_modules/@storybook/addon-controls": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.0.0.tgz", - "integrity": "sha512-hBYJ9O6G+lN43TxNPnw78GhLirjRVN8kFJSVg2Bha87hIvS3c/zx5ZWqtiXjp4wL4/r/IFe4EvBcBQh4Mpi8uw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.0.4.tgz", + "integrity": "sha512-K5EYBTsUOTJlvIdA7p6Xj31wnV+RbZAkk56UKQvA7nJD7oDuLOq3E9u46F/uZD1vxddd9zFhf2iONfMe3KTTwQ==", "dev": true, "dependencies": { - "@storybook/blocks": "8.0.0", + "@storybook/blocks": "8.0.4", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" }, @@ -4860,24 +4816,24 @@ } }, "node_modules/@storybook/addon-docs": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.0.0.tgz", - "integrity": "sha512-P86M4Mo3FKtMIzSc8Hao46NmrlBs4w81BVf3AWNVka5aIPdWP2pINgDDDweASPgFKMVQNWUreR5pl0DHZfaJ5g==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.0.4.tgz", + "integrity": "sha512-m0Y7qGAMnNPLEOEgzW/SBm8GX0xabJBaRN+aYijO6UKTln7F6oXXVve+xPC0Y4s6Gc9HZFdJY8WXZr1YSGEUVA==", "dev": true, "dependencies": { "@babel/core": "^7.12.3", "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.0.0", - "@storybook/client-logger": "8.0.0", - "@storybook/components": "8.0.0", - "@storybook/csf-plugin": "8.0.0", - "@storybook/csf-tools": "8.0.0", + "@storybook/blocks": "8.0.4", + "@storybook/client-logger": "8.0.4", + "@storybook/components": "8.0.4", + "@storybook/csf-plugin": "8.0.4", + "@storybook/csf-tools": "8.0.4", "@storybook/global": "^5.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/preview-api": "8.0.0", - "@storybook/react-dom-shim": "8.0.0", - "@storybook/theming": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/node-logger": "8.0.4", + "@storybook/preview-api": "8.0.4", + "@storybook/react-dom-shim": "8.0.4", + "@storybook/theming": "8.0.4", + "@storybook/types": "8.0.4", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "fs-extra": "^11.1.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", @@ -4892,24 +4848,24 @@ } }, "node_modules/@storybook/addon-essentials": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.0.0.tgz", - "integrity": "sha512-n5uNerxBj2PrL8NJhzSUL3ctsW3Wy0ySBBrrChhBaXLoAkTP+KpJlX8h55abxdMkI0i+dreS//XQ0lpw1KX4pw==", - "dev": true, - "dependencies": { - "@storybook/addon-actions": "8.0.0", - "@storybook/addon-backgrounds": "8.0.0", - "@storybook/addon-controls": "8.0.0", - "@storybook/addon-docs": "8.0.0", - "@storybook/addon-highlight": "8.0.0", - "@storybook/addon-measure": "8.0.0", - "@storybook/addon-outline": "8.0.0", - "@storybook/addon-toolbars": "8.0.0", - "@storybook/addon-viewport": "8.0.0", - "@storybook/core-common": "8.0.0", - "@storybook/manager-api": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/preview-api": "8.0.0", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.0.4.tgz", + "integrity": "sha512-mUIqhAkSz6Qv7nRqAAyCqMLiXBWVsY/8qN7HEIoaMQgdFq38KW3rYwNdzd2JLeXNWP1bBXwfvfcFe7/eqhYJFA==", + "dev": true, + "dependencies": { + "@storybook/addon-actions": "8.0.4", + "@storybook/addon-backgrounds": "8.0.4", + "@storybook/addon-controls": "8.0.4", + "@storybook/addon-docs": "8.0.4", + "@storybook/addon-highlight": "8.0.4", + "@storybook/addon-measure": "8.0.4", + "@storybook/addon-outline": "8.0.4", + "@storybook/addon-toolbars": "8.0.4", + "@storybook/addon-viewport": "8.0.4", + "@storybook/core-common": "8.0.4", + "@storybook/manager-api": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/preview-api": "8.0.4", "ts-dedent": "^2.0.0" }, "funding": { @@ -4918,9 +4874,9 @@ } }, "node_modules/@storybook/addon-highlight": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.0.0.tgz", - "integrity": "sha512-bSba9UTcPJBFUy5peIU8XPlKK/7lT054977oLGgVYup2u88km6pWaMNSGMWhb3xXdseTgrj96k/b+md4X+WrMg==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.0.4.tgz", + "integrity": "sha512-tnEiVaJlXL07v8JBox+QtRPVruoy0YovOTAOWY7fKDiKzF1I9wLaJjQF3wOsvwspHTHu00OZw2gsazgXiH4wLQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -4931,14 +4887,15 @@ } }, "node_modules/@storybook/addon-interactions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.0.0.tgz", - "integrity": "sha512-lb6WZAeF3MIT05wSVbz2ZKDpTIoTmHW5e8hImdquNlOm8qNm4fl5BLpVrZT1YkC6v42MM8yU/DeeUw+8w7rXDg==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.0.4.tgz", + "integrity": "sha512-wTEOnVUbF1lNJxxocr5IKmpgnmwyO8YsQf6Baw3tTWCHAa/MaWWQYq1OA6CfFfmVGGRjv/w2GTuf1Vyq99O7mg==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/types": "8.0.0", - "jest-mock": "^27.0.6", + "@storybook/instrumenter": "8.0.4", + "@storybook/test": "8.0.4", + "@storybook/types": "8.0.4", "polished": "^4.2.2", "ts-dedent": "^2.2.0" }, @@ -4948,9 +4905,9 @@ } }, "node_modules/@storybook/addon-links": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.0.0.tgz", - "integrity": "sha512-UjB68EJwSvRsD326KJAzYkuzhCdJmkliiitaqSJ7GUdgGgTkKC7cqH8QmRC0SK5qRi0lN59ARIKPiP5wjsEeOw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.0.4.tgz", + "integrity": "sha512-SzE+JPZ4mxjprZqbLHf8Hx7UA2fXfMajFjeY9c3JREKQrDoOF1e4r28nAoVsZYF+frWxQB51U4+hOqjlx06wEA==", "dev": true, "dependencies": { "@storybook/csf": "^0.1.2", @@ -4971,9 +4928,9 @@ } }, "node_modules/@storybook/addon-measure": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.0.0.tgz", - "integrity": "sha512-vSqQMxNHO++1XIyOF4HkQ/9UNADYCVCzoWG/JwOmWJ1NdfaPffN+QxLn+MYq+ex9R174nBdbjVqb2+e4MdYzPw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.0.4.tgz", + "integrity": "sha512-GZYKo2ss5Br+dfHinoK3bgTaS90z3oKKDkhv6lrFfjjU1mDYzzMJpxajQhd3apCYxHLr3MbUqMQibWu2T/q2DQ==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -4985,9 +4942,9 @@ } }, "node_modules/@storybook/addon-outline": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.0.0.tgz", - "integrity": "sha512-8/rs+4UYSQNE2J2CgeeAMJuz7UmJRN4T2Id4oESv7nfM+aUXXF1cOBw1EnofBie2ukVad9lATlsPaNx6ldoWsg==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.0.4.tgz", + "integrity": "sha512-6J9ezNDUxdA3rMCh8sUEQbUwAgkrr+M9QdiFr1t+gKrk5FKP5gwubw1sr3sF1IRB9+s/AjljcOtJAVulSfq05w==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0", @@ -5623,9 +5580,9 @@ } }, "node_modules/@storybook/addon-styling/node_modules/@types/node": { - "version": "18.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.24.tgz", - "integrity": "sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw==", + "version": "18.19.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", + "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -5736,9 +5693,9 @@ } }, "node_modules/@storybook/addon-toolbars": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.0.0.tgz", - "integrity": "sha512-+nNe52DAs42VIJxJnsg3d3BAVf+svR9lvaf3dD/HgS9vBWtp2wIumDM6b05umnVuR/dXviSpdpy+gm/cCdIQGQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.0.4.tgz", + "integrity": "sha512-yodRXDYog/90cNEy84kg6s7L+nxQ+egBjHBTsav1L4cJmQI/uAX8yISHHiX4I5ppNc120Jz3UdHdRxXRlo345g==", "dev": true, "funding": { "type": "opencollective", @@ -5746,9 +5703,9 @@ } }, "node_modules/@storybook/addon-viewport": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.0.0.tgz", - "integrity": "sha512-eqgyZszJSz6C3GXJTn8/8bmL8zqALr4dnBFg8w/RJ+gydVCk17Ow3ifYTWrEGVLXCCwd0XbCZGj9tAmfhovjTQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.0.4.tgz", + "integrity": "sha512-E5IKOsxKcOtlOYc0cWgzVJohQB+dVBWwaJcg5FlslToknfVB9M0kfQ/SQcp3KB0C9/cOmJK1Jm388InW+EjrBQ==", "dev": true, "dependencies": { "memoizerific": "^1.11.3" @@ -5894,23 +5851,23 @@ } }, "node_modules/@storybook/blocks": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.0.0.tgz", - "integrity": "sha512-Sxy7pOa6B3ci/XhfKca6u97Kz6pGZV5ieQBUWRYByUZTjiOp12RVLFptexxrJHyNBA00BHJPek4fvFSJfn6nOQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.0.4.tgz", + "integrity": "sha512-9dRXk9zLJVPOmEWsSXm10XUmIfvS/tVgeBgFXNbusFQZXPpexIPNdRgB004pDGg9RvlY78ykpnd3yP143zaXMg==", "dev": true, "dependencies": { - "@storybook/channels": "8.0.0", - "@storybook/client-logger": "8.0.0", - "@storybook/components": "8.0.0", - "@storybook/core-events": "8.0.0", + "@storybook/channels": "8.0.4", + "@storybook/client-logger": "8.0.4", + "@storybook/components": "8.0.4", + "@storybook/core-events": "8.0.4", "@storybook/csf": "^0.1.2", - "@storybook/docs-tools": "8.0.0", + "@storybook/docs-tools": "8.0.4", "@storybook/global": "^5.0.0", "@storybook/icons": "^1.2.5", - "@storybook/manager-api": "8.0.0", - "@storybook/preview-api": "8.0.0", - "@storybook/theming": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/manager-api": "8.0.4", + "@storybook/preview-api": "8.0.4", + "@storybook/theming": "8.0.4", + "@storybook/types": "8.0.4", "@types/lodash": "^4.14.167", "color-convert": "^2.0.1", "dequal": "^2.0.2", @@ -5942,15 +5899,15 @@ } }, "node_modules/@storybook/builder-manager": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-8.0.0.tgz", - "integrity": "sha512-cUj1YKOvk+pemom9QXdLm+yWRovTQiV2HPfdjVftASD++Bau2hVpZKDhII0dLKg9mluojJ6Rt83F1daAyA2njQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-8.0.4.tgz", + "integrity": "sha512-BafYVxq77uuTmXdjYo5by42OyOrb6qcpWYKva3ntWK2ZhTaLJlwwqAOdahT1DVzi4VeUP6465YvsTCzIE8fuIw==", "dev": true, "dependencies": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@storybook/core-common": "8.0.0", - "@storybook/manager": "8.0.0", - "@storybook/node-logger": "8.0.0", + "@storybook/core-common": "8.0.4", + "@storybook/manager": "8.0.4", + "@storybook/node-logger": "8.0.4", "@types/ejs": "^3.1.1", "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", "browser-assert": "^1.2.1", @@ -5968,19 +5925,19 @@ } }, "node_modules/@storybook/builder-webpack5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.0.0.tgz", - "integrity": "sha512-Pkqeume16aXR1jkMFfafTuhFXviBZWguCqSsTCzH+fyN28k9QYfcsUUZ5LlEGz9ZKFEO2+ZIuq2Mg1iBeSzUSw==", - "dev": true, - "dependencies": { - "@storybook/channels": "8.0.0", - "@storybook/client-logger": "8.0.0", - "@storybook/core-common": "8.0.0", - "@storybook/core-events": "8.0.0", - "@storybook/core-webpack": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/preview": "8.0.0", - "@storybook/preview-api": "8.0.0", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.0.4.tgz", + "integrity": "sha512-FKXIGfDjZJ7KCq6w8e3NEp2+KATsh4U24UV/K8cFjCrRIU++jDpO274D9ozdpzEmhvHOfxK/QlgalqS4G599Aw==", + "dev": true, + "dependencies": { + "@storybook/channels": "8.0.4", + "@storybook/client-logger": "8.0.4", + "@storybook/core-common": "8.0.4", + "@storybook/core-events": "8.0.4", + "@storybook/core-webpack": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/preview": "8.0.4", + "@storybook/preview-api": "8.0.4", "@types/node": "^18.0.0", "@types/semver": "^7.3.4", "browser-assert": "^1.2.1", @@ -6019,9 +5976,9 @@ } }, "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { - "version": "18.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.24.tgz", - "integrity": "sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw==", + "version": "18.19.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", + "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -6061,13 +6018,13 @@ "dev": true }, "node_modules/@storybook/channels": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-8.0.0.tgz", - "integrity": "sha512-uykCBlSIMVodsgTFC/XAgO7JeaTJrKtDmmM6Z4liGkPS6EUvurOEu2vK6FuvojzhLHdVJ5bP+VXSJerfm7aE4Q==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-8.0.4.tgz", + "integrity": "sha512-haKV+8RbiSzLjicowUfc7h2fTClZHX/nz9SRUecf4IEZUEu2T78OgM/TzqZvL7rA3+/fKqp5iI+3PN3OA75Sdg==", "dev": true, "dependencies": { - "@storybook/client-logger": "8.0.0", - "@storybook/core-events": "8.0.0", + "@storybook/client-logger": "8.0.4", + "@storybook/core-events": "8.0.4", "@storybook/global": "^5.0.0", "telejson": "^7.2.0", "tiny-invariant": "^1.3.1" @@ -6078,22 +6035,22 @@ } }, "node_modules/@storybook/cli": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-8.0.0.tgz", - "integrity": "sha512-4W99ldBUJjrEbZlxI4rvqW8lRY+AP2+wLGRMp4nyI/XW5cp7R+OryZf4imHgecunBQyKGXVek+poDlgKPQsxsg==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-8.0.4.tgz", + "integrity": "sha512-8jb8hrulRMfyFyNXFEapxHBS51xb42ZZGfVAacXIsHOJtjOd5CnOoSUYn0aOkVl19VF/snoa9JOW7BaW/50Eqw==", "dev": true, "dependencies": { "@babel/core": "^7.23.0", "@babel/types": "^7.23.0", "@ndelangen/get-tarball": "^3.0.7", - "@storybook/codemod": "8.0.0", - "@storybook/core-common": "8.0.0", - "@storybook/core-events": "8.0.0", - "@storybook/core-server": "8.0.0", - "@storybook/csf-tools": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/telemetry": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/codemod": "8.0.4", + "@storybook/core-common": "8.0.4", + "@storybook/core-events": "8.0.4", + "@storybook/core-server": "8.0.4", + "@storybook/csf-tools": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/telemetry": "8.0.4", + "@storybook/types": "8.0.4", "@types/semver": "^7.3.4", "@yarnpkg/fslib": "2.10.3", "@yarnpkg/libzip": "2.3.0", @@ -6253,9 +6210,9 @@ "dev": true }, "node_modules/@storybook/client-logger": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-8.0.0.tgz", - "integrity": "sha512-olc1vUfaZNkXc7L8UoCdGmyBieHQbsaB+0vVoivYMSa1DHYtXE75RefU3lhMSGrkvIZmXMvfaIDmnyJIOB5FxA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-8.0.4.tgz", + "integrity": "sha512-2SeEg3PT/d0l/+EAVtyj9hmMLTyTPp+bRBSzxYouBjtJPM1jrdKpFagj1o3uBRovwWm9SIVX6/ZsoRC33PEV1g==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -6266,18 +6223,18 @@ } }, "node_modules/@storybook/codemod": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.0.0.tgz", - "integrity": "sha512-rLY3M1xL+4S5dUB8XoSfDF46FxdntSsaFH4sjHZ08itVbwAAl7XqhYElVGueuobTgicJcOVTY8CJNkWcY6ETzA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.0.4.tgz", + "integrity": "sha512-bysG46P4wjlR3RCpr/ntNAUaupWpzLcWYWti3iNtIyZ/iPrX6KtXoA9QCIwJZrlv41us6F+KEZbzLzkgWbymtQ==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", "@babel/preset-env": "^7.23.2", "@babel/types": "^7.23.0", "@storybook/csf": "^0.1.2", - "@storybook/csf-tools": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/csf-tools": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/types": "8.0.4", "@types/cross-spawn": "^6.0.2", "cross-spawn": "^7.0.3", "globby": "^11.0.2", @@ -6322,18 +6279,18 @@ } }, "node_modules/@storybook/components": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.0.0.tgz", - "integrity": "sha512-+LmHnR2XQQ76uyWW5u+9ZBlS5sPyJWE6cbMdmkJ0PMGaZdZuF07urcg4z4/qBsDxRZDquBPu/Li5xx6OjXhVKw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.0.4.tgz", + "integrity": "sha512-i5ngl5GTOLB9nZ1cmpxTjtWct5IuH9UxzFC73a0jHMkCwN26w16IqufRVDaoQv0AvZN4pd4fNM2in/XVHA10dw==", "dev": true, "dependencies": { "@radix-ui/react-slot": "^1.0.2", - "@storybook/client-logger": "8.0.0", + "@storybook/client-logger": "8.0.4", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", "@storybook/icons": "^1.2.5", - "@storybook/theming": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/theming": "8.0.4", + "@storybook/types": "8.0.4", "memoizerific": "^1.11.3", "util-deprecate": "^1.0.2" }, @@ -6347,15 +6304,15 @@ } }, "node_modules/@storybook/core-common": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-8.0.0.tgz", - "integrity": "sha512-fqlQYw5/PDW/oj34QwU5u0HkNLPgELfszsvLFsUcwI7uAzwb/WC2WdPvncT7qRPNcSZLXKJcA8QAqKL4t4I8bg==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-8.0.4.tgz", + "integrity": "sha512-dzFRLm5FxUa2EFE6Rx/KLDTJNLBIp1S2/+Q1K+rG8V+CLvewCc2Cd486rStZqSXEKI7vDnsRs/aMla+N0X/++Q==", "dev": true, "dependencies": { - "@storybook/core-events": "8.0.0", - "@storybook/csf-tools": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/core-events": "8.0.4", + "@storybook/csf-tools": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/types": "8.0.4", "@yarnpkg/fslib": "2.10.3", "@yarnpkg/libzip": "2.3.0", "chalk": "^4.1.0", @@ -6472,9 +6429,9 @@ "dev": true }, "node_modules/@storybook/core-events": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-8.0.0.tgz", - "integrity": "sha512-kkabj4V99gOTBW+y3HM/LTCDekglqb+lslZMamM+Ytxv1lCqCEOIR/OGfnYOyEaK4BLcx61Zp+fO30FZxtoT1w==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-8.0.4.tgz", + "integrity": "sha512-1FgLacIGi9i6/fyxw7ZJDC621RK47IMaA3keH4lc11ASRzCSwJ4YOrXjBFjfPc79EF2BuX72DDJNbhj6ynfF3g==", "dev": true, "dependencies": { "ts-dedent": "^2.0.0" @@ -6485,28 +6442,28 @@ } }, "node_modules/@storybook/core-server": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-8.0.0.tgz", - "integrity": "sha512-uVvS4psu/wQ+m9JTAvEvSwxjNKiCviNmNX1fv/VYRhQiAHhdb3e58NfeHd6QBffyOF80hY1RJWe3vAPcNIoZxA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-8.0.4.tgz", + "integrity": "sha512-/633Pp7LPcDWXkPLSW+W9VUYUbVkdVBG6peXjuzogV0vzdM0dM9af/T0uV2NQxUhzoy6/7QdSDljE+eEOBs2Lw==", "dev": true, "dependencies": { "@aw-web-design/x-default-browser": "1.4.126", "@babel/core": "^7.23.9", "@discoveryjs/json-ext": "^0.5.3", - "@storybook/builder-manager": "8.0.0", - "@storybook/channels": "8.0.0", - "@storybook/core-common": "8.0.0", - "@storybook/core-events": "8.0.0", + "@storybook/builder-manager": "8.0.4", + "@storybook/channels": "8.0.4", + "@storybook/core-common": "8.0.4", + "@storybook/core-events": "8.0.4", "@storybook/csf": "^0.1.2", - "@storybook/csf-tools": "8.0.0", + "@storybook/csf-tools": "8.0.4", "@storybook/docs-mdx": "3.0.0", "@storybook/global": "^5.0.0", - "@storybook/manager": "8.0.0", - "@storybook/manager-api": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/preview-api": "8.0.0", - "@storybook/telemetry": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/manager": "8.0.4", + "@storybook/manager-api": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/preview-api": "8.0.4", + "@storybook/telemetry": "8.0.4", + "@storybook/types": "8.0.4", "@types/detect-port": "^1.3.0", "@types/node": "^18.0.0", "@types/pretty-hrtime": "^1.0.0", @@ -6540,9 +6497,9 @@ } }, "node_modules/@storybook/core-server/node_modules/@types/node": { - "version": "18.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.24.tgz", - "integrity": "sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw==", + "version": "18.19.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", + "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -6663,14 +6620,14 @@ "dev": true }, "node_modules/@storybook/core-webpack": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.0.0.tgz", - "integrity": "sha512-JhZwPFoL92ntTdhwGSokodNZlpogs/u2OjImynfcXpnz7FqEQVJ/d3GiPwG9Wx+Ek2mUOn8XeorZI1LNTj+ihA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.0.4.tgz", + "integrity": "sha512-sECeoJtT6iFWzgZaQbS1TEZvBrXIT4qb9fa0x2/I5YhCTPnprCNL1yyN90hFQTpdLco5vfQ86YnpzMRntODn7A==", "dev": true, "dependencies": { - "@storybook/core-common": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/core-common": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/types": "8.0.4", "@types/node": "^18.0.0", "ts-dedent": "^2.0.0" }, @@ -6680,30 +6637,30 @@ } }, "node_modules/@storybook/core-webpack/node_modules/@types/node": { - "version": "18.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.24.tgz", - "integrity": "sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw==", + "version": "18.19.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", + "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@storybook/csf": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.2.tgz", - "integrity": "sha512-ePrvE/pS1vsKR9Xr+o+YwdqNgHUyXvg+1Xjx0h9LrVx7Zq4zNe06pd63F5EvzTbCbJsHj7GHr9tkiaqm7U8WRA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.3.tgz", + "integrity": "sha512-IPZvXXo4b3G+gpmgBSBqVM81jbp2ePOKsvhgJdhyZJtkYQCII7rg9KKLQhvBQM5sLaF1eU6r0iuwmyynC9d9SA==", "dev": true, "dependencies": { "type-fest": "^2.19.0" } }, "node_modules/@storybook/csf-plugin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.0.0.tgz", - "integrity": "sha512-bCX3XvZ8X1dS08ung0IhugtTUOK+rWwRjWjyj5WC7fl5HYyFYQ91MC2f8EccYQaDYl9Dfvo1cw685gnk6PoLbw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.0.4.tgz", + "integrity": "sha512-pEgctWuS/qeKMFZJJUM2JuKwjKBt27ye+216ft7xhNqpsrmCgumJYrkU/ii2CsFJU/qr5Fu9EYw+N+vof1OalQ==", "dev": true, "dependencies": { - "@storybook/csf-tools": "8.0.0", + "@storybook/csf-tools": "8.0.4", "unplugin": "^1.3.1" }, "funding": { @@ -6712,9 +6669,9 @@ } }, "node_modules/@storybook/csf-tools": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-8.0.0.tgz", - "integrity": "sha512-VIMaZJiGM2NVzlgxaOyaVlH1pw/VSrJygDqOZyANh/kl4KHA+6xIqOkZC+X0+5K295dTFx2nR6S3btTjwT/Wrg==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-8.0.4.tgz", + "integrity": "sha512-dMSZxWnXBhmXGOZZOAJ4DKZRCYdA0HaqqZ4/eF9MLLsI+qvW4EklcpjVY6bsIzACgubRWtRZkTpxTnjExi/N1A==", "dev": true, "dependencies": { "@babel/generator": "^7.23.0", @@ -6722,7 +6679,7 @@ "@babel/traverse": "^7.23.2", "@babel/types": "^7.23.0", "@storybook/csf": "^0.1.2", - "@storybook/types": "8.0.0", + "@storybook/types": "8.0.4", "fs-extra": "^11.1.0", "recast": "^0.23.5", "ts-dedent": "^2.0.0" @@ -6739,14 +6696,14 @@ "dev": true }, "node_modules/@storybook/docs-tools": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-8.0.0.tgz", - "integrity": "sha512-d6slxGMosurSTPp1zOTnr7EILnm9xmUrT0xF3Vxr3Yat5/YQEe3WSADktIFyWwlqvIu7MQ8Lh+oelAb5TuxiDw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-8.0.4.tgz", + "integrity": "sha512-PONfG8j/AOHi79NbEkneFRZIscrShbA0sgA+62zeejH4r9+fuIkIKtLnKcAxvr8Bm6uo9aSQbISJZUcBG42WhQ==", "dev": true, "dependencies": { - "@storybook/core-common": "8.0.0", - "@storybook/preview-api": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/core-common": "8.0.4", + "@storybook/preview-api": "8.0.4", + "@storybook/types": "8.0.4", "@types/doctrine": "^0.0.3", "assert": "^2.1.0", "doctrine": "^3.0.0", @@ -6776,10 +6733,29 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@storybook/instrumenter": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.0.4.tgz", + "integrity": "sha512-lkHv1na12oMTZvuDbzufgqrtFlV1XqdXrAAg7YXZOia/oMz6Z/XMldEqwLPUCLGVodbFJofrpE67Wtw8dNTDQg==", + "dev": true, + "dependencies": { + "@storybook/channels": "8.0.4", + "@storybook/client-logger": "8.0.4", + "@storybook/core-events": "8.0.4", + "@storybook/global": "^5.0.0", + "@storybook/preview-api": "8.0.4", + "@vitest/utils": "^1.3.1", + "util": "^0.12.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, "node_modules/@storybook/manager": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-8.0.0.tgz", - "integrity": "sha512-1aCHzc+A4IOdDves+mE0K9bjyyPzPAIlR7oI6kSuO416/HXXJDdN5G825OQB/VIBYc1b8cNElMdNVKQK2FQorQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-8.0.4.tgz", + "integrity": "sha512-M5IofDSxbIQIdAglxUtZOGKjZ1EAq1Mdbh4UolVsF1PKF6dAvBQJLVW6TiLjEbmPBtqgeYKMgrmmYiFNqVcdBQ==", "dev": true, "funding": { "type": "opencollective", @@ -6787,19 +6763,20 @@ } }, "node_modules/@storybook/manager-api": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.0.0.tgz", - "integrity": "sha512-vJcCc2hG78RjIyhmooqnBlVrTdIomzRqG5WO025tXFgRV1eRUkWJRqSSudcLJO6wk77ZSAtI1ihsDrjsrBFWZw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.0.4.tgz", + "integrity": "sha512-TudiRmWlsi8kdjwqW0DDLen76Zp4Sci/AnvTbZvZOWe8C2mruxcr6aaGwuIug6y+uxIyXDvURF6Cek5Twz4isg==", "dev": true, "dependencies": { - "@storybook/channels": "8.0.0", - "@storybook/client-logger": "8.0.0", - "@storybook/core-events": "8.0.0", + "@storybook/channels": "8.0.4", + "@storybook/client-logger": "8.0.4", + "@storybook/core-events": "8.0.4", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/router": "8.0.0", - "@storybook/theming": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/icons": "^1.2.5", + "@storybook/router": "8.0.4", + "@storybook/theming": "8.0.4", + "@storybook/types": "8.0.4", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", @@ -6813,9 +6790,9 @@ } }, "node_modules/@storybook/nextjs": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-8.0.0.tgz", - "integrity": "sha512-Z+eWizq7k+Nsr8edFwQmJAhEjJEu8o8i0lkcD+v/7kQbmwl+WDpRbSBu824FCaQNNkSLArXk6FgItlxGk31KrA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-8.0.4.tgz", + "integrity": "sha512-60OmklpKB48l57Tfo3X5+RxSuz15iudjrwyeTJBq6Afi0fFa7hWk4jq/n+LdCjhOxavLtHRv/qFEQrMDmGH0gA==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", @@ -6832,15 +6809,15 @@ "@babel/preset-typescript": "^7.23.2", "@babel/runtime": "^7.23.2", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", - "@storybook/addon-actions": "8.0.0", - "@storybook/builder-webpack5": "8.0.0", - "@storybook/core-common": "8.0.0", - "@storybook/core-events": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/preset-react-webpack": "8.0.0", - "@storybook/preview-api": "8.0.0", - "@storybook/react": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/addon-actions": "8.0.4", + "@storybook/builder-webpack5": "8.0.4", + "@storybook/core-common": "8.0.4", + "@storybook/core-events": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/preset-react-webpack": "8.0.4", + "@storybook/preview-api": "8.0.4", + "@storybook/react": "8.0.4", + "@storybook/types": "8.0.4", "@types/node": "^18.0.0", "@types/semver": "^7.3.4", "babel-loader": "^9.1.3", @@ -6887,9 +6864,9 @@ } }, "node_modules/@storybook/nextjs/node_modules/@types/node": { - "version": "18.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.24.tgz", - "integrity": "sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw==", + "version": "18.19.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", + "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -6967,9 +6944,9 @@ "dev": true }, "node_modules/@storybook/node-logger": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-8.0.0.tgz", - "integrity": "sha512-C/sMNQqCIYVtJaLpe92RSkPgW3GXcWp6QeH5+glfP42kh+G9axxnEJJ996tyAnNQRzUuI+Eh+B7ytPZU1/WseQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-8.0.4.tgz", + "integrity": "sha512-cALLHuX53vLQsoJamGRlquh2pfhPq9copXou2JTmFT6mrCcipo77SzhBDfeeuhaGv6vUWPfmGjPBEHXWGPe4+g==", "dev": true, "funding": { "type": "opencollective", @@ -6977,15 +6954,15 @@ } }, "node_modules/@storybook/preset-react-webpack": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.0.0.tgz", - "integrity": "sha512-3XGtKR684A91CZVcD7l7CfuaaVl6ih5hKy+ITAGSulTyxz4Ym2MakZwz0VrenPHdndu1+vFvBWkf4Kh3WbyjYQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.0.4.tgz", + "integrity": "sha512-XldgoZJOXNbZLGhvP6FqVeRnXigEZXV88uhEveREH4zRceYxXUmiCjFUnFy5aXaYZLcv09GHpqTPCqRoOZ+upg==", "dev": true, "dependencies": { - "@storybook/core-webpack": "8.0.0", - "@storybook/docs-tools": "8.0.0", - "@storybook/node-logger": "8.0.0", - "@storybook/react": "8.0.0", + "@storybook/core-webpack": "8.0.4", + "@storybook/docs-tools": "8.0.4", + "@storybook/node-logger": "8.0.4", + "@storybook/react": "8.0.4", "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", "@types/node": "^18.0.0", "@types/semver": "^7.3.4", @@ -7016,9 +6993,9 @@ } }, "node_modules/@storybook/preset-react-webpack/node_modules/@types/node": { - "version": "18.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.24.tgz", - "integrity": "sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw==", + "version": "18.19.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", + "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -7058,9 +7035,9 @@ "dev": true }, "node_modules/@storybook/preview": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-8.0.0.tgz", - "integrity": "sha512-cFV7+6LYe1qr1HXm+oc74Z6ygAKgkjkhfGsfDhdS+UrzoFL9JF/+++RcE+xSBNVfzZjL19U1CsPEN0v0smIbkQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-8.0.4.tgz", + "integrity": "sha512-dJa13bIxQBfa5ZsXAeL6X/oXI6b87Fy31pvpKPkW1o+7M6MC4OvwGQBqgAd7m8yn6NuIHxrdwjEupa7l7PGb6w==", "dev": true, "funding": { "type": "opencollective", @@ -7068,17 +7045,17 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.0.0.tgz", - "integrity": "sha512-R2NBKtvHi+i1b/3PZe4u4YdJ7dlqr8YTqLn7syB/YSnKRAa7DYed+GJLu4qFJisE6IuYi+57AsdW16otRFEVvg==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.0.4.tgz", + "integrity": "sha512-uZCgZ/7BZkFTNudCBWx3YPFVdReMQSZJj9EfQVhQaPmfGORHGMvZMRsQXl0ONhPy7zDD4rVQxu5dSKWmIiYoWQ==", "dev": true, "dependencies": { - "@storybook/channels": "8.0.0", - "@storybook/client-logger": "8.0.0", - "@storybook/core-events": "8.0.0", + "@storybook/channels": "8.0.4", + "@storybook/client-logger": "8.0.4", + "@storybook/core-events": "8.0.4", "@storybook/csf": "^0.1.2", "@storybook/global": "^5.0.0", - "@storybook/types": "8.0.0", + "@storybook/types": "8.0.4", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", @@ -7094,17 +7071,17 @@ } }, "node_modules/@storybook/react": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.0.0.tgz", - "integrity": "sha512-Nl3jEd8Ezd2aDXfoQAgfGmwna3U6NOLMcCRSYOR63bH4/u16MnnDE8ACy+mH/+yWGEoxNjqcWUJiDk2h4C07LA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.0.4.tgz", + "integrity": "sha512-p4wQSJIhG48UD2fZ6tFDT9zaqrVnvZxjV18+VjSi3dez/pDoEMJ3SWZWcmeDenKwvvk+SPdRH7k5mUHW1Rh0xg==", "dev": true, "dependencies": { - "@storybook/client-logger": "8.0.0", - "@storybook/docs-tools": "8.0.0", + "@storybook/client-logger": "8.0.4", + "@storybook/docs-tools": "8.0.4", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "8.0.0", - "@storybook/react-dom-shim": "8.0.0", - "@storybook/types": "8.0.0", + "@storybook/preview-api": "8.0.4", + "@storybook/react-dom-shim": "8.0.4", + "@storybook/types": "8.0.4", "@types/escodegen": "^0.0.6", "@types/estree": "^0.0.51", "@types/node": "^18.0.0", @@ -7159,9 +7136,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.0.0.tgz", - "integrity": "sha512-bpT/7XyO9T+mWJojAblnuScum/UI65UksaL1jKYySMpBuW4jTJVE1YPzN1oe9A4me8HQCPeDw4Rg+ZB91H5sKA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.0.4.tgz", + "integrity": "sha512-H8bci23e+G40WsdYPuPrhAjCeeXypXuAV6mTVvLHGKH+Yb+3wiB1weaXrot/TgzPbkDNybuhTI3Qm48FPLt0bw==", "dev": true, "funding": { "type": "opencollective", @@ -7173,9 +7150,9 @@ } }, "node_modules/@storybook/react/node_modules/@types/node": { - "version": "18.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.24.tgz", - "integrity": "sha512-eghAz3gnbQbvnHqB+mgB2ZR3aH6RhdEmHGS48BnV75KceQPHqabkxKI0BbUSsqhqy2Ddhc2xD/VAR9ySZd57Lw==", + "version": "18.19.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", + "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -7215,12 +7192,12 @@ "dev": true }, "node_modules/@storybook/router": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-8.0.0.tgz", - "integrity": "sha512-NPV4pb7TBOepPymHBLDmnwPcH4SnrNsD3LiHaVoaE4xaKMZBse2slWxeWM6IGb6Ynoy6pQpsHhAnt+rTjlcv9w==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-8.0.4.tgz", + "integrity": "sha512-hlR80QvmLBflAqMeGcgtDuSe6TJlzdizwEAkBLE1lDvFI6tvvEyAliCAXBpIDdOZTe0u/zeeJkOUXKSx33caoQ==", "dev": true, "dependencies": { - "@storybook/client-logger": "8.0.0", + "@storybook/client-logger": "8.0.4", "memoizerific": "^1.11.3", "qs": "^6.10.0" }, @@ -7230,14 +7207,14 @@ } }, "node_modules/@storybook/telemetry": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-8.0.0.tgz", - "integrity": "sha512-TpPswQYvhpFCyojWdKKOL7JMUhGqAr6Rqc/KQx4KEkHZat4K1yP7idNqpEIo/gavhlS1xVCNyp+WtzBI7d1PFw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-8.0.4.tgz", + "integrity": "sha512-Q3ITY6J46R/TrrPRIU1fs3WNs69ExpTJZ9UlB8087qOUyV90Ex33SYk3i10xVWRczxCmyC1V58Xuht6nxz7mNQ==", "dev": true, "dependencies": { - "@storybook/client-logger": "8.0.0", - "@storybook/core-common": "8.0.0", - "@storybook/csf-tools": "8.0.0", + "@storybook/client-logger": "8.0.4", + "@storybook/core-common": "8.0.4", + "@storybook/csf-tools": "8.0.4", "chalk": "^4.1.0", "detect-package-manager": "^2.0.1", "fetch-retry": "^5.0.2", @@ -7301,6 +7278,29 @@ "node": ">=8" } }, + "node_modules/@storybook/test": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.0.4.tgz", + "integrity": "sha512-/uvE8Rtu7tIcuyQBUzKq7uuDCsjmADI18BApLdwo/qthmN8ERDxRSz0Ngj2gvBMQFv99At8ESi/xh6oFGu3rWg==", + "dev": true, + "dependencies": { + "@storybook/client-logger": "8.0.4", + "@storybook/core-events": "8.0.4", + "@storybook/instrumenter": "8.0.4", + "@storybook/preview-api": "8.0.4", + "@testing-library/dom": "^9.3.4", + "@testing-library/jest-dom": "^6.4.2", + "@testing-library/user-event": "^14.5.2", + "@vitest/expect": "1.3.1", + "@vitest/spy": "^1.3.1", + "chai": "^4.4.1", + "util": "^0.12.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, "node_modules/@storybook/testing-library": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.2.tgz", @@ -7313,13 +7313,13 @@ } }, "node_modules/@storybook/theming": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.0.0.tgz", - "integrity": "sha512-Yu6ybemarPN3RBdsljtvpEVNqnqG1YxDLOmkzl1MFtJ1uA5Zd5mTMjc37iD0WDvLOk8mc1HmEqB5+fDrX0U4Vw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.0.4.tgz", + "integrity": "sha512-NxtTU2wMC0lj375ejoT3Npdcqwv6NeUpLaJl6EZCMXSR41ve9WG4suUNWQ63olhqKxirjzAz0IL7ggH7c3hPvA==", "dev": true, "dependencies": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@storybook/client-logger": "8.0.0", + "@storybook/client-logger": "8.0.4", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" }, @@ -7341,12 +7341,12 @@ } }, "node_modules/@storybook/types": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-8.0.0.tgz", - "integrity": "sha512-6nJipdgoAkVFk2JpRPCm9vb/Yuak2lmdZRv9qzl8cNRttlbOESVlzbmhgxCmWV0OYUaMeYge9L8NWhJ14LKbzw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-8.0.4.tgz", + "integrity": "sha512-OO7QY+qZFCYkItDUBACtIV32p75O7sNziAiyS1V2Oxgo7Ln7fwZwr3mJcA1ruBed6ZcrW3c87k7Xs40T2zAWcg==", "dev": true, "dependencies": { - "@storybook/channels": "8.0.0", + "@storybook/channels": "8.0.4", "@types/express": "^4.7.0", "file-system-cache": "2.3.0" }, @@ -7364,11 +7364,11 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.1.3.tgz", - "integrity": "sha512-YCzcbF/Ws/uZ0q3Z6fagH+JVhx4JLvbSflgldMgLsuvB8aXjZLLb3HvrEVxY480F9wFlBiXlvQxOyXb5ENPrNA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.2.0.tgz", + "integrity": "sha512-OEdMByf2hEfDa6XDbGlZN8qO6bTjlNKqjM3im9JG+u3mCL8jALy0T/67oDI001raUUPh1Bdmfn4ZvPOV5knpcg==", "dependencies": { - "@tanstack/virtual-core": "3.1.3" + "@tanstack/virtual-core": "3.2.0" }, "funding": { "type": "github", @@ -7380,9 +7380,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.1.3.tgz", - "integrity": "sha512-Y5B4EYyv1j9V8LzeAoOVeTg0LI7Fo5InYKgAjkY1Pu9GjtUwX/EKxNcU7ng3sKr99WEf+bPTcktAeybyMOYo+g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.2.0.tgz", + "integrity": "sha512-P5XgYoAw/vfW65byBbJQCw+cagdXDT/qH6wmABiLt4v4YBT2q2vqCOhihe+D1Nt325F/S/0Tkv6C5z0Lv+VBQQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -7459,6 +7459,106 @@ "node": ">=8" } }, + "node_modules/@testing-library/jest-dom": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz", + "integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.3.2", + "@babel/runtime": "^7.9.2", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/bun": "latest", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/bun": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@testing-library/user-event": { "version": "14.5.2", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", @@ -7651,9 +7751,9 @@ "dev": true }, "node_modules/@types/eslint": { - "version": "8.56.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz", - "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==", + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", "dev": true, "dependencies": { "@types/estree": "*", @@ -7727,30 +7827,6 @@ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "dev": true }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -7770,9 +7846,9 @@ "dev": true }, "node_modules/@types/mdx": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.11.tgz", - "integrity": "sha512-HM5bwOaIQJIQbAYfax35HCKxx7a3KrK3nBtIqJgSOitivTD1y3oW9P3rxY9RkXYPUk7y/AjAohfHKmFpGE79zw==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.12.tgz", + "integrity": "sha512-H9VZ9YqE+H28FQVchC83RCs5xQ2J7mAAv6qdDEaWmXEVl3OpdH+xfrSUzQ1lp7U7oSTRZ0RvW08ASPJsYBi7Cw==", "dev": true }, "node_modules/@types/mime": { @@ -7782,9 +7858,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz", - "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", "dependencies": { "undici-types": "~5.26.4" } @@ -7817,14 +7893,14 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.11", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/qs": { - "version": "6.9.12", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz", - "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==", + "version": "6.9.14", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", + "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", "dev": true }, "node_modules/@types/range-parser": { @@ -7834,9 +7910,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.66", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.66.tgz", - "integrity": "sha512-OYTmMI4UigXeFMF/j4uv0lBBEbongSgptPrHBxqME44h9+yNov+oL6Z3ocJKo0WyXR84sQUNeyIp9MRfckvZpg==", + "version": "18.2.70", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.70.tgz", + "integrity": "sha512-hjlM2hho2vqklPhopNkXkdkeq6Lv8WSZTpr7956zY+3WS5cfYUewtCzsJLsbW5dEv3lfSeQ4W14ZFeKC437JRQ==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -7914,21 +7990,6 @@ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, - "node_modules/@types/yargs": { - "version": "16.0.9", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", - "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, "node_modules/@typescript-eslint/parser": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", @@ -8308,6 +8369,138 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vitest/expect": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz", + "integrity": "sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.3.1", + "@vitest/utils": "1.3.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/spy": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz", + "integrity": "sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.1.tgz", + "integrity": "sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/expect/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/expect/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@vitest/spy": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", + "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", @@ -8766,9 +8959,9 @@ "dev": true }, "node_modules/aria-hidden": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz", - "integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", "dependencies": { "tslib": "^2.0.0" }, @@ -8808,15 +9001,16 @@ "dev": true }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -8844,35 +9038,17 @@ "node": ">=0.10.0" } }, - "node_modules/array.prototype.filter": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", - "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array.prototype.findlast": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.4.tgz", - "integrity": "sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", + "es-abstract": "^1.23.2", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" }, "engines": { @@ -8883,15 +9059,16 @@ } }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", - "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", + "es-abstract": "^1.23.2", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" }, "engines": { @@ -9014,6 +9191,15 @@ "util": "^0.12.5" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ast-types": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", @@ -9045,9 +9231,9 @@ "dev": true }, "node_modules/autoprefixer": { - "version": "10.4.18", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz", - "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", "dev": true, "funding": [ { @@ -9065,7 +9251,7 @@ ], "dependencies": { "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001591", + "caniuse-lite": "^1.0.30001599", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -9341,57 +9527,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", - "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0", - "core-js-compat": "^3.34.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", + "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "@babel/helper-define-polyfill-provider": "^0.6.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -9403,9 +9557,9 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bare-events": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.1.tgz", - "integrity": "sha512-9GYPpsPFvrWBkelIhOhTWtkeZxVxZOdb3VnFTCzlOo3OjvmTvzLoZFUT8kNFACx0vJej6QPney1Cf9BvzCNE/A==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", + "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", "dev": true, "optional": true }, @@ -9927,9 +10081,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001597", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", - "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==", + "version": "1.0.30001600", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", + "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", "funding": [ { "type": "opencollective", @@ -9954,6 +10108,24 @@ "node": ">=4" } }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -9967,6 +10139,18 @@ "node": ">=4" } }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -10104,9 +10288,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", + "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", "dev": true, "dependencies": { "string-width": "^4.2.0" @@ -10440,9 +10624,10 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -10543,12 +10728,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", - "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", "dev": true, "dependencies": { - "browserslist": "^4.22.3" + "browserslist": "^4.23.0" }, "funding": { "type": "opencollective", @@ -10556,9 +10741,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.0.tgz", - "integrity": "sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==", + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.1.tgz", + "integrity": "sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA==", "dev": true, "hasInstallScript": true, "funding": { @@ -10788,6 +10973,12 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -11029,6 +11220,18 @@ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-equal": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", @@ -11270,9 +11473,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "dev": true, "engines": { "node": ">=8" @@ -11314,6 +11517,15 @@ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -11557,9 +11769,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.708", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.708.tgz", - "integrity": "sha512-iWgEEvREL4GTXXHKohhh33+6Y8XkPI5eHihDmm8zUk5Zo7HICEW+wI/j5kJ2tbuNUCXJ/sNXa03ajW635DiJXA==", + "version": "1.4.715", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.715.tgz", + "integrity": "sha512-XzWNH4ZSa9BwVUQSDorPWAUQ5WGuYz7zJUNpNif40zFCiCl20t8zgylmreNmn26h5kiyw2lg7RfTmeMBsDklqg==", "dev": true }, "node_modules/elliptic": { @@ -11697,9 +11909,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.0.tgz", - "integrity": "sha512-vmuE7Uoevk2xkwu5Gwa7RfJk/ebVV6xRv7KuZNbUglmJHhWPMbLL20ztreVpBbdxBZijETx3Aml3NssX4SFMvQ==", + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", + "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -11707,10 +11919,11 @@ "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.0", + "data-view-byte-length": "^1.0.1", "data-view-byte-offset": "^1.0.0", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", @@ -11721,7 +11934,7 @@ "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "hasown": "^2.0.1", + "hasown": "^2.0.2", "internal-slot": "^1.0.7", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", @@ -11736,17 +11949,17 @@ "object-keys": "^1.1.1", "object.assign": "^4.1.5", "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.0", + "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", "string.prototype.trimstart": "^1.0.7", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", "typed-array-length": "^1.0.5", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -11755,12 +11968,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -11828,11 +12035,23 @@ } }, "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.2.tgz", + "integrity": "sha512-7nOqkomXZEaxUDJw21XZNtRk739QvrPSoZoRtbsEfcii00vdzZUh6zh1CQwHhrib8MdEtJfv5rJiGeb4KuV/vw==", "dev": true }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", @@ -12038,12 +12257,12 @@ } }, "node_modules/eslint-config-next": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.3.tgz", - "integrity": "sha512-sUCpWlGuHpEhI0pIT0UtdSLJk5Z8E2DYinPTwsBiWaSYQomchdl0i60pjynY48+oXvtyWMQ7oE+G3m49yrfacg==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.4.tgz", + "integrity": "sha512-cihIahbhYAWwXJwZkAaRPpUi5t9aOi/HdfWXOjZeUOqNWXHD8X22kd1KG58Dc3MVaRx3HoR/oMGk2ltcrqDn8g==", "dev": true, "dependencies": { - "@next/eslint-plugin-next": "14.1.3", + "@next/eslint-plugin-next": "14.1.4", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", @@ -12555,6 +12774,21 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/estree-walker/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -12639,9 +12873,9 @@ } }, "node_modules/express": { - "version": "4.18.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", - "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, "dependencies": { "accepts": "~1.3.8", @@ -12649,7 +12883,7 @@ "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -13410,6 +13644,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -13558,18 +13801,18 @@ } }, "node_modules/giget": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.1.tgz", - "integrity": "sha512-4VG22mopWtIeHwogGSy1FViXVo0YT+m6BrqZfz0JJFwbSsePsCdOzdLIIli5BtMp7Xe8f/o2OmBpQX2NBOC24g==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz", + "integrity": "sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==", "dev": true, "dependencies": { - "citty": "^0.1.5", + "citty": "^0.1.6", "consola": "^3.2.3", - "defu": "^6.1.3", - "node-fetch-native": "^1.6.1", - "nypm": "^0.3.3", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.3", + "nypm": "^0.3.8", "ohash": "^1.1.3", - "pathe": "^1.1.1", + "pathe": "^1.1.2", "tar": "^6.2.0" }, "bin": { @@ -14914,19 +15157,6 @@ "node": ">=8" } }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -15504,6 +15734,15 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -15585,9 +15824,9 @@ } }, "node_modules/material-symbols": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/material-symbols/-/material-symbols-0.17.0.tgz", - "integrity": "sha512-CwDddz58cIH/svt8/wjAegQTp9bfNNIkIPjkkr0MAmA1oMlmUkG+C2ss2/yR22mlDzUX4DnXIq5MrgcpKTXoyA==" + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/material-symbols/-/material-symbols-0.17.1.tgz", + "integrity": "sha512-1kJan8t3U3Fmuu/YPu2MVsL/ODSja71o+J7ODROQfMaCzzal0izY4SATafEKgXUXU+jL0zIiBQdyzsno7vXBvA==" }, "node_modules/md5.js": { "version": "1.3.5", @@ -15964,11 +16203,11 @@ "dev": true }, "node_modules/next": { - "version": "14.1.3", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.3.tgz", - "integrity": "sha512-oexgMV2MapI0UIWiXKkixF8J8ORxpy64OuJ/J9oVUmIthXOUCcuVEZX+dtpgq7wIfIqtBwQsKEDXejcjTsan9g==", + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.4.tgz", + "integrity": "sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ==", "dependencies": { - "@next/env": "14.1.3", + "@next/env": "14.1.4", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -15983,15 +16222,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.3", - "@next/swc-darwin-x64": "14.1.3", - "@next/swc-linux-arm64-gnu": "14.1.3", - "@next/swc-linux-arm64-musl": "14.1.3", - "@next/swc-linux-x64-gnu": "14.1.3", - "@next/swc-linux-x64-musl": "14.1.3", - "@next/swc-win32-arm64-msvc": "14.1.3", - "@next/swc-win32-ia32-msvc": "14.1.3", - "@next/swc-win32-x64-msvc": "14.1.3" + "@next/swc-darwin-arm64": "14.1.4", + "@next/swc-darwin-x64": "14.1.4", + "@next/swc-linux-arm64-gnu": "14.1.4", + "@next/swc-linux-arm64-musl": "14.1.4", + "@next/swc-linux-x64-gnu": "14.1.4", + "@next/swc-linux-x64-musl": "14.1.4", + "@next/swc-win32-arm64-msvc": "14.1.4", + "@next/swc-win32-ia32-msvc": "14.1.4", + "@next/swc-win32-x64-msvc": "14.1.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -16035,6 +16274,14 @@ } } }, + "node_modules/next-auth/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/next-auth/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -16170,9 +16417,9 @@ } }, "node_modules/node-fetch-native": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.2.tgz", - "integrity": "sha512-69mtXOFZ6hSkYiXAVB5SqaRvrbITC/NPyqv7yuu/qw0nmgPyYbIMYYNIDhNtwPrzk0ptrimrLz/hhjvm4w5Z+w==", + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", + "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==", "dev": true }, "node_modules/node-polyfill-webpack-plugin": { @@ -16509,28 +16756,29 @@ } }, "node_modules/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -16540,40 +16788,45 @@ } }, "node_modules/object.groupby": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", - "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, "dependencies": { - "array.prototype.filter": "^1.0.3", - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0" + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/object.hasown": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", - "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "dev": true, "dependencies": { - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -17015,6 +17268,15 @@ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", @@ -17141,9 +17403,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "funding": [ { "type": "opencollective", @@ -17161,7 +17423,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -17433,9 +17695,9 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/preact": { - "version": "10.19.6", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.6.tgz", - "integrity": "sha512-gympg+T2Z1fG1unB8NH29yHJwnEaCH37Z32diPDku316OTnRPeMbiRV9kTrfZpocXjdfnWuFUl/Mj4BHaf6gnw==", + "version": "10.20.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.20.1.tgz", + "integrity": "sha512-JIFjgFg9B2qnOoGiYMVBtrcFxHqn+dNXbq76bVmcaHYJFYR4lW67AOcXgAYQQTDYXDOg/kTZrKPNCdRgJ2UJmw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -18101,9 +18363,9 @@ } }, "node_modules/react-smooth": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.0.tgz", - "integrity": "sha512-2NMXOBY1uVUQx1jBeENGA497HK20y6CPGYL1ZnJLeoQ8rrc3UfmOM82sRxtzpcoCkUMy4CS0RGylfuVhuFjBgg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", + "integrity": "sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==", "dependencies": { "fast-equals": "^5.0.1", "prop-types": "^15.8.1", @@ -18378,17 +18640,42 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redent/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reflect.getprototypeof": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", - "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0", - "get-intrinsic": "^1.2.3", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", "which-builtin-type": "^1.1.3" }, @@ -19214,9 +19501,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "engines": { "node": ">=0.10.0" } @@ -19321,12 +19608,12 @@ "dev": true }, "node_modules/storybook": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.0.0.tgz", - "integrity": "sha512-ZWfFoKLsZ7kYgqcVgDeUZpN89cxzEx2Mw9afhfMNzwSnjhx9xRdzdNvK7DY1nDnfborxzBhkvwYf/oxRbifKuw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.0.4.tgz", + "integrity": "sha512-FUr3Uc2dSAQ80jINH5fSXz7zD7Ncn08OthROjwRtHAH+jMf4wxyZ+RhF3heFy9xLot2/HXOLIWyHyzZZMtGhxg==", "dev": true, "dependencies": { - "@storybook/cli": "8.0.0" + "@storybook/cli": "8.0.4" }, "bin": { "sb": "index.js", @@ -19493,34 +19780,41 @@ } }, "node_modules/string.prototype.matchall": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", - "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "regexp.prototype.flags": "^1.5.0", - "set-function-name": "^2.0.0", - "side-channel": "^1.0.4" + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -19530,28 +19824,31 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19900,9 +20197,9 @@ } }, "node_modules/tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, "dependencies": { "chownr": "^2.0.0", @@ -20207,6 +20504,15 @@ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -20435,6 +20741,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -20514,9 +20829,9 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", - "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "dependencies": { "call-bind": "^1.0.7", @@ -20534,9 +20849,9 @@ } }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -20547,9 +20862,9 @@ } }, "node_modules/ufo": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.1.tgz", - "integrity": "sha512-HGyF79+/qZ4soRvM+nHERR2pJ3VXDZ/8sL1uLahdgEDf580NkgiWOxLk33FetExqOWp352JZRsgXbG/4MaGOSg==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", "dev": true }, "node_modules/uglify-js": { @@ -20807,9 +21122,9 @@ "dev": true }, "node_modules/use-callback-ref": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.1.tgz", - "integrity": "sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", "dependencies": { "tslib": "^2.0.0" }, @@ -21016,26 +21331,26 @@ "dev": true }, "node_modules/webpack": { - "version": "5.90.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", - "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", + "version": "5.91.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", + "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", "acorn-import-assertions": "^1.9.0", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.16.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", @@ -21043,7 +21358,7 @@ "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -21063,9 +21378,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz", - "integrity": "sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.2.tgz", + "integrity": "sha512-Wu+EHmX326YPYUpQLKmKbTyZZJIB8/n6R09pTmB03kJmnMsVPTo9COzHZFr01txwaCAuZvfBJE4ZCHRcKs5JaQ==", "dev": true, "dependencies": { "colorette": "^2.0.10", diff --git a/ui/package.json b/ui/package.json index 440ce34084..0ea0b49cea 100644 --- a/ui/package.json +++ b/ui/package.json @@ -33,16 +33,16 @@ "@radix-ui/react-toggle-group": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", "@tremor/react": "^3.14.1", - "@types/node": "^20.11.28", - "@types/react": "^18.2.66", + "@types/node": "^20.11.30", + "@types/react": "^18.2.70", "@types/react-dom": "^18.2.22", "classnames": "^2.5.1", "long": "^5.2.3", "lucide-react": "^0.354.0", - "material-symbols": "^0.17.0", + "material-symbols": "^0.17.1", "moment": "^2.30.1", "moment-timezone": "^0.5.45", - "next": "^14.1.3", + "next": "^14.1.4", "next-auth": "^4.24.7", "prop-types": "^15.8.1", "protobufjs": "^7.2.6", @@ -57,31 +57,31 @@ "zod": "^3.22.4" }, "devDependencies": { - "@storybook/addon-essentials": "^8.0.0", - "@storybook/addon-interactions": "^8.0.0", - "@storybook/addon-links": "^8.0.0", + "@storybook/addon-essentials": "^8.0.4", + "@storybook/addon-interactions": "^8.0.4", + "@storybook/addon-links": "^8.0.4", "@storybook/addon-styling": "^1.3.7", "@storybook/blocks": "^8.0.0", - "@storybook/nextjs": "^8.0.0", + "@storybook/nextjs": "^8.0.4", "@storybook/react": "^8.0.0", "@storybook/testing-library": "^0.2.2", - "autoprefixer": "^10.4.18", + "autoprefixer": "^10.4.19", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", - "eslint-config-next": "^14.1.3", + "eslint-config-next": "^14.1.4", "eslint-config-prettier": "^9.1.0", "eslint-plugin-storybook": "^0.8.0", "gh-pages": "^6.1.1", "less": "^4.2.0", - "postcss": "^8.4.35", + "postcss": "^8.4.38", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", "prisma": "^5.11.0", - "storybook": "^8.0.0", + "storybook": "^8.0.4", "string-width": "^7.1.0", "tailwindcss": "^3.4.1", "tailwindcss-animate": "^1.0.7", - "typescript": "^5.4.2", - "webpack": "^5.90.3" + "typescript": "^5.4.3", + "webpack": "^5.91.0" } } From 8f0c29ace582ddb39843b2b29e2741a4adedc9ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Mar 2024 16:57:15 +0000 Subject: [PATCH 08/48] lua: add json preload (#1527) --- flow/go.mod | 1 + flow/go.sum | 2 ++ flow/pua/peerdb.go | 2 ++ 3 files changed, 5 insertions(+) diff --git a/flow/go.mod b/flow/go.mod index d97bd4fe74..9af5d00ef5 100644 --- a/flow/go.mod +++ b/flow/go.mod @@ -14,6 +14,7 @@ require ( github.com/PeerDB-io/glua64 v1.0.1 github.com/PeerDB-io/gluabit32 v1.0.2 github.com/PeerDB-io/gluaflatbuffers v1.0.1 + github.com/PeerDB-io/gluajson v1.0.0 github.com/aws/aws-sdk-go-v2 v1.26.0 github.com/aws/aws-sdk-go-v2/config v1.27.9 github.com/aws/aws-sdk-go-v2/credentials v1.17.9 diff --git a/flow/go.sum b/flow/go.sum index 3553892eb1..83e6849a74 100644 --- a/flow/go.sum +++ b/flow/go.sum @@ -64,6 +64,8 @@ github.com/PeerDB-io/gluabit32 v1.0.2 h1:AGI1Z7dwDVotakpuOOuyTX4/QGi5HUYsipL/Vfo github.com/PeerDB-io/gluabit32 v1.0.2/go.mod h1:tsHStN1XG5uGVWEA8d/RameB7el3PE3sVkvk8e3+FJg= github.com/PeerDB-io/gluaflatbuffers v1.0.1 h1:Oxlv0VlMYoQ05Q5n/k4hXAsvtDnuVNC99JBUf927br0= github.com/PeerDB-io/gluaflatbuffers v1.0.1/go.mod h1:unZOM4Mm2Sn+aAFuVjoJDZ2Dji7jlDWrt4Hvq79as2g= +github.com/PeerDB-io/gluajson v1.0.0 h1:+W3nZ2WNqyCDIjRM7XtFKZLoZeB6rvsiAE4Ci1jHmzQ= +github.com/PeerDB-io/gluajson v1.0.0/go.mod h1:arRzpblxlLiWfBAluxP9Xibf6J8UkUIfoY4FPHTsz4Q= github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= diff --git a/flow/pua/peerdb.go b/flow/pua/peerdb.go index 60a3d8687c..778cfd366e 100644 --- a/flow/pua/peerdb.go +++ b/flow/pua/peerdb.go @@ -13,6 +13,7 @@ import ( "github.com/PeerDB-io/glua64" "github.com/PeerDB-io/gluabit32" + "github.com/PeerDB-io/gluajson" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/peerdbenv" @@ -38,6 +39,7 @@ func RegisterTypes(ls *lua.LState) { loaders.RawSetInt(2, ls.NewFunction(LoadPeerdbScript)) ls.PreloadModule("bit32", gluabit32.Loader) + ls.PreloadModule("json", gluajson.Loader) mt := LuaRecord.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaRecordIndex)) From e1dbd98d38da1fe2bf0c94464a00f561e7ff9870 Mon Sep 17 00:00:00 2001 From: Amogh Bharadwaj Date: Mon, 25 Mar 2024 22:55:40 +0530 Subject: [PATCH 09/48] UI: Initial load status for initial load tab (#1522) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds user-facing information denoting the current phase of snapshot flow - fetching, syncing or consolidate. Screenshot 2024-03-21 at 11 15 49 PM Screenshot 2024-03-21 at 11 16 39 PM Functionally tested. Fixes #1511 --- flow/activities/flowable.go | 11 +- flow/cmd/mirror_status.go | 28 +- .../connectors/utils/monitoring/monitoring.go | 4 +- .../migrations/V24__qrep_runs_destination.sql | 11 + protos/route.proto | 3 + ui/app/mirrors/[mirrorId]/cdc.tsx | 228 +------------- ui/app/mirrors/[mirrorId]/configValues.ts | 8 +- ui/app/mirrors/[mirrorId]/snapshot.tsx | 285 ++++++++++++++++++ .../mirrors/status/qrep/[mirrorId]/page.tsx | 1 - .../qrep/[mirrorId]/qrepStatusTable.tsx | 12 +- 10 files changed, 340 insertions(+), 251 deletions(-) create mode 100644 nexus/catalog/migrations/V24__qrep_runs_destination.sql create mode 100644 ui/app/mirrors/[mirrorId]/snapshot.tsx diff --git a/flow/activities/flowable.go b/flow/activities/flowable.go index 1f7601b719..22f11f80c9 100644 --- a/flow/activities/flowable.go +++ b/flow/activities/flowable.go @@ -545,6 +545,16 @@ func (a *FlowableActivity) GetQRepPartitions(ctx context.Context, runUUID string, ) (*protos.QRepParitionResult, error) { ctx = context.WithValue(ctx, shared.FlowNameKey, config.FlowJobName) + err := monitoring.InitializeQRepRun( + ctx, + a.CatalogPool, + config, + runUUID, + nil, + ) + if err != nil { + return nil, err + } srcConn, err := connectors.GetQRepPullConnector(ctx, config.SourcePeer) if err != nil { return nil, fmt.Errorf("failed to get qrep pull connector: %w", err) @@ -555,7 +565,6 @@ func (a *FlowableActivity) GetQRepPartitions(ctx context.Context, return "getting partitions for job" }) defer shutdown() - partitions, err := srcConn.GetQRepPartitions(ctx, config, last) if err != nil { a.Alerter.LogFlowError(ctx, config.FlowJobName, err) diff --git a/flow/cmd/mirror_status.go b/flow/cmd/mirror_status.go index f72cd5311e..172a5e9833 100644 --- a/flow/cmd/mirror_status.go +++ b/flow/cmd/mirror_status.go @@ -121,21 +121,24 @@ func (h *FlowRequestHandler) cloneTableSummary( ) ([]*protos.CloneTableSummary, error) { q := ` SELECT - qp.flow_name, + distinct qr.flow_name, qr.config_proto, - MIN(qp.start_time) AS StartTime, - COUNT(*) AS NumPartitionsTotal, + qr.start_time AS StartTime, + qr.fetch_complete as FetchCompleted, + qr.consolidate_complete as ConsolidateCompleted, + COUNT(CASE WHEN qp.flow_name IS NOT NULL THEN 1 END) AS NumPartitionsTotal, COUNT(CASE WHEN qp.end_time IS NOT NULL THEN 1 END) AS NumPartitionsCompleted, SUM(qp.rows_in_partition) FILTER (WHERE qp.end_time IS NOT NULL) AS NumRowsSynced, AVG(EXTRACT(EPOCH FROM (qp.end_time - qp.start_time)) * 1000) FILTER (WHERE qp.end_time IS NOT NULL) AS AvgTimePerPartitionMs FROM peerdb_stats.qrep_partitions qp - JOIN peerdb_stats.qrep_runs qr ON qp.flow_name = qr.flow_name - WHERE qp.flow_name ILIKE $1 - GROUP BY qp.flow_name, qr.config_proto; + RIGHT JOIN peerdb_stats.qrep_runs qr ON qp.flow_name = qr.flow_name + WHERE qr.flow_name ILIKE $1 + GROUP BY qr.flow_name, qr.config_proto, qr.start_time, qr.fetch_complete, qr.consolidate_complete; ` - var flowName pgtype.Text var configBytes []byte + var fetchCompleted pgtype.Bool + var consolidateCompleted pgtype.Bool var startTime pgtype.Timestamp var numPartitionsTotal pgtype.Int8 var numPartitionsCompleted pgtype.Int8 @@ -157,6 +160,8 @@ func (h *FlowRequestHandler) cloneTableSummary( &flowName, &configBytes, &startTime, + &fetchCompleted, + &consolidateCompleted, &numPartitionsTotal, &numPartitionsCompleted, &numRowsSynced, @@ -174,6 +179,14 @@ func (h *FlowRequestHandler) cloneTableSummary( res.StartTime = timestamppb.New(startTime.Time) } + if fetchCompleted.Valid { + res.FetchCompleted = fetchCompleted.Bool + } + + if consolidateCompleted.Valid { + res.ConsolidateCompleted = consolidateCompleted.Bool + } + if numPartitionsTotal.Valid { res.NumPartitionsTotal = int32(numPartitionsTotal.Int64) } @@ -197,6 +210,7 @@ func (h *FlowRequestHandler) cloneTableSummary( return nil, fmt.Errorf("unable to unmarshal config: %w", err) } res.TableName = config.DestinationTableIdentifier + res.SourceTable = config.WatermarkTable } cloneStatuses = append(cloneStatuses, &res) diff --git a/flow/connectors/utils/monitoring/monitoring.go b/flow/connectors/utils/monitoring/monitoring.go index ebb73a0b60..97fe08616c 100644 --- a/flow/connectors/utils/monitoring/monitoring.go +++ b/flow/connectors/utils/monitoring/monitoring.go @@ -176,7 +176,7 @@ func InitializeQRepRun( func UpdateStartTimeForQRepRun(ctx context.Context, pool *pgxpool.Pool, runUUID string) error { _, err := pool.Exec(ctx, - "UPDATE peerdb_stats.qrep_runs SET start_time=$1 WHERE run_uuid=$2", + "UPDATE peerdb_stats.qrep_runs SET start_time=$1, fetch_complete=true WHERE run_uuid=$2", time.Now(), runUUID) if err != nil { return fmt.Errorf("error while updating start time for run_uuid %s in qrep_runs: %w", runUUID, err) @@ -187,7 +187,7 @@ func UpdateStartTimeForQRepRun(ctx context.Context, pool *pgxpool.Pool, runUUID func UpdateEndTimeForQRepRun(ctx context.Context, pool *pgxpool.Pool, runUUID string) error { _, err := pool.Exec(ctx, - "UPDATE peerdb_stats.qrep_runs SET end_time=$1 WHERE run_uuid=$2", + "UPDATE peerdb_stats.qrep_runs SET end_time=$1, consolidate_complete=true WHERE run_uuid=$2", time.Now(), runUUID) if err != nil { return fmt.Errorf("error while updating end time for run_uuid %s in qrep_runs: %w", runUUID, err) diff --git a/nexus/catalog/migrations/V24__qrep_runs_destination.sql b/nexus/catalog/migrations/V24__qrep_runs_destination.sql new file mode 100644 index 0000000000..19c5c69264 --- /dev/null +++ b/nexus/catalog/migrations/V24__qrep_runs_destination.sql @@ -0,0 +1,11 @@ +ALTER TABLE peerdb_stats.qrep_runs +ADD COLUMN destination_table TEXT; + +ALTER TABLE peerdb_stats.qrep_runs +ADD COLUMN source_table TEXT; + +ALTER TABLE peerdb_stats.qrep_runs +ADD COLUMN fetch_complete BOOLEAN DEFAULT FALSE; + +ALTER TABLE peerdb_stats.qrep_runs +ADD COLUMN consolidate_complete BOOLEAN DEFAULT FALSE; diff --git a/protos/route.proto b/protos/route.proto index 4d2c601fad..180576fc1b 100644 --- a/protos/route.proto +++ b/protos/route.proto @@ -181,6 +181,9 @@ message CloneTableSummary { int64 num_rows_synced = 5; int64 avg_time_per_partition_ms = 6; string flow_job_name = 7; + string source_table = 8; + bool fetch_completed = 9; + bool consolidate_completed = 10; } message SnapshotStatus { diff --git a/ui/app/mirrors/[mirrorId]/cdc.tsx b/ui/app/mirrors/[mirrorId]/cdc.tsx index 61ebc03434..ca407f8c90 100644 --- a/ui/app/mirrors/[mirrorId]/cdc.tsx +++ b/ui/app/mirrors/[mirrorId]/cdc.tsx @@ -1,235 +1,13 @@ 'use client'; import { SyncStatusRow } from '@/app/dto/MirrorsDTO'; -import SelectTheme from '@/app/styles/select'; -import TimeLabel from '@/components/TimeComponent'; -import { - CloneTableSummary, - MirrorStatusResponse, - SnapshotStatus, -} from '@/grpc_generated/route'; -import { Button } from '@/lib/Button'; -import { Icon } from '@/lib/Icon'; +import { MirrorStatusResponse } from '@/grpc_generated/route'; import { Label } from '@/lib/Label'; -import { ProgressBar } from '@/lib/ProgressBar'; import { ProgressCircle } from '@/lib/ProgressCircle'; -import { SearchField } from '@/lib/SearchField'; -import { Table, TableCell, TableRow } from '@/lib/Table'; import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@tremor/react'; -import moment, { Duration, Moment } from 'moment'; -import Link from 'next/link'; -import { useEffect, useMemo, useState } from 'react'; -import ReactSelect from 'react-select'; +import { useEffect, useState } from 'react'; import { useLocalStorage } from 'usehooks-ts'; import CdcDetails from './cdcDetails'; - -class TableCloneSummary { - cloneStartTime: Moment | null = null; - cloneTableSummary: CloneTableSummary; - avgTimePerPartition: Duration | null = null; - - constructor(clone: CloneTableSummary) { - this.cloneTableSummary = clone; - if (clone.startTime) { - this.cloneStartTime = moment(clone.startTime); - } - if (clone.avgTimePerPartitionMs) { - this.avgTimePerPartition = moment.duration( - clone.avgTimePerPartitionMs, - 'ms' - ); - } - } - - getPartitionProgressPercentage(): number { - if (this.cloneTableSummary.numPartitionsTotal === 0) { - return 0; - } - return ( - (this.cloneTableSummary.numPartitionsCompleted / - this.cloneTableSummary.numPartitionsTotal) * - 100 - ); - } -} - -function summarizeTableClone(clone: CloneTableSummary): TableCloneSummary { - return new TableCloneSummary(clone); -} - -type SnapshotStatusProps = { - status: SnapshotStatus; -}; - -const ROWS_PER_PAGE = 5; -export const SnapshotStatusTable = ({ status }: SnapshotStatusProps) => { - const [sortField, setSortField] = useState< - 'cloneStartTime' | 'avgTimePerPartition' - >('cloneStartTime'); - const allRows = status.clones.map(summarizeTableClone); - const [currentPage, setCurrentPage] = useState(1); - const totalPages = Math.ceil(allRows.length / ROWS_PER_PAGE); - const [searchQuery, setSearchQuery] = useState(''); - const [sortDir, setSortDir] = useState<'asc' | 'dsc'>('dsc'); - const displayedRows = useMemo(() => { - const shownRows = allRows.filter((row: TableCloneSummary) => - row.cloneTableSummary.tableName - ?.toLowerCase() - .includes(searchQuery.toLowerCase()) - ); - shownRows.sort((a, b) => { - const aValue = a[sortField]; - const bValue = b[sortField]; - if (aValue === null || bValue === null) { - return 0; - } - - if (aValue < bValue) { - return sortDir === 'dsc' ? 1 : -1; - } else if (aValue > bValue) { - return sortDir === 'dsc' ? -1 : 1; - } else { - return 0; - } - }); - - const startRow = (currentPage - 1) * ROWS_PER_PAGE; - const endRow = startRow + ROWS_PER_PAGE; - return shownRows.length > ROWS_PER_PAGE - ? shownRows.slice(startRow, endRow) - : shownRows; - }, [allRows, currentPage, searchQuery, sortField, sortDir]); - - const handlePrevPage = () => { - if (currentPage > 1) { - setCurrentPage(currentPage - 1); - } - }; - - const handleNextPage = () => { - if (currentPage < totalPages) { - setCurrentPage(currentPage + 1); - } - }; - - const sortOptions = [ - { value: 'cloneStartTime', label: 'Start Time' }, - { value: 'avgTimePerPartition', label: 'Time Per Partition' }, - ]; - return ( -
- Initial Copy} - toolbar={{ - left: ( -
- - - - -
- { - const sortVal = - (val?.value as - | 'cloneStartTime' - | 'avgTimePerPartition') ?? 'cloneStartTime'; - setSortField(sortVal); - }} - value={{ - value: sortField, - label: sortOptions.find((opt) => opt.value === sortField) - ?.label, - }} - defaultValue={{ - value: 'cloneStartTime', - label: 'Start Time', - }} - theme={SelectTheme} - /> -
- - -
- ), - right: ( - ) => - setSearchQuery(e.target.value) - } - /> - ), - }} - header={ - - Table Identifier - Start Time - Progress Partitions - Num Rows Synced - Avg Time Per Partition - - } - > - {displayedRows.map((clone, index) => ( - - - - - - - - - - {clone.cloneTableSummary.numPartitionsCompleted} /{' '} - {clone.cloneTableSummary.numPartitionsTotal} - - {clone.cloneTableSummary.numRowsSynced} - - - - - ))} -
-
- ); -}; +import { SnapshotStatusTable } from './snapshot'; type CDCMirrorStatusProps = { status: MirrorStatusResponse; diff --git a/ui/app/mirrors/[mirrorId]/configValues.ts b/ui/app/mirrors/[mirrorId]/configValues.ts index 55b5a4c0b3..6cf2d9f941 100644 --- a/ui/app/mirrors/[mirrorId]/configValues.ts +++ b/ui/app/mirrors/[mirrorId]/configValues.ts @@ -19,12 +19,12 @@ const MirrorValues = (mirrorConfig: FlowConnectionConfigs | undefined) => { label: 'Snapshot Parallel Tables', }, { - value: mirrorConfig?.cdcStagingPath || 'Local', - label: 'CDC Staging Path', + value: `${mirrorConfig?.softDelete}`, + label: 'Soft Delete', }, { - value: mirrorConfig?.snapshotStagingPath || 'Local', - label: 'Snapshot Staging Path', + value: mirrorConfig?.cdcStagingPath || 'Local', + label: 'CDC Staging Path', }, { value: mirrorConfig?.snapshotStagingPath || 'Local', diff --git a/ui/app/mirrors/[mirrorId]/snapshot.tsx b/ui/app/mirrors/[mirrorId]/snapshot.tsx new file mode 100644 index 0000000000..d0a3e69e1a --- /dev/null +++ b/ui/app/mirrors/[mirrorId]/snapshot.tsx @@ -0,0 +1,285 @@ +'use client'; +import SelectTheme from '@/app/styles/select'; +import TimeLabel from '@/components/TimeComponent'; +import { CloneTableSummary, SnapshotStatus } from '@/grpc_generated/route'; +import { Badge } from '@/lib/Badge/Badge'; +import { Button } from '@/lib/Button'; +import { Icon } from '@/lib/Icon'; +import { Label } from '@/lib/Label'; +import { ProgressBar } from '@/lib/ProgressBar'; +import { SearchField } from '@/lib/SearchField'; +import { Table, TableCell, TableRow } from '@/lib/Table'; +import moment, { Duration, Moment } from 'moment'; +import Link from 'next/link'; +import { useMemo, useState } from 'react'; +import ReactSelect from 'react-select'; + +export class TableCloneSummary { + cloneStartTime: Moment | null = null; + cloneTableSummary: CloneTableSummary; + avgTimePerPartition: Duration | null = null; + constructor(clone: CloneTableSummary) { + this.cloneTableSummary = clone; + if (clone.startTime) { + this.cloneStartTime = moment(clone.startTime); + } + if (clone.avgTimePerPartitionMs) { + this.avgTimePerPartition = moment.duration( + clone.avgTimePerPartitionMs, + 'ms' + ); + } + } + + getPartitionProgressPercentage(): number { + if (this.cloneTableSummary.numPartitionsTotal === 0) { + return 0; + } + return ( + (this.cloneTableSummary.numPartitionsCompleted / + this.cloneTableSummary.numPartitionsTotal) * + 100 + ); + } +} + +export function summarizeTableClone( + clone: CloneTableSummary +): TableCloneSummary { + return new TableCloneSummary(clone); +} + +type SnapshotStatusProps = { + status: SnapshotStatus; +}; + +const ROWS_PER_PAGE = 5; +export const SnapshotStatusTable = ({ status }: SnapshotStatusProps) => { + const [sortField, setSortField] = useState< + 'cloneStartTime' | 'avgTimePerPartition' + >('cloneStartTime'); + const allRows = status.clones.map(summarizeTableClone); + const [currentPage, setCurrentPage] = useState(1); + const totalPages = Math.ceil(allRows.length / ROWS_PER_PAGE); + const [searchQuery, setSearchQuery] = useState(''); + const [sortDir, setSortDir] = useState<'asc' | 'dsc'>('dsc'); + const displayedRows = useMemo(() => { + const shownRows = allRows.filter((row: TableCloneSummary) => + row.cloneTableSummary.tableName + ?.toLowerCase() + .includes(searchQuery.toLowerCase()) + ); + shownRows.sort((a, b) => { + const aValue = a[sortField]; + const bValue = b[sortField]; + if (aValue === null || bValue === null) { + return 0; + } + + if (aValue < bValue) { + return sortDir === 'dsc' ? 1 : -1; + } else if (aValue > bValue) { + return sortDir === 'dsc' ? -1 : 1; + } else { + return 0; + } + }); + + const startRow = (currentPage - 1) * ROWS_PER_PAGE; + const endRow = startRow + ROWS_PER_PAGE; + return shownRows.length > ROWS_PER_PAGE + ? shownRows.slice(startRow, endRow) + : shownRows; + }, [allRows, currentPage, searchQuery, sortField, sortDir]); + + const handlePrevPage = () => { + if (currentPage > 1) { + setCurrentPage(currentPage - 1); + } + }; + + const handleNextPage = () => { + if (currentPage < totalPages) { + setCurrentPage(currentPage + 1); + } + }; + + const getStatus = (clone: CloneTableSummary) => { + if (clone.consolidateCompleted) { + return ( + + +
Done
+
+ ); + } + if (!clone.fetchCompleted) { + return ( + + +
Fetching
+
+ ); + } + + if (clone.numPartitionsCompleted == clone.numPartitionsTotal) { + return ( + + +
Consolidating
+
+ ); + } + + return ( + + +
Syncing
+
+ ); + }; + + const sortOptions = [ + { value: 'cloneStartTime', label: 'Start Time' }, + { value: 'avgTimePerPartition', label: 'Time Per Partition' }, + ]; + return ( +
+ Initial Copy} + toolbar={{ + left: ( +
+ + + + +
+ { + const sortVal = + (val?.value as + | 'cloneStartTime' + | 'avgTimePerPartition') ?? 'cloneStartTime'; + setSortField(sortVal); + }} + value={{ + value: sortField, + label: sortOptions.find((opt) => opt.value === sortField) + ?.label, + }} + defaultValue={{ + value: 'cloneStartTime', + label: 'Start Time', + }} + theme={SelectTheme} + /> +
+ + +
+ ), + right: ( + ) => + setSearchQuery(e.target.value) + } + /> + ), + }} + header={ + + Table Identifier + Status + Sync Start + Progress Partitions + Num Rows Processed + Avg Time Per Partition + + } + > + {displayedRows.map((clone, index) => ( + + + + + {getStatus(clone.cloneTableSummary)} + + {clone.cloneStartTime ? ( + + ) : ( + 'N/A' + )} + + {clone.cloneTableSummary.fetchCompleted ? ( + + + {clone.cloneTableSummary.numPartitionsCompleted} /{' '} + {clone.cloneTableSummary.numPartitionsTotal} + + ) : ( + N/A + )} + + {clone.cloneTableSummary.fetchCompleted + ? clone.cloneTableSummary.numRowsSynced + : 0} + + {clone.cloneTableSummary.fetchCompleted ? ( + + + + ) : ( + N/A + )} + + ))} +
+
+ ); +}; diff --git a/ui/app/mirrors/status/qrep/[mirrorId]/page.tsx b/ui/app/mirrors/status/qrep/[mirrorId]/page.tsx index eeaec8cb77..c50d016633 100644 --- a/ui/app/mirrors/status/qrep/[mirrorId]/page.tsx +++ b/ui/app/mirrors/status/qrep/[mirrorId]/page.tsx @@ -30,7 +30,6 @@ export default async function QRepMirrorStatus({ const partitions = runs.map((run) => { let ret: QRepPartitionStatus = { partitionId: run.partition_uuid, - runUuid: run.run_uuid, startTime: run.start_time, endTime: run.end_time, pulledRows: run.rows_in_partition, diff --git a/ui/app/mirrors/status/qrep/[mirrorId]/qrepStatusTable.tsx b/ui/app/mirrors/status/qrep/[mirrorId]/qrepStatusTable.tsx index d0a01a1468..e0a7577c33 100644 --- a/ui/app/mirrors/status/qrep/[mirrorId]/qrepStatusTable.tsx +++ b/ui/app/mirrors/status/qrep/[mirrorId]/qrepStatusTable.tsx @@ -13,7 +13,6 @@ import ReactSelect from 'react-select'; export type QRepPartitionStatus = { partitionId: string; - runUuid: string; status: string; startTime: Date | null; endTime: Date | null; @@ -31,7 +30,6 @@ function TimeOrProgressBar({ time }: { time: Date | null }) { function RowPerPartition({ partitionId, - runUuid, status, startTime, endTime, @@ -52,11 +50,6 @@ function RowPerPartition({ {partitionId} - - - @@ -81,10 +74,7 @@ type QRepStatusTableProps = { partitions: QRepPartitionStatus[]; }; -export default function QRepStatusTable({ - flowJobName, - partitions, -}: QRepStatusTableProps) { +export default function QRepStatusTable({ partitions }: QRepStatusTableProps) { const ROWS_PER_PAGE = 10; const [currentPage, setCurrentPage] = useState(1); const totalPages = Math.ceil(partitions.length / ROWS_PER_PAGE); From a735989a398ca0a4d4e56f4d28e181cab6b2dfed Mon Sep 17 00:00:00 2001 From: Amogh Bharadwaj Date: Tue, 26 Mar 2024 02:00:09 +0530 Subject: [PATCH 10/48] UI CDC: Show inserts, updates and deletes (#1525) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds two visual elements to the CDC page in UI: - Inserts, updates and deletes in total - Inserts, updates and deletes for each table Screenshot 2024-03-22 at 9 33 17 PM Update: The I/U/D graph is now visible on click expand: Screenshot 2024-03-25 at 8 31 38 PM Fixes #1520 --- flow/connectors/bigquery/bigquery.go | 2 +- flow/connectors/bigquery/qrep_avro_sync.go | 2 +- flow/connectors/clickhouse/cdc.go | 2 +- flow/connectors/eventhub/eventhub.go | 2 +- flow/connectors/kafka/kafka.go | 6 +- flow/connectors/postgres/postgres.go | 8 +- flow/connectors/pubsub/pubsub.go | 6 +- flow/connectors/s3/s3.go | 2 +- flow/connectors/snowflake/snowflake.go | 2 +- .../connectors/utils/monitoring/monitoring.go | 15 ++-- flow/connectors/utils/stream.go | 26 ++++-- flow/model/model.go | 30 ++++++- flow/model/qrecord_stream.go | 10 ++- .../migrations/V25__recordtypecounts.sql | 4 + ui/app/dto/MirrorsDTO.ts | 8 ++ ui/app/mirrors/[mirrorId]/cdcGraph.tsx | 2 +- ui/app/mirrors/[mirrorId]/rowsDisplay.tsx | 56 +++++++++++++ ui/app/mirrors/[mirrorId]/syncStatus.tsx | 71 ++++++++++++---- ui/app/mirrors/[mirrorId]/syncStatusTable.tsx | 3 +- ui/app/mirrors/[mirrorId]/tableStats.tsx | 75 +++++++++++++++++ ui/prisma/schema.prisma | 80 +++++++++++++++++-- 21 files changed, 355 insertions(+), 57 deletions(-) create mode 100644 nexus/catalog/migrations/V25__recordtypecounts.sql create mode 100644 ui/app/mirrors/[mirrorId]/rowsDisplay.tsx create mode 100644 ui/app/mirrors/[mirrorId]/tableStats.tsx diff --git a/flow/connectors/bigquery/bigquery.go b/flow/connectors/bigquery/bigquery.go index 7dc1b3b77e..bad43d61cb 100644 --- a/flow/connectors/bigquery/bigquery.go +++ b/flow/connectors/bigquery/bigquery.go @@ -370,7 +370,7 @@ func (c *BigQueryConnector) syncRecordsViaAvro( rawTableName string, syncBatchID int64, ) (*model.SyncResponse, error) { - tableNameRowsMapping := make(map[string]uint32) + tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, syncBatchID) streamRes, err := utils.RecordsToRawTableStream(streamReq) if err != nil { diff --git a/flow/connectors/bigquery/qrep_avro_sync.go b/flow/connectors/bigquery/qrep_avro_sync.go index a4b4023d1b..2586436ab6 100644 --- a/flow/connectors/bigquery/qrep_avro_sync.go +++ b/flow/connectors/bigquery/qrep_avro_sync.go @@ -45,7 +45,7 @@ func (s *QRepAvroSyncMethod) SyncRecords( dstTableMetadata *bigquery.TableMetadata, syncBatchID int64, stream *model.QRecordStream, - tableNameRowsMapping map[string]uint32, + tableNameRowsMapping map[string]*model.RecordTypeCounts, ) (*model.SyncResponse, error) { activity.RecordHeartbeat(ctx, fmt.Sprintf("Flow job %s: Obtaining Avro schema"+ diff --git a/flow/connectors/clickhouse/cdc.go b/flow/connectors/clickhouse/cdc.go index 12d1402d87..aabd51c11f 100644 --- a/flow/connectors/clickhouse/cdc.go +++ b/flow/connectors/clickhouse/cdc.go @@ -80,7 +80,7 @@ func (c *ClickhouseConnector) syncRecordsViaAvro( rawTableIdentifier string, syncBatchID int64, ) (*model.SyncResponse, error) { - tableNameRowsMapping := make(map[string]uint32) + tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, syncBatchID) streamRes, err := utils.RecordsToRawTableStream(streamReq) if err != nil { diff --git a/flow/connectors/eventhub/eventhub.go b/flow/connectors/eventhub/eventhub.go index 7d75298777..a1ab93f391 100644 --- a/flow/connectors/eventhub/eventhub.go +++ b/flow/connectors/eventhub/eventhub.go @@ -215,7 +215,7 @@ func (c *EventHubConnector) SyncRecords(ctx context.Context, req *model.SyncReco CurrentSyncBatchID: req.SyncBatchID, LastSyncedCheckpointID: lastCheckpoint, NumRecordsSynced: int64(numRecords), - TableNameRowsMapping: make(map[string]uint32), + TableNameRowsMapping: make(map[string]*model.RecordTypeCounts), TableSchemaDeltas: req.Records.SchemaDeltas, }, nil } diff --git a/flow/connectors/kafka/kafka.go b/flow/connectors/kafka/kafka.go index cefe73ca4b..6d878f7bfd 100644 --- a/flow/connectors/kafka/kafka.go +++ b/flow/connectors/kafka/kafka.go @@ -12,7 +12,7 @@ import ( "github.com/twmb/franz-go/pkg/sasl/plain" "github.com/twmb/franz-go/pkg/sasl/scram" "github.com/twmb/franz-go/plugin/kslog" - "github.com/yuin/gopher-lua" + lua "github.com/yuin/gopher-lua" "go.temporal.io/sdk/log" metadataStore "github.com/PeerDB-io/peer-flow/connectors/external_metadata" @@ -191,7 +191,7 @@ func (c *KafkaConnector) SyncRecords(ctx context.Context, req *model.SyncRecords } numRecords := int64(0) - tableNameRowsMapping := make(map[string]uint32) + tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) ls, err := utils.LoadScript(wgCtx, req.Script, func(ls *lua.LState) int { top := ls.GetTop() @@ -236,7 +236,7 @@ func (c *KafkaConnector) SyncRecords(ctx context.Context, req *model.SyncRecords wg.Add(1) c.client.Produce(wgCtx, kr, produceCb) - tableNameRowsMapping[kr.Topic] += 1 + record.PopulateCountMap(tableNameRowsMapping) } } numRecords += 1 diff --git a/flow/connectors/postgres/postgres.go b/flow/connectors/postgres/postgres.go index 82cbd9dd6d..c89567a4e6 100644 --- a/flow/connectors/postgres/postgres.go +++ b/flow/connectors/postgres/postgres.go @@ -405,8 +405,7 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco c.logger.Info(fmt.Sprintf("pushing records to Postgres table %s via COPY", rawTableIdentifier)) numRecords := int64(0) - tableNameRowsMapping := make(map[string]uint32) - + tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReadFunc := func() ([]any, error) { record, ok := <-req.Records.GetRecords() @@ -434,6 +433,7 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco req.SyncBatchID, "", } + case *model.UpdateRecord: newItemsJSON, err := typedRecord.NewItems.ToJSONWithOptions(&model.ToJSONOptions{ UnnestColumns: map[string]struct{}{}, @@ -460,6 +460,7 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco req.SyncBatchID, utils.KeysToString(typedRecord.UnchangedToastColumns), } + case *model.DeleteRecord: itemsJSON, err := typedRecord.Items.ToJSONWithOptions(&model.ToJSONOptions{ UnnestColumns: map[string]struct{}{}, @@ -479,12 +480,13 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco req.SyncBatchID, "", } + default: return nil, fmt.Errorf("unsupported record type for Postgres flow connector: %T", typedRecord) } + record.PopulateCountMap(tableNameRowsMapping) numRecords += 1 - tableNameRowsMapping[record.GetDestinationTableName()] += 1 return row, nil } } diff --git a/flow/connectors/pubsub/pubsub.go b/flow/connectors/pubsub/pubsub.go index 6b51bb246a..111c9815d9 100644 --- a/flow/connectors/pubsub/pubsub.go +++ b/flow/connectors/pubsub/pubsub.go @@ -7,7 +7,7 @@ import ( "sync" "cloud.google.com/go/pubsub" - "github.com/yuin/gopher-lua" + lua "github.com/yuin/gopher-lua" "go.temporal.io/sdk/log" metadataStore "github.com/PeerDB-io/peer-flow/connectors/external_metadata" @@ -135,7 +135,7 @@ func lvalueToPubSubMessage(ls *lua.LState, value lua.LValue) (string, *pubsub.Me func (c *PubSubConnector) SyncRecords(ctx context.Context, req *model.SyncRecordsRequest) (*model.SyncResponse, error) { numRecords := int64(0) - tableNameRowsMapping := make(map[string]uint32) + tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) ls, err := utils.LoadScript(ctx, req.Script, func(ls *lua.LState) int { top := ls.GetTop() @@ -221,7 +221,7 @@ func (c *PubSubConnector) SyncRecords(ctx context.Context, req *model.SyncRecord pubresult := topicClient.Publish(ctx, msg) wg.Add(1) publish <- pubresult - tableNameRowsMapping[topic] += 1 + record.PopulateCountMap(tableNameRowsMapping) } } numRecords += 1 diff --git a/flow/connectors/s3/s3.go b/flow/connectors/s3/s3.go index ddb6061b0d..7e95e00b43 100644 --- a/flow/connectors/s3/s3.go +++ b/flow/connectors/s3/s3.go @@ -153,7 +153,7 @@ func (c *S3Connector) SetLastOffset(ctx context.Context, jobName string, offset } func (c *S3Connector) SyncRecords(ctx context.Context, req *model.SyncRecordsRequest) (*model.SyncResponse, error) { - tableNameRowsMapping := make(map[string]uint32) + tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, req.SyncBatchID) streamRes, err := utils.RecordsToRawTableStream(streamReq) if err != nil { diff --git a/flow/connectors/snowflake/snowflake.go b/flow/connectors/snowflake/snowflake.go index f67fe59df0..1d9ed6fe58 100644 --- a/flow/connectors/snowflake/snowflake.go +++ b/flow/connectors/snowflake/snowflake.go @@ -447,7 +447,7 @@ func (c *SnowflakeConnector) syncRecordsViaAvro( rawTableIdentifier string, syncBatchID int64, ) (*model.SyncResponse, error) { - tableNameRowsMapping := make(map[string]uint32) + tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, syncBatchID) streamRes, err := utils.RecordsToRawTableStream(streamReq) if err != nil { diff --git a/flow/connectors/utils/monitoring/monitoring.go b/flow/connectors/utils/monitoring/monitoring.go index 97fe08616c..472cc1efed 100644 --- a/flow/connectors/utils/monitoring/monitoring.go +++ b/flow/connectors/utils/monitoring/monitoring.go @@ -14,6 +14,7 @@ import ( "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" + "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/shared" ) @@ -106,7 +107,7 @@ func UpdateEndTimeForCDCBatch( } func AddCDCBatchTablesForFlow(ctx context.Context, pool *pgxpool.Pool, flowJobName string, - batchID int64, tableNameRowsMapping map[string]uint32, + batchID int64, tableNameRowsMapping map[string]*model.RecordTypeCounts, ) error { insertBatchTablesTx, err := pool.Begin(ctx) if err != nil { @@ -121,11 +122,15 @@ func AddCDCBatchTablesForFlow(ctx context.Context, pool *pgxpool.Pool, flowJobNa } }() - for destinationTableName, numRows := range tableNameRowsMapping { + for destinationTableName, rowCounts := range tableNameRowsMapping { + numRows := rowCounts.InsertCount + rowCounts.UpdateCount + rowCounts.DeleteCount _, err = insertBatchTablesTx.Exec(ctx, - `INSERT INTO peerdb_stats.cdc_batch_table(flow_name,batch_id,destination_table_name,num_rows) - VALUES($1,$2,$3,$4) ON CONFLICT DO NOTHING`, - flowJobName, batchID, destinationTableName, numRows) + `INSERT INTO peerdb_stats.cdc_batch_table + (flow_name,batch_id,destination_table_name,num_rows, + insert_count,update_count,delete_count) + VALUES($1,$2,$3,$4,$5,$6,$7) ON CONFLICT DO NOTHING`, + flowJobName, batchID, destinationTableName, numRows, + rowCounts.InsertCount, rowCounts.UpdateCount, rowCounts.DeleteCount) if err != nil { return fmt.Errorf("error while inserting statistics into cdc_batch_table: %w", err) } diff --git a/flow/connectors/utils/stream.go b/flow/connectors/utils/stream.go index 898acd03b5..c2d146c062 100644 --- a/flow/connectors/utils/stream.go +++ b/flow/connectors/utils/stream.go @@ -6,6 +6,7 @@ import ( "github.com/google/uuid" + "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/qvalue" ) @@ -62,19 +63,19 @@ func RecordsToRawTableStream(req *model.RecordsToStreamRequest) (*model.RecordsT go func() { for record := range req.GetRecords() { - qRecordOrError := recordToQRecordOrError(req.TableMapping, req.BatchID, record) + record.PopulateCountMap(req.TableMapping) + qRecordOrError := recordToQRecordOrError(req.BatchID, record) recordStream.Records <- qRecordOrError } close(recordStream.Records) }() - return &model.RecordsToStreamResponse{ Stream: recordStream, }, nil } -func recordToQRecordOrError(tableMapping map[string]uint32, batchID int64, record model.Record) model.QRecordOrError { +func recordToQRecordOrError(batchID int64, record model.Record) model.QRecordOrError { var entries [8]qvalue.QValue switch typedRecord := record.(type) { case *model.InsertRecord: @@ -102,7 +103,7 @@ func recordToQRecordOrError(tableMapping map[string]uint32, batchID int64, recor Kind: qvalue.QValueKindString, Value: "", } - tableMapping[typedRecord.DestinationTableName] += 1 + case *model.UpdateRecord: newItemsJSON, err := typedRecord.NewItems.ToJSON() if err != nil { @@ -133,7 +134,7 @@ func recordToQRecordOrError(tableMapping map[string]uint32, batchID int64, recor Kind: qvalue.QValueKindString, Value: KeysToString(typedRecord.UnchangedToastColumns), } - tableMapping[typedRecord.DestinationTableName] += 1 + case *model.DeleteRecord: itemsJSON, err := typedRecord.Items.ToJSON() if err != nil { @@ -158,7 +159,7 @@ func recordToQRecordOrError(tableMapping map[string]uint32, batchID int64, recor Kind: qvalue.QValueKindString, Value: KeysToString(typedRecord.UnchangedToastColumns), } - tableMapping[typedRecord.DestinationTableName] += 1 + default: return model.QRecordOrError{ Err: fmt.Errorf("unknown record type: %T", typedRecord), @@ -186,3 +187,16 @@ func recordToQRecordOrError(tableMapping map[string]uint32, batchID int64, recor Record: entries[:], } } + +func InitialiseTableRowsMap(tableMaps []*protos.TableMapping) map[string]*model.RecordTypeCounts { + tableNameRowsMapping := make(map[string]*model.RecordTypeCounts, len(tableMaps)) + for _, mapping := range tableMaps { + tableNameRowsMapping[mapping.DestinationTableIdentifier] = &model.RecordTypeCounts{ + InsertCount: 0, + UpdateCount: 0, + DeleteCount: 0, + } + } + + return tableNameRowsMapping +} diff --git a/flow/model/model.go b/flow/model/model.go index 1561e66544..10fe95d5a7 100644 --- a/flow/model/model.go +++ b/flow/model/model.go @@ -54,6 +54,7 @@ type Record interface { GetSourceTableName() string // get columns and values for the record GetItems() *RecordItems + PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) } type ToJSONOptions struct { @@ -114,6 +115,13 @@ func (r *InsertRecord) GetItems() *RecordItems { return r.Items } +func (r *InsertRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { + recordCount, ok := mapOfCounts[r.DestinationTableName] + if ok { + recordCount.InsertCount++ + } +} + type UpdateRecord struct { BaseRecord // Name of the source table @@ -140,6 +148,13 @@ func (r *UpdateRecord) GetItems() *RecordItems { return r.NewItems } +func (r *UpdateRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { + recordCount, ok := mapOfCounts[r.DestinationTableName] + if ok { + recordCount.UpdateCount++ + } +} + type DeleteRecord struct { BaseRecord // Name of the source table @@ -164,6 +179,13 @@ func (r *DeleteRecord) GetItems() *RecordItems { return r.Items } +func (r *DeleteRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { + recordCount, ok := mapOfCounts[r.DestinationTableName] + if ok { + recordCount.DeleteCount++ + } +} + type TableWithPkey struct { TableName string // SHA256 hash of the primary key columns @@ -196,11 +218,10 @@ type SyncResponse struct { // LastSyncedCheckpointID is the last ID that was synced. LastSyncedCheckpointID int64 // NumRecordsSynced is the number of records that were synced. - NumRecordsSynced int64 - // CurrentSyncBatchID is the ID of the currently synced batch. + NumRecordsSynced int64 CurrentSyncBatchID int64 // TableNameRowsMapping tells how many records need to be synced to each destination table. - TableNameRowsMapping map[string]uint32 + TableNameRowsMapping map[string]*RecordTypeCounts // to be carried to parent workflow TableSchemaDeltas []*protos.TableSchemaDelta } @@ -236,4 +257,7 @@ func (r *RelationRecord) GetItems() *RecordItems { return nil } +func (r *RelationRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { +} + type RelationMessageMapping map[uint32]*pglogrepl.RelationMessage diff --git a/flow/model/qrecord_stream.go b/flow/model/qrecord_stream.go index e3fa4ee74e..97546ce247 100644 --- a/flow/model/qrecord_stream.go +++ b/flow/model/qrecord_stream.go @@ -6,6 +6,12 @@ import ( "github.com/PeerDB-io/peer-flow/model/qvalue" ) +type RecordTypeCounts struct { + InsertCount int + UpdateCount int + DeleteCount int +} + type QRecordOrError struct { Record []qvalue.QValue Err error @@ -25,13 +31,13 @@ type QRecordStream struct { type RecordsToStreamRequest struct { records <-chan Record - TableMapping map[string]uint32 + TableMapping map[string]*RecordTypeCounts BatchID int64 } func NewRecordsToStreamRequest( records <-chan Record, - tableMapping map[string]uint32, + tableMapping map[string]*RecordTypeCounts, batchID int64, ) *RecordsToStreamRequest { return &RecordsToStreamRequest{ diff --git a/nexus/catalog/migrations/V25__recordtypecounts.sql b/nexus/catalog/migrations/V25__recordtypecounts.sql new file mode 100644 index 0000000000..e7f7f18880 --- /dev/null +++ b/nexus/catalog/migrations/V25__recordtypecounts.sql @@ -0,0 +1,4 @@ +ALTER TABLE peerdb_stats.cdc_batch_table +ADD COLUMN insert_count INTEGER, +ADD COLUMN update_count INTEGER, +ADD COLUMN delete_count INTEGER; diff --git a/ui/app/dto/MirrorsDTO.ts b/ui/app/dto/MirrorsDTO.ts index 9b3724902a..0fbb8b9009 100644 --- a/ui/app/dto/MirrorsDTO.ts +++ b/ui/app/dto/MirrorsDTO.ts @@ -35,3 +35,11 @@ export type SyncStatusRow = { endTime: Date | null; numRows: number; }; + +export type MirrorRowsData = { + destinationTableName: string; + insertCount: number; + updateCount: number; + deleteCount: number; + totalCount: number; +}; diff --git a/ui/app/mirrors/[mirrorId]/cdcGraph.tsx b/ui/app/mirrors/[mirrorId]/cdcGraph.tsx index c4b5a7c9cc..41c69b9161 100644 --- a/ui/app/mirrors/[mirrorId]/cdcGraph.tsx +++ b/ui/app/mirrors/[mirrorId]/cdcGraph.tsx @@ -38,7 +38,7 @@ function CdcGraph({ syncs }: { syncs: SyncStatusRow[] }) { />
- +
+ `${Intl.NumberFormat('us').format(number).toString()}`; + +const RowsDisplay = ({ + totalRowsData, +}: { + totalRowsData: { + total: Number; + inserts: number; + updates: number; + deletes: number; + }; +}) => { + const [show, setShow] = useState(false); + const rowsHero = [ + { name: 'Inserts', value: totalRowsData.inserts }, + { name: 'Updates', value: totalRowsData.updates, color: 'yellow' }, + { name: 'Deletes', value: totalRowsData.deletes, color: 'rose' }, + ]; + return ( +
+

+ Rows Synced +

+

+ {RowDataFormatter(totalRowsData.total.valueOf())} +

+ + {show && ( +
+ +
+ )} +
+ ); +}; + +export default RowsDisplay; diff --git a/ui/app/mirrors/[mirrorId]/syncStatus.tsx b/ui/app/mirrors/[mirrorId]/syncStatus.tsx index ba50ff67b8..98bdba35c3 100644 --- a/ui/app/mirrors/[mirrorId]/syncStatus.tsx +++ b/ui/app/mirrors/[mirrorId]/syncStatus.tsx @@ -1,17 +1,46 @@ -import { SyncStatusRow } from '@/app/dto/MirrorsDTO'; -import { Label } from '@/lib/Label'; +import { MirrorRowsData, SyncStatusRow } from '@/app/dto/MirrorsDTO'; +import prisma from '@/app/utils/prisma'; import CdcGraph from './cdcGraph'; +import RowsDisplay from './rowsDisplay'; import { SyncStatusTable } from './syncStatusTable'; +import TableStats from './tableStats'; -function numberWithCommas(x: Number): string { - return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); -} type SyncStatusProps = { flowJobName: string | undefined; rowsSynced: Number; rows: SyncStatusRow[]; }; +const GetTablesStats = async (flowName: string) => { + let tableSyncs = await prisma.cdc_batch_table.groupBy({ + _sum: { + insert_count: true, + update_count: true, + delete_count: true, + }, + by: ['destination_table_name'], + where: { + flow_name: flowName, + }, + }); + + const rowsData: MirrorRowsData[] = []; + tableSyncs.forEach((tableSync) => { + const inserts = tableSync._sum.insert_count ?? 0; + const updates = tableSync._sum.update_count ?? 0; + const deletes = tableSync._sum.delete_count ?? 0; + const total = inserts + updates + deletes; + rowsData.push({ + destinationTableName: tableSync.destination_table_name, + insertCount: inserts, + updateCount: updates, + deleteCount: deletes, + totalCount: total, + }); + }); + return rowsData; +}; + export default async function SyncStatus({ flowJobName, rowsSynced, @@ -21,23 +50,33 @@ export default async function SyncStatus({ return
Flow job name not provided!
; } + const tableSyncs = await GetTablesStats(flowJobName); + const inserts = tableSyncs.reduce( + (acc, tableData) => acc + tableData.insertCount, + 0 + ); + const updates = tableSyncs.reduce( + (acc, tableData) => acc + tableData.updateCount, + 0 + ); + const deletes = tableSyncs.reduce( + (acc, tableData) => acc + tableData.deleteCount, + 0 + ); + const totalRowsData = { + total: inserts + updates + deletes, + inserts, + updates, + deletes, + }; return (
-
-
- -
-
- -
-
- +
+
); } diff --git a/ui/app/mirrors/[mirrorId]/syncStatusTable.tsx b/ui/app/mirrors/[mirrorId]/syncStatusTable.tsx index 7d9a453b1c..a5fcdff3ed 100644 --- a/ui/app/mirrors/[mirrorId]/syncStatusTable.tsx +++ b/ui/app/mirrors/[mirrorId]/syncStatusTable.tsx @@ -12,6 +12,7 @@ import { Table, TableCell, TableRow } from '@/lib/Table'; import moment from 'moment'; import { useMemo, useState } from 'react'; import ReactSelect from 'react-select'; +import { RowDataFormatter } from './rowsDisplay'; type SyncStatusTableProps = { rows: SyncStatusRow[]; @@ -201,7 +202,7 @@ export const SyncStatusTable = ({ rows }: SyncStatusTableProps) => { endTime={row.endTime} /> - {row.numRows} + {RowDataFormatter(row.numRows)} ))} diff --git a/ui/app/mirrors/[mirrorId]/tableStats.tsx b/ui/app/mirrors/[mirrorId]/tableStats.tsx new file mode 100644 index 0000000000..21b4529c4c --- /dev/null +++ b/ui/app/mirrors/[mirrorId]/tableStats.tsx @@ -0,0 +1,75 @@ +'use client'; +import { MirrorRowsData } from '@/app/dto/MirrorsDTO'; +import { Label } from '@/lib/Label'; +import { SearchField } from '@/lib/SearchField/SearchField'; +import { Table, TableCell, TableRow } from '@/lib/Table'; +import { useMemo, useState } from 'react'; +import { RowDataFormatter } from './rowsDisplay'; + +const TableStats = ({ tableSyncs }: { tableSyncs: MirrorRowsData[] }) => { + const [searchQuery, setSearchQuery] = useState(''); + const tableDataToShow = useMemo(() => { + return tableSyncs.filter((tableSync) => + tableSync.destinationTableName + .toLowerCase() + .includes(searchQuery.toLowerCase()) + ); + }, [tableSyncs, searchQuery]); + + return ( +
+ +
+ ) => + setSearchQuery(e.target.value) + } + /> + ), + }} + header={ + + {['Table Name', 'Total', 'Inserts', 'Updates', 'Deletes'].map( + (heading, index) => ( + + + + ) + )} + + } + > + {tableDataToShow.map((tableSync) => { + return ( + + + + + {[ + tableSync.totalCount, + tableSync.insertCount, + tableSync.updateCount, + tableSync.deleteCount, + ].map((rowMetric, id) => { + return ( + + + + ); + })} + + ); + })} +
+
+
+ ); +}; + +export default TableStats; diff --git a/ui/prisma/schema.prisma b/ui/prisma/schema.prisma index 3337588e2b..a690445e36 100644 --- a/ui/prisma/schema.prisma +++ b/ui/prisma/schema.prisma @@ -71,6 +71,9 @@ model cdc_batch_table { num_rows BigInt metadata Json? id Int @id @default(autoincrement()) + insert_count Int? + update_count Int? + delete_count Int? cdc_flows cdc_flows @relation(fields: [flow_name], references: [flow_name], onDelete: Cascade, onUpdate: NoAction, map: "fk_cdc_batch_table_flow_name") @@index([flow_name, batch_id], map: "idx_cdc_batch_table_flow_name_batch_id") @@ -87,6 +90,9 @@ model cdc_batches { end_time DateTime? @db.Timestamp(6) metadata Json? id Int @id @default(autoincrement()) + insert_count Int @default(0) + update_count Int @default(0) + delete_count Int @default(0) cdc_flows cdc_flows @relation(fields: [flow_name], references: [flow_name], onDelete: Cascade, onUpdate: NoAction, map: "fk_cdc_batches_flow_name") @@index([batch_id], map: "idx_cdc_batches_batch_id") @@ -130,14 +136,16 @@ model qrep_partitions { } model qrep_runs { - flow_name String - run_uuid String - start_time DateTime? @db.Timestamp(6) - end_time DateTime? @db.Timestamp(6) - metadata Json? - config_proto Bytes? - id Int @id @default(autoincrement()) - qrep_partitions qrep_partitions[] + flow_name String + run_uuid String + start_time DateTime? @db.Timestamp(6) + end_time DateTime? @db.Timestamp(6) + metadata Json? + config_proto Bytes? + id Int @id @default(autoincrement()) + fetch_complete Boolean? @default(false) + consolidate_complete Boolean? @default(false) + qrep_partitions qrep_partitions[] @@unique([flow_name, run_uuid], map: "uq_qrep_runs_flow_run") @@index([flow_name], map: "idx_qrep_runs_flow_name", type: Hash) @@ -158,6 +166,7 @@ model peer_slot_size { wal_status String? @@index([slot_name], map: "index_slot_name") + @@index([updated_at], map: "index_slot_updated_at") @@schema("peerdb_stats") } @@ -177,6 +186,7 @@ model alerts_v1 { alert_level String @default("critical") alert_message String created_timestamp DateTime? @default(now()) @db.Timestamp(6) + alert_config_id BigInt? @@schema("peerdb_stats") } @@ -203,3 +213,57 @@ model schema_deltas_audit_log { @@schema("peerdb_stats") } + +model alerting_settings { + id Int @id(map: "alerting_settings_pkey1") @default(autoincrement()) + config_name String + config_value String + + @@schema("public") +} + +model dynamic_settings { + id Int @id(map: "alerting_settings_pkey") @default(autoincrement()) + config_name String @unique(map: "idx_alerting_settings_config_name") + config_value String + setting_description String? + needs_restart Boolean? + + @@schema("public") +} + +model metadata_last_sync_state { + job_name String @id + last_offset BigInt + updated_at DateTime @default(now()) @db.Timestamptz(6) + sync_batch_id BigInt + normalize_batch_id BigInt? + + @@schema("public") +} + +model metadata_qrep_partitions { + job_name String + partition_id String + sync_partition Json @db.Json + sync_start_time DateTime @db.Timestamptz(6) + sync_finish_time DateTime @default(now()) @db.Timestamptz(6) + + @@id([job_name, partition_id]) + @@schema("public") +} + +model scripts { + id Int @id @default(autoincrement()) + lang script_lang + name String @unique + source Bytes + + @@schema("public") +} + +enum script_lang { + lua + + @@schema("public") +} From c27afd6c884cc0262bc963ba5556b19706b7e508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 25 Mar 2024 20:50:27 +0000 Subject: [PATCH 11/48] Change QValue into an interface (#1528) Existing QValue was troublesome, an artifact of wanting tagged unions, but result was having to dispatch on tag & then dispatch again on type, not only in terms of perf, but in terms of what can be in Value: UUID could be string, [16]byte, or uuid.UUID This problem was not unique to UUID This isn't an attempt at a final QValue representation, long term I'd like to get rid of QValueKind altogether Not happy with duplication around time types, ideally we'd have 1 time type with a kind tag, maybe a QTime interface the types share --- flow/connectors/bigquery/bigquery.go | 4 +- flow/connectors/clickhouse/cdc.go | 4 +- flow/connectors/eventhub/eventhub.go | 2 +- flow/connectors/postgres/cdc.go | 49 +- flow/connectors/postgres/postgres.go | 16 +- .../postgres/qrep_query_executor.go | 29 +- .../postgres/qrep_query_executor_test.go | 40 +- flow/connectors/postgres/qrep_sql_sync.go | 18 +- flow/connectors/postgres/qvalue_convert.go | 178 +-- flow/connectors/s3/s3.go | 3 +- .../snowflake/avro_file_writer_test.go | 68 +- .../snowflake/qrep_avro_consolidate.go | 2 +- flow/connectors/snowflake/snowflake.go | 4 +- flow/connectors/sql/query_executor.go | 153 ++- .../utils/cdc_records/cdc_records_storage.go | 40 + .../cdc_records/cdc_records_storage_test.go | 15 +- flow/connectors/utils/stream.go | 87 +- flow/e2e/bigquery/bigquery_helper.go | 68 +- flow/e2e/bigquery/peer_flow_bq_test.go | 23 +- flow/e2e/snowflake/qrep_flow_sf_test.go | 2 +- flow/e2e/snowflake/snowflake_helper.go | 27 +- flow/e2eshared/e2eshared.go | 4 +- flow/hstore/hstore.go | 29 +- flow/model/conversion_avro.go | 4 +- flow/model/model.go | 4 +- flow/model/qrecord_batch.go | 233 ++-- flow/model/qrecord_stream.go | 4 - flow/model/qrecord_test.go | 16 +- flow/model/qvalue/avro_converter.go | 515 +++----- flow/model/qvalue/equals.go | 485 ++++++++ flow/model/qvalue/kind.go | 1 - flow/model/qvalue/qvalue.go | 1107 +++++++---------- flow/model/record_items.go | 165 ++- flow/pua/peerdb.go | 16 +- 34 files changed, 1720 insertions(+), 1695 deletions(-) create mode 100644 flow/model/qvalue/equals.go diff --git a/flow/connectors/bigquery/bigquery.go b/flow/connectors/bigquery/bigquery.go index bad43d61cb..e2f2f12659 100644 --- a/flow/connectors/bigquery/bigquery.go +++ b/flow/connectors/bigquery/bigquery.go @@ -372,7 +372,7 @@ func (c *BigQueryConnector) syncRecordsViaAvro( ) (*model.SyncResponse, error) { tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, syncBatchID) - streamRes, err := utils.RecordsToRawTableStream(streamReq) + stream, err := utils.RecordsToRawTableStream(streamReq) if err != nil { return nil, fmt.Errorf("failed to convert records to raw table stream: %w", err) } @@ -384,7 +384,7 @@ func (c *BigQueryConnector) syncRecordsViaAvro( } res, err := avroSync.SyncRecords(ctx, req, rawTableName, - rawTableMetadata, syncBatchID, streamRes.Stream, streamReq.TableMapping) + rawTableMetadata, syncBatchID, stream, streamReq.TableMapping) if err != nil { return nil, fmt.Errorf("failed to sync records via avro: %w", err) } diff --git a/flow/connectors/clickhouse/cdc.go b/flow/connectors/clickhouse/cdc.go index aabd51c11f..9b0911955b 100644 --- a/flow/connectors/clickhouse/cdc.go +++ b/flow/connectors/clickhouse/cdc.go @@ -82,7 +82,7 @@ func (c *ClickhouseConnector) syncRecordsViaAvro( ) (*model.SyncResponse, error) { tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, syncBatchID) - streamRes, err := utils.RecordsToRawTableStream(streamReq) + stream, err := utils.RecordsToRawTableStream(streamReq) if err != nil { return nil, fmt.Errorf("failed to convert records to raw table stream: %w", err) } @@ -98,7 +98,7 @@ func (c *ClickhouseConnector) syncRecordsViaAvro( return nil, err } - numRecords, err := avroSyncer.SyncRecords(ctx, destinationTableSchema, streamRes.Stream, req.FlowJobName) + numRecords, err := avroSyncer.SyncRecords(ctx, destinationTableSchema, stream, req.FlowJobName) if err != nil { return nil, err } diff --git a/flow/connectors/eventhub/eventhub.go b/flow/connectors/eventhub/eventhub.go index a1ab93f391..d58530da54 100644 --- a/flow/connectors/eventhub/eventhub.go +++ b/flow/connectors/eventhub/eventhub.go @@ -158,7 +158,7 @@ func (c *EventHubConnector) processBatch( // partition_column is the column in the table that is used to determine // the partition key for the eventhub. partitionColumn := destination.PartitionKeyColumn - partitionValue := record.GetItems().GetColumnValue(partitionColumn).Value + partitionValue := record.GetItems().GetColumnValue(partitionColumn).Value() var partitionKey string if partitionValue != nil { partitionKey = fmt.Sprint(partitionValue) diff --git a/flow/connectors/postgres/cdc.go b/flow/connectors/postgres/cdc.go index e5bad73d62..056eafcccc 100644 --- a/flow/connectors/postgres/cdc.go +++ b/flow/connectors/postgres/cdc.go @@ -607,7 +607,7 @@ func (p *PostgresCDCSource) convertTupleToMap( } switch col.DataType { case 'n': // null - val := qvalue.QValue{Kind: qvalue.QValueKindInvalid, Value: nil} + val := qvalue.QValueNull(qvalue.QValueKindInvalid) items.AddColumn(colName, val) case 't': // text /* bytea also appears here as a hex */ @@ -649,19 +649,28 @@ func (p *PostgresCDCSource) decodeColumnData(data []byte, dataType uint32, forma // but not representable by time.Time p.logger.Warn(fmt.Sprintf("Invalidated and hence nulled %s data: %s", dt.Name, string(data))) - return qvalue.QValue{}, nil + switch dt.Name { + case "time": + return qvalue.QValueNull(qvalue.QValueKindTime), nil + case "timetz": + return qvalue.QValueNull(qvalue.QValueKindTimeTZ), nil + case "timestamp": + return qvalue.QValueNull(qvalue.QValueKindTimestamp), nil + case "timestamptz": + return qvalue.QValueNull(qvalue.QValueKindTimestampTZ), nil + } } - return qvalue.QValue{}, err + return nil, err } retVal, err := p.parseFieldFromPostgresOID(dataType, parsedData) if err != nil { - return qvalue.QValue{}, err + return nil, err } return retVal, nil } else if dataType == uint32(oid.T_timetz) { // ugly TIMETZ workaround for CDC decoding. retVal, err := p.parseFieldFromPostgresOID(dataType, string(data)) if err != nil { - return qvalue.QValue{}, err + return nil, err } return retVal, nil } @@ -669,28 +678,26 @@ func (p *PostgresCDCSource) decodeColumnData(data []byte, dataType uint32, forma typeName, ok := p.customTypesMapping[dataType] if ok { customQKind := customTypeToQKind(typeName) - if customQKind == qvalue.QValueKindGeography || customQKind == qvalue.QValueKindGeometry { + switch customQKind { + case qvalue.QValueKindGeography, qvalue.QValueKindGeometry: wkt, err := geo.GeoValidate(string(data)) if err != nil { - return qvalue.QValue{ - Kind: customQKind, - Value: nil, - }, nil + return qvalue.QValueNull(customQKind), nil + } else if customQKind == qvalue.QValueKindGeography { + return qvalue.QValueGeography{Val: wkt}, nil } else { - return qvalue.QValue{ - Kind: customQKind, - Value: wkt, - }, nil + return qvalue.QValueGeometry{Val: wkt}, nil } - } else { - return qvalue.QValue{ - Kind: customQKind, - Value: string(data), - }, nil + case qvalue.QValueKindHStore: + return qvalue.QValueHStore{Val: string(data)}, nil + case qvalue.QValueKindString: + return qvalue.QValueString{Val: string(data)}, nil + default: + return nil, fmt.Errorf("unknown custom qkind: %s", customQKind) } } - return qvalue.QValue{Kind: qvalue.QValueKindString, Value: string(data)}, nil + return qvalue.QValueString{Val: string(data)}, nil } func (p *PostgresCDCSource) auditSchemaDelta(ctx context.Context, flowJobName string, rec *model.RelationRecord) error { @@ -795,7 +802,7 @@ func (p *PostgresCDCSource) recToTablePKey(req *model.PullRecordsRequest, if err != nil { return nil, fmt.Errorf("error getting pkey column value: %w", err) } - pkeyColsMerged = append(pkeyColsMerged, []byte(fmt.Sprint(pkeyColVal.Value))) + pkeyColsMerged = append(pkeyColsMerged, []byte(fmt.Sprint(pkeyColVal.Value()))) } return &model.TableWithPkey{ diff --git a/flow/connectors/postgres/postgres.go b/flow/connectors/postgres/postgres.go index c89567a4e6..57cd7e9d86 100644 --- a/flow/connectors/postgres/postgres.go +++ b/flow/connectors/postgres/postgres.go @@ -415,8 +415,8 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco var row []any switch typedRecord := record.(type) { case *model.InsertRecord: - itemsJSON, err := typedRecord.Items.ToJSONWithOptions(&model.ToJSONOptions{ - UnnestColumns: map[string]struct{}{}, + itemsJSON, err := typedRecord.Items.ToJSONWithOptions(model.ToJSONOptions{ + UnnestColumns: nil, HStoreAsJSON: false, }) if err != nil { @@ -435,15 +435,15 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco } case *model.UpdateRecord: - newItemsJSON, err := typedRecord.NewItems.ToJSONWithOptions(&model.ToJSONOptions{ - UnnestColumns: map[string]struct{}{}, + newItemsJSON, err := typedRecord.NewItems.ToJSONWithOptions(model.ToJSONOptions{ + UnnestColumns: nil, HStoreAsJSON: false, }) if err != nil { return nil, fmt.Errorf("failed to serialize update record new items to JSON: %w", err) } - oldItemsJSON, err := typedRecord.OldItems.ToJSONWithOptions(&model.ToJSONOptions{ - UnnestColumns: map[string]struct{}{}, + oldItemsJSON, err := typedRecord.OldItems.ToJSONWithOptions(model.ToJSONOptions{ + UnnestColumns: nil, HStoreAsJSON: false, }) if err != nil { @@ -462,8 +462,8 @@ func (c *PostgresConnector) SyncRecords(ctx context.Context, req *model.SyncReco } case *model.DeleteRecord: - itemsJSON, err := typedRecord.Items.ToJSONWithOptions(&model.ToJSONOptions{ - UnnestColumns: map[string]struct{}{}, + itemsJSON, err := typedRecord.Items.ToJSONWithOptions(model.ToJSONOptions{ + UnnestColumns: nil, HStoreAsJSON: false, }) if err != nil { diff --git a/flow/connectors/postgres/qrep_query_executor.go b/flow/connectors/postgres/qrep_query_executor.go index a4efdfc85b..f7fb9accbd 100644 --- a/flow/connectors/postgres/qrep_query_executor.go +++ b/flow/connectors/postgres/qrep_query_executor.go @@ -458,19 +458,26 @@ func (qe *QRepQueryExecutor) mapRowToQRecord( record[i] = tmp } else { customQKind := customTypeToQKind(typeName) - if customQKind == qvalue.QValueKindGeography || customQKind == qvalue.QValueKindGeometry { - wkbString, ok := values[i].(string) - wkt, err := geo.GeoValidate(wkbString) - if err != nil || !ok { - values[i] = nil - } else { - values[i] = wkt + if values[i] == nil { + record[i] = qvalue.QValueNull(customQKind) + } else { + switch customQKind { + case qvalue.QValueKindGeography, qvalue.QValueKindGeometry: + wkbString, ok := values[i].(string) + wkt, err := geo.GeoValidate(wkbString) + if err != nil || !ok { + record[i] = qvalue.QValueNull(qvalue.QValueKindGeography) + } else if customQKind == qvalue.QValueKindGeography { + record[i] = qvalue.QValueGeography{Val: wkt} + } else { + record[i] = qvalue.QValueGeometry{Val: wkt} + } + case qvalue.QValueKindHStore: + record[i] = qvalue.QValueHStore{Val: fmt.Sprint(values[i])} + case qvalue.QValueKindString: + record[i] = qvalue.QValueString{Val: fmt.Sprint(values[i])} } } - record[i] = qvalue.QValue{ - Kind: customQKind, - Value: values[i], - } } } diff --git a/flow/connectors/postgres/qrep_query_executor_test.go b/flow/connectors/postgres/qrep_query_executor_test.go index cdb37b0349..9a5ca02330 100644 --- a/flow/connectors/postgres/qrep_query_executor_test.go +++ b/flow/connectors/postgres/qrep_query_executor_test.go @@ -75,8 +75,8 @@ func TestExecuteAndProcessQuery(t *testing.T) { t.Fatalf("expected 1 record, got %v", len(batch.Records)) } - if batch.Records[0][1].Value != "testdata" { - t.Fatalf("expected 'testdata', got %v", batch.Records[0][0].Value) + if batch.Records[0][1].Value() != "testdata" { + t.Fatalf("expected 'testdata', got %v", batch.Records[0][0].Value()) } } @@ -189,52 +189,52 @@ func TestAllDataTypes(t *testing.T) { record := batch.Records[0] expectedBool := true - if record[0].Value.(bool) != expectedBool { - t.Fatalf("expected %v, got %v", expectedBool, record[0].Value) + if record[0].Value().(bool) != expectedBool { + t.Fatalf("expected %v, got %v", expectedBool, record[0].Value()) } expectedInt4 := int32(2) - if record[1].Value.(int32) != expectedInt4 { - t.Fatalf("expected %v, got %v", expectedInt4, record[1].Value) + if record[1].Value().(int32) != expectedInt4 { + t.Fatalf("expected %v, got %v", expectedInt4, record[1].Value()) } expectedInt8 := int64(3) - if record[2].Value.(int64) != expectedInt8 { - t.Fatalf("expected %v, got %v", expectedInt8, record[2].Value) + if record[2].Value().(int64) != expectedInt8 { + t.Fatalf("expected %v, got %v", expectedInt8, record[2].Value()) } expectedFloat4 := float32(1.1) - if record[3].Value.(float32) != expectedFloat4 { - t.Fatalf("expected %v, got %v", expectedFloat4, record[3].Value) + if record[3].Value().(float32) != expectedFloat4 { + t.Fatalf("expected %v, got %v", expectedFloat4, record[3].Value()) } expectedFloat8 := float64(2.2) - if record[4].Value.(float64) != expectedFloat8 { - t.Fatalf("expected %v, got %v", expectedFloat8, record[4].Value) + if record[4].Value().(float64) != expectedFloat8 { + t.Fatalf("expected %v, got %v", expectedFloat8, record[4].Value()) } expectedText := "text" - if record[5].Value.(string) != expectedText { - t.Fatalf("expected %v, got %v", expectedText, record[5].Value) + if record[5].Value().(string) != expectedText { + t.Fatalf("expected %v, got %v", expectedText, record[5].Value()) } expectedBytea := []byte("bytea") - if !bytes.Equal(record[6].Value.([]byte), expectedBytea) { - t.Fatalf("expected %v, got %v", expectedBytea, record[6].Value) + if !bytes.Equal(record[6].Value().([]byte), expectedBytea) { + t.Fatalf("expected %v, got %v", expectedBytea, record[6].Value()) } expectedJSON := `{"key":"value"}` - if record[7].Value.(string) != expectedJSON { - t.Fatalf("expected %v, got %v", expectedJSON, record[7].Value) + if record[7].Value().(string) != expectedJSON { + t.Fatalf("expected %v, got %v", expectedJSON, record[7].Value()) } - actualUUID := record[8].Value.([16]uint8) + actualUUID := record[8].Value().([16]uint8) if !bytes.Equal(actualUUID[:], savedUUID[:]) { t.Fatalf("expected %v, got %v", savedUUID, actualUUID) } expectedNumeric := "123.456" - actualNumeric := record[10].Value.(decimal.Decimal).String() + actualNumeric := record[10].Value().(decimal.Decimal).String() if actualNumeric != expectedNumeric { t.Fatalf("expected %v, got %v", expectedNumeric, actualNumeric) } diff --git a/flow/connectors/postgres/qrep_sql_sync.go b/flow/connectors/postgres/qrep_sql_sync.go index a6ccc5e224..bd0e78f32a 100644 --- a/flow/connectors/postgres/qrep_sql_sync.go +++ b/flow/connectors/postgres/qrep_sql_sync.go @@ -92,7 +92,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( copySource, ) if err != nil { - return -1, fmt.Errorf("failed to copy records into destination table: %v", err) + return -1, fmt.Errorf("failed to copy records into destination table: %w", err) } if syncedAtCol != "" { @@ -104,7 +104,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( ) _, err = tx.Exec(context.Background(), updateSyncedAtStmt) if err != nil { - return -1, fmt.Errorf("failed to update synced_at column: %v", err) + return -1, fmt.Errorf("failed to update synced_at column: %w", err) } } } else { @@ -123,7 +123,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( stagingTableName, createStagingTableStmt), syncLog) _, err = tx.Exec(context.Background(), createStagingTableStmt) if err != nil { - return -1, fmt.Errorf("failed to create staging table: %v", err) + return -1, fmt.Errorf("failed to create staging table: %w", err) } // Step 2.2: Insert records into the staging table @@ -134,7 +134,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( copySource, ) if err != nil || numRowsSynced != int64(copySource.NumRecords()) { - return -1, fmt.Errorf("failed to copy records into staging table: %v", err) + return -1, fmt.Errorf("failed to copy records into staging table: %w", err) } // construct the SET clause for the upsert operation @@ -173,7 +173,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( s.connector.logger.Info("Performing upsert operation", slog.String("upsertStmt", upsertStmt), syncLog) res, err := tx.Exec(context.Background(), upsertStmt) if err != nil { - return -1, fmt.Errorf("failed to perform upsert operation: %v", err) + return -1, fmt.Errorf("failed to perform upsert operation: %w", err) } numRowsSynced = res.RowsAffected() @@ -186,7 +186,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( s.connector.logger.Info("Dropping staging table", slog.String("stagingTable", stagingTableName), syncLog) _, err = tx.Exec(context.Background(), dropStagingTableStmt) if err != nil { - return -1, fmt.Errorf("failed to drop staging table: %v", err) + return -1, fmt.Errorf("failed to drop staging table: %w", err) } } @@ -195,7 +195,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( // marshal the partition to json using protojson pbytes, err := protojson.Marshal(partition) if err != nil { - return -1, fmt.Errorf("failed to marshal partition to json: %v", err) + return -1, fmt.Errorf("failed to marshal partition to json: %w", err) } metadataTableIdentifier := pgx.Identifier{s.connector.metadataSchema, qRepMetadataTableName} @@ -214,12 +214,12 @@ func (s *QRepStagingTableSync) SyncQRepRecords( time.Now(), ) if err != nil { - return -1, fmt.Errorf("failed to execute statements in a transaction: %v", err) + return -1, fmt.Errorf("failed to execute statements in a transaction: %w", err) } err = tx.Commit(context.Background()) if err != nil { - return -1, fmt.Errorf("failed to commit transaction: %v", err) + return -1, fmt.Errorf("failed to commit transaction: %w", err) } numRowsInserted := copySource.NumRecords() diff --git a/flow/connectors/postgres/qvalue_convert.go b/flow/connectors/postgres/qvalue_convert.go index d0e3e8cc0b..01164672e8 100644 --- a/flow/connectors/postgres/qvalue_convert.go +++ b/flow/connectors/postgres/qvalue_convert.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/google/uuid" "github.com/jackc/pgx/v5/pgtype" "github.com/lib/pq/oid" "github.com/shopspring/decimal" @@ -195,39 +196,37 @@ func qValueKindToPostgresType(colTypeStr string) string { func parseJSON(value interface{}) (qvalue.QValue, error) { jsonVal, err := json.Marshal(value) if err != nil { - return qvalue.QValue{}, fmt.Errorf("failed to parse JSON: %w", err) + return nil, fmt.Errorf("failed to parse JSON: %w", err) } - return qvalue.QValue{Kind: qvalue.QValueKindJSON, Value: string(jsonVal)}, nil + return qvalue.QValueJSON{Val: string(jsonVal)}, nil } -func convertToArray[T any](kind qvalue.QValueKind, value interface{}) (qvalue.QValue, error) { +func convertToArray[T any](kind qvalue.QValueKind, value interface{}) ([]T, error) { switch v := value.(type) { case pgtype.Array[T]: if v.Valid { - return qvalue.QValue{Kind: kind, Value: v.Elements}, nil + return v.Elements, nil } case []T: - return qvalue.QValue{Kind: kind, Value: v}, nil + return v, nil case []interface{}: - return qvalue.QValue{Kind: kind, Value: shared.ArrayCastElements[T](v)}, nil + return shared.ArrayCastElements[T](v), nil } - return qvalue.QValue{}, fmt.Errorf("failed to parse array %s from %T: %v", kind, value, value) + return nil, fmt.Errorf("failed to parse array %s from %T: %v", kind, value, value) } func parseFieldFromQValueKind(qvalueKind qvalue.QValueKind, value interface{}) (qvalue.QValue, error) { - val := qvalue.QValue{} - if value == nil { - return qvalue.QValue{Kind: qvalueKind, Value: nil}, nil + return qvalue.QValueNull(qvalueKind), nil } switch qvalueKind { case qvalue.QValueKindTimestamp: timestamp := value.(time.Time) - val = qvalue.QValue{Kind: qvalue.QValueKindTimestamp, Value: timestamp} + return qvalue.QValueTimestamp{Val: timestamp}, nil case qvalue.QValueKindTimestampTZ: timestamp := value.(time.Time) - val = qvalue.QValue{Kind: qvalue.QValueKindTimestampTZ, Value: timestamp} + return qvalue.QValueTimestampTZ{Val: timestamp}, nil case qvalue.QValueKindInterval: intervalObject := value.(pgtype.Interval) var interval peerdb_interval.PeerDBInterval @@ -241,22 +240,22 @@ func parseFieldFromQValueKind(qvalueKind qvalue.QValueKind, value interface{}) ( intervalJSON, err := json.Marshal(interval) if err != nil { - return qvalue.QValue{}, fmt.Errorf("failed to parse interval: %w", err) + return nil, fmt.Errorf("failed to parse interval: %w", err) } if !interval.Valid { - return qvalue.QValue{}, fmt.Errorf("invalid interval: %v", value) + return nil, fmt.Errorf("invalid interval: %v", value) } - return qvalue.QValue{Kind: qvalue.QValueKindString, Value: string(intervalJSON)}, nil + return qvalue.QValueString{Val: string(intervalJSON)}, nil case qvalue.QValueKindDate: date := value.(time.Time) - val = qvalue.QValue{Kind: qvalue.QValueKindDate, Value: date} + return qvalue.QValueDate{Val: date}, nil case qvalue.QValueKindTime: timeVal := value.(pgtype.Time) if timeVal.Valid { // 86399999999 to prevent 24:00:00 - val = qvalue.QValue{Kind: qvalue.QValueKindTime, Value: time.UnixMicro(min(timeVal.Microseconds, 86399999999))} + return qvalue.QValueTime{Val: time.UnixMicro(min(timeVal.Microseconds, 86399999999))}, nil } case qvalue.QValueKindTimeTZ: timeVal := value.(string) @@ -266,147 +265,186 @@ func parseFieldFromQValueKind(qvalueKind qvalue.QValueKind, value interface{}) ( timeVal = strings.Replace(timeVal, "+00", "+0000", 1) t, err := time.Parse("15:04:05.999999-0700", timeVal) if err != nil { - return qvalue.QValue{}, fmt.Errorf("failed to parse time: %w", err) + return nil, fmt.Errorf("failed to parse time: %w", err) } t = t.AddDate(1970, 0, 0) - val = qvalue.QValue{Kind: qvalue.QValueKindTimeTZ, Value: t} + return qvalue.QValueTimeTZ{Val: t}, nil case qvalue.QValueKindBoolean: boolVal := value.(bool) - val = qvalue.QValue{Kind: qvalue.QValueKindBoolean, Value: boolVal} + return qvalue.QValueBoolean{Val: boolVal}, nil case qvalue.QValueKindJSON: tmp, err := parseJSON(value) if err != nil { - return qvalue.QValue{}, fmt.Errorf("failed to parse JSON: %w", err) + return nil, fmt.Errorf("failed to parse JSON: %w", err) } - val = tmp + return tmp, nil case qvalue.QValueKindInt16: intVal := value.(int16) - val = qvalue.QValue{Kind: qvalue.QValueKindInt16, Value: int32(intVal)} + return qvalue.QValueInt16{Val: intVal}, nil case qvalue.QValueKindInt32: intVal := value.(int32) - val = qvalue.QValue{Kind: qvalue.QValueKindInt32, Value: intVal} + return qvalue.QValueInt32{Val: intVal}, nil case qvalue.QValueKindInt64: intVal := value.(int64) - val = qvalue.QValue{Kind: qvalue.QValueKindInt64, Value: intVal} + return qvalue.QValueInt64{Val: intVal}, nil case qvalue.QValueKindFloat32: floatVal := value.(float32) - val = qvalue.QValue{Kind: qvalue.QValueKindFloat32, Value: floatVal} + return qvalue.QValueFloat32{Val: floatVal}, nil case qvalue.QValueKindFloat64: floatVal := value.(float64) - val = qvalue.QValue{Kind: qvalue.QValueKindFloat64, Value: floatVal} + return qvalue.QValueFloat64{Val: floatVal}, nil case qvalue.QValueKindQChar: - val = qvalue.QValue{Kind: qvalue.QValueKindQChar, Value: uint8(value.(rune))} + return qvalue.QValueQChar{Val: uint8(value.(rune))}, nil case qvalue.QValueKindString: // handling all unsupported types with strings as well for now. - val = qvalue.QValue{Kind: qvalue.QValueKindString, Value: fmt.Sprint(value)} + return qvalue.QValueString{Val: fmt.Sprint(value)}, nil case qvalue.QValueKindUUID: - switch value.(type) { + switch v := value.(type) { case string: - val = qvalue.QValue{Kind: qvalue.QValueKindUUID, Value: value} + id, err := uuid.Parse(v) + if err != nil { + return nil, fmt.Errorf("failed to parse UUID: %w", err) + } + return qvalue.QValueUUID{Val: [16]byte(id)}, nil case [16]byte: - val = qvalue.QValue{Kind: qvalue.QValueKindUUID, Value: value} + return qvalue.QValueUUID{Val: v}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse UUID: %v", value) + return nil, fmt.Errorf("failed to parse UUID: %v", value) } case qvalue.QValueKindINET: switch v := value.(type) { case string: - val = qvalue.QValue{Kind: qvalue.QValueKindINET, Value: value} + return qvalue.QValueINET{Val: v}, nil case [16]byte: - val = qvalue.QValue{Kind: qvalue.QValueKindINET, Value: value} + return qvalue.QValueINET{Val: string(v[:])}, nil case netip.Prefix: - val = qvalue.QValue{Kind: qvalue.QValueKindINET, Value: v.String()} + return qvalue.QValueINET{Val: v.String()}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse INET: %v", v) + return nil, fmt.Errorf("failed to parse INET: %v", v) } case qvalue.QValueKindCIDR: switch v := value.(type) { case string: - val = qvalue.QValue{Kind: qvalue.QValueKindCIDR, Value: value} + return qvalue.QValueCIDR{Val: v}, nil case [16]byte: - val = qvalue.QValue{Kind: qvalue.QValueKindCIDR, Value: value} + return qvalue.QValueCIDR{Val: string(v[:])}, nil case netip.Prefix: - val = qvalue.QValue{Kind: qvalue.QValueKindCIDR, Value: v.String()} + return qvalue.QValueCIDR{Val: v.String()}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse CIDR: %v", value) + return nil, fmt.Errorf("failed to parse CIDR: %v", value) } case qvalue.QValueKindMacaddr: - switch value.(type) { + switch v := value.(type) { case string: - val = qvalue.QValue{Kind: qvalue.QValueKindMacaddr, Value: value} + return qvalue.QValueMacaddr{Val: v}, nil case [16]byte: - val = qvalue.QValue{Kind: qvalue.QValueKindMacaddr, Value: value} + return qvalue.QValueMacaddr{Val: string(v[:])}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse MACADDR: %v", value) + return nil, fmt.Errorf("failed to parse MACADDR: %v", value) } case qvalue.QValueKindBytes: rawBytes := value.([]byte) - val = qvalue.QValue{Kind: qvalue.QValueKindBytes, Value: rawBytes} + return qvalue.QValueBytes{Val: rawBytes}, nil case qvalue.QValueKindBit: bitsVal := value.(pgtype.Bits) if bitsVal.Valid { - val = qvalue.QValue{Kind: qvalue.QValueKindBit, Value: bitsVal.Bytes} + return qvalue.QValueBit{Val: bitsVal.Bytes}, nil } case qvalue.QValueKindNumeric: numVal := value.(pgtype.Numeric) if numVal.Valid { num, err := numericToDecimal(numVal) if err != nil { - return qvalue.QValue{}, fmt.Errorf("failed to convert numeric [%v] to decimal: %w", value, err) + return nil, fmt.Errorf("failed to convert numeric [%v] to decimal: %w", value, err) } - val = qvalue.QValue{Kind: qvalue.QValueKindNumeric, Value: num} + return num, nil } case qvalue.QValueKindArrayFloat32: - return convertToArray[float32](qvalueKind, value) + a, err := convertToArray[float32](qvalueKind, value) + if err != nil { + return nil, err + } + return qvalue.QValueArrayFloat32{Val: a}, nil case qvalue.QValueKindArrayFloat64: - return convertToArray[float64](qvalueKind, value) + a, err := convertToArray[float64](qvalueKind, value) + if err != nil { + return nil, err + } + return qvalue.QValueArrayFloat64{Val: a}, nil case qvalue.QValueKindArrayInt16: - return convertToArray[int16](qvalueKind, value) + a, err := convertToArray[int16](qvalueKind, value) + if err != nil { + return nil, err + } + return qvalue.QValueArrayInt16{Val: a}, nil case qvalue.QValueKindArrayInt32: - return convertToArray[int32](qvalueKind, value) + a, err := convertToArray[int32](qvalueKind, value) + if err != nil { + return nil, err + } + return qvalue.QValueArrayInt32{Val: a}, nil case qvalue.QValueKindArrayInt64: - return convertToArray[int64](qvalueKind, value) + a, err := convertToArray[int64](qvalueKind, value) + if err != nil { + return nil, err + } + return qvalue.QValueArrayInt64{Val: a}, nil case qvalue.QValueKindArrayDate, qvalue.QValueKindArrayTimestamp, qvalue.QValueKindArrayTimestampTZ: - return convertToArray[time.Time](qvalueKind, value) + a, err := convertToArray[time.Time](qvalueKind, value) + if err != nil { + return nil, err + } + switch qvalueKind { + case qvalue.QValueKindArrayDate: + return qvalue.QValueArrayDate{Val: a}, nil + case qvalue.QValueKindArrayTimestamp: + return qvalue.QValueArrayTimestamp{Val: a}, nil + case qvalue.QValueKindArrayTimestampTZ: + return qvalue.QValueArrayTimestampTZ{Val: a}, nil + } case qvalue.QValueKindArrayBoolean: - return convertToArray[bool](qvalueKind, value) + a, err := convertToArray[bool](qvalueKind, value) + if err != nil { + return nil, err + } + return qvalue.QValueArrayBoolean{Val: a}, nil case qvalue.QValueKindArrayString: - return convertToArray[string](qvalueKind, value) + a, err := convertToArray[string](qvalueKind, value) + if err != nil { + return nil, err + } + return qvalue.QValueArrayString{Val: a}, nil case qvalue.QValueKindPoint: xCoord := value.(pgtype.Point).P.X yCoord := value.(pgtype.Point).P.Y - val = qvalue.QValue{ - Kind: qvalue.QValueKindPoint, - Value: fmt.Sprintf("POINT(%f %f)", xCoord, yCoord), - } + return qvalue.QValuePoint{ + Val: fmt.Sprintf("POINT(%f %f)", xCoord, yCoord), + }, nil default: textVal, ok := value.(string) if ok { - val = qvalue.QValue{Kind: qvalue.QValueKindString, Value: textVal} + return qvalue.QValueString{Val: textVal}, nil } } // parsing into pgtype failed. - if val == (qvalue.QValue{}) { - return qvalue.QValue{}, fmt.Errorf("failed to parse value %v into QValueKind %v", value, qvalueKind) - } - return val, nil + return nil, fmt.Errorf("failed to parse value %v into QValueKind %v", value, qvalueKind) } func (c *PostgresConnector) parseFieldFromPostgresOID(oid uint32, value interface{}) (qvalue.QValue, error) { return parseFieldFromQValueKind(c.postgresOIDToQValueKind(oid), value) } -func numericToDecimal(numVal pgtype.Numeric) (interface{}, error) { +func numericToDecimal(numVal pgtype.Numeric) (qvalue.QValue, error) { switch { case !numVal.Valid: - return nil, errors.New("invalid numeric") + return qvalue.QValueNull(qvalue.QValueKindNumeric), errors.New("invalid numeric") case numVal.NaN, numVal.InfinityModifier == pgtype.Infinity, numVal.InfinityModifier == pgtype.NegativeInfinity: - return nil, nil + return qvalue.QValueNull(qvalue.QValueKindNumeric), nil default: - return decimal.NewFromBigInt(numVal.Int, numVal.Exp), nil + return qvalue.QValueNumeric{Val: decimal.NewFromBigInt(numVal.Int, numVal.Exp)}, nil } } diff --git a/flow/connectors/s3/s3.go b/flow/connectors/s3/s3.go index 7e95e00b43..fddd69f78f 100644 --- a/flow/connectors/s3/s3.go +++ b/flow/connectors/s3/s3.go @@ -155,11 +155,10 @@ func (c *S3Connector) SetLastOffset(ctx context.Context, jobName string, offset func (c *S3Connector) SyncRecords(ctx context.Context, req *model.SyncRecordsRequest) (*model.SyncResponse, error) { tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, req.SyncBatchID) - streamRes, err := utils.RecordsToRawTableStream(streamReq) + recordStream, err := utils.RecordsToRawTableStream(streamReq) if err != nil { return nil, fmt.Errorf("failed to convert records to raw table stream: %w", err) } - recordStream := streamRes.Stream qrepConfig := &protos.QRepConfig{ FlowJobName: req.FlowJobName, DestinationTableIdentifier: "raw_table_" + req.FlowJobName, diff --git a/flow/connectors/snowflake/avro_file_writer_test.go b/flow/connectors/snowflake/avro_file_writer_test.go index 13f4a9e3e8..0006513cbb 100644 --- a/flow/connectors/snowflake/avro_file_writer_test.go +++ b/flow/connectors/snowflake/avro_file_writer_test.go @@ -17,45 +17,53 @@ import ( ) // createQValue creates a QValue of the appropriate kind for a given placeholder. -func createQValue(t *testing.T, kind qvalue.QValueKind, placeHolder int) qvalue.QValue { +func createQValue(t *testing.T, kind qvalue.QValueKind, placeholder int) qvalue.QValue { t.Helper() - var value interface{} switch kind { - case qvalue.QValueKindInt16, qvalue.QValueKindInt32, qvalue.QValueKindInt64: - value = int64(placeHolder) + case qvalue.QValueKindInt16: + return qvalue.QValueInt16{Val: int16(placeholder)} + case qvalue.QValueKindInt32: + return qvalue.QValueInt32{Val: int32(placeholder)} + case qvalue.QValueKindInt64: + return qvalue.QValueInt64{Val: int64(placeholder)} case qvalue.QValueKindFloat32: - value = float32(placeHolder) + return qvalue.QValueFloat32{Val: float32(placeholder) / 4.0} case qvalue.QValueKindFloat64: - value = float64(placeHolder) + return qvalue.QValueFloat64{Val: float64(placeholder) / 4.0} case qvalue.QValueKindBoolean: - value = placeHolder%2 == 0 + return qvalue.QValueBoolean{Val: placeholder%2 == 0} case qvalue.QValueKindString: - value = fmt.Sprintf("string%d", placeHolder) - case qvalue.QValueKindTimestamp, qvalue.QValueKindTimestampTZ, qvalue.QValueKindTime, - qvalue.QValueKindTimeTZ, qvalue.QValueKindDate: - value = time.Now() + return qvalue.QValueString{Val: fmt.Sprintf("string%d", placeholder)} + case qvalue.QValueKindTimestamp: + return qvalue.QValueTimestamp{Val: time.Now()} + case qvalue.QValueKindTimestampTZ: + return qvalue.QValueTimestampTZ{Val: time.Now()} + case qvalue.QValueKindTime: + return qvalue.QValueTime{Val: time.Now()} + case qvalue.QValueKindTimeTZ: + return qvalue.QValueTimeTZ{Val: time.Now()} + case qvalue.QValueKindDate: + return qvalue.QValueDate{Val: time.Now()} case qvalue.QValueKindNumeric: - value = decimal.New(int64(placeHolder), 1) + return qvalue.QValueNumeric{Val: decimal.New(int64(placeholder), 1)} case qvalue.QValueKindUUID: - value = uuid.New() // assuming you have the github.com/google/uuid package + return qvalue.QValueUUID{Val: [16]byte(uuid.New())} // assuming you have the github.com/google/uuid package case qvalue.QValueKindQChar: - value = uint8(48) - // case qvalue.QValueKindArray: - // value = []int{1, 2, 3} // placeholder array, replace with actual logic - // case qvalue.QValueKindStruct: - // value = map[string]interface{}{"key": "value"} // placeholder struct, replace with actual logic - // case qvalue.QValueKindJSON: - // value = `{"key": "value"}` // placeholder JSON, replace with actual logic - case qvalue.QValueKindBytes, qvalue.QValueKindBit: - value = []byte("sample bytes") // placeholder bytes, replace with actual logic + return qvalue.QValueQChar{Val: uint8(48 + placeholder%10)} // assuming you have the github.com/google/uuid package + // case qvalue.QValueKindArray: + // value = []int{1, 2, 3} // placeholder array, replace with actual logic + // case qvalue.QValueKindStruct: + // value = map[string]interface{}{"key": "value"} // placeholder struct, replace with actual logic + // case qvalue.QValueKindJSON: + // value = `{"key": "value"}` // placeholder JSON, replace with actual logic + case qvalue.QValueKindBytes: + return qvalue.QValueBytes{Val: []byte("sample bytes")} // placeholder bytes, replace with actual logic + case qvalue.QValueKindBit: + return qvalue.QValueBit{Val: []byte("sample bits")} // placeholder bytes, replace with actual logic default: require.Failf(t, "unsupported QValueKind", "unsupported QValueKind: %s", kind) - } - - return qvalue.QValue{ - Kind: kind, - Value: value, + return qvalue.QValueNull(kind) } } @@ -115,10 +123,10 @@ func generateRecords( entries := make([]qvalue.QValue, len(allQValueKinds)) for i, kind := range allQValueKinds { - placeHolder := int(row) * i - entries[i] = createQValue(t, kind, placeHolder) if allnulls { - entries[i].Value = nil + entries[i] = qvalue.QValueNull(kind) + } else { + entries[i] = createQValue(t, kind, int(row)*i) } } diff --git a/flow/connectors/snowflake/qrep_avro_consolidate.go b/flow/connectors/snowflake/qrep_avro_consolidate.go index 8d39ecf0b8..6f261d2cf8 100644 --- a/flow/connectors/snowflake/qrep_avro_consolidate.go +++ b/flow/connectors/snowflake/qrep_avro_consolidate.go @@ -142,7 +142,7 @@ func (s *SnowflakeAvroConsolidateHandler) generateUpsertMergeCommand( upsertKeyCols := s.config.WriteMode.UpsertKeyColumns // all cols are acquired from snowflake schema, so let us try to make upsert key cols match the case // and also the watermark col, then the quoting should be fine - caseMatchedCols := map[string]string{} + caseMatchedCols := make(map[string]string, len(s.allColNames)) for _, col := range s.allColNames { caseMatchedCols[strings.ToLower(col)] = col } diff --git a/flow/connectors/snowflake/snowflake.go b/flow/connectors/snowflake/snowflake.go index 1d9ed6fe58..3844c321fc 100644 --- a/flow/connectors/snowflake/snowflake.go +++ b/flow/connectors/snowflake/snowflake.go @@ -449,7 +449,7 @@ func (c *SnowflakeConnector) syncRecordsViaAvro( ) (*model.SyncResponse, error) { tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, syncBatchID) - streamRes, err := utils.RecordsToRawTableStream(streamReq) + stream, err := utils.RecordsToRawTableStream(streamReq) if err != nil { return nil, fmt.Errorf("failed to convert records to raw table stream: %w", err) } @@ -466,7 +466,7 @@ func (c *SnowflakeConnector) syncRecordsViaAvro( return nil, err } - numRecords, err := avroSyncer.SyncRecords(ctx, destinationTableSchema, streamRes.Stream, req.FlowJobName) + numRecords, err := avroSyncer.SyncRecords(ctx, destinationTableSchema, stream, req.FlowJobName) if err != nil { return nil, err } diff --git a/flow/connectors/sql/query_executor.go b/flow/connectors/sql/query_executor.go index 05279fdde4..447da7c712 100644 --- a/flow/connectors/sql/query_executor.go +++ b/flow/connectors/sql/query_executor.go @@ -7,6 +7,7 @@ import ( "fmt" "log/slog" "strings" + "time" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgtype" @@ -218,7 +219,7 @@ func (g *GenericSQLQueryExecutor) processRows(ctx context.Context, rows *sqlx.Ro case qvalue.QValueKindBoolean: var b sql.NullBool values[i] = &b - case qvalue.QValueKindString: + case qvalue.QValueKindString, qvalue.QValueKindHStore: var s sql.NullString values[i] = &s case qvalue.QValueKindBytes, qvalue.QValueKindBit: @@ -321,87 +322,124 @@ func (g *GenericSQLQueryExecutor) CheckNull(ctx context.Context, schema string, func toQValue(kind qvalue.QValueKind, val interface{}) (qvalue.QValue, error) { if val == nil { - return qvalue.QValue{Kind: kind, Value: nil}, nil + return qvalue.QValueNull(kind), nil } switch kind { case qvalue.QValueKindInt32: if v, ok := val.(*sql.NullInt32); ok { if v.Valid { - return qvalue.QValue{Kind: qvalue.QValueKindInt32, Value: v.Int32}, nil + return qvalue.QValueInt32{Val: v.Int32}, nil } else { - return qvalue.QValue{Kind: qvalue.QValueKindInt32, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindInt32), nil } } case qvalue.QValueKindInt64: if v, ok := val.(*sql.NullInt64); ok { if v.Valid { - return qvalue.QValue{Kind: qvalue.QValueKindInt64, Value: v.Int64}, nil + return qvalue.QValueInt64{Val: v.Int64}, nil } else { - return qvalue.QValue{Kind: qvalue.QValueKindInt64, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindInt64), nil } } case qvalue.QValueKindFloat32: if v, ok := val.(*sql.NullFloat64); ok { if v.Valid { - return qvalue.QValue{Kind: qvalue.QValueKindFloat32, Value: float32(v.Float64)}, nil + return qvalue.QValueFloat32{Val: float32(v.Float64)}, nil } else { - return qvalue.QValue{Kind: qvalue.QValueKindFloat32, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindFloat32), nil } } case qvalue.QValueKindFloat64: if v, ok := val.(*sql.NullFloat64); ok { if v.Valid { - return qvalue.QValue{Kind: qvalue.QValueKindFloat64, Value: v.Float64}, nil + return qvalue.QValueFloat64{Val: v.Float64}, nil } else { - return qvalue.QValue{Kind: qvalue.QValueKindFloat64, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindFloat64), nil } } case qvalue.QValueKindQChar: if v, ok := val.(uint8); ok { - return qvalue.QValue{Kind: qvalue.QValueKindQChar, Value: v}, nil + return qvalue.QValueQChar{Val: v}, nil } case qvalue.QValueKindString: if v, ok := val.(*sql.NullString); ok { if v.Valid { - return qvalue.QValue{Kind: qvalue.QValueKindString, Value: v.String}, nil + return qvalue.QValueString{Val: v.String}, nil } else { - return qvalue.QValue{Kind: qvalue.QValueKindString, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindString), nil } } case qvalue.QValueKindBoolean: if v, ok := val.(*sql.NullBool); ok { if v.Valid { - return qvalue.QValue{Kind: qvalue.QValueKindBoolean, Value: v.Bool}, nil + return qvalue.QValueBoolean{Val: v.Bool}, nil } else { - return qvalue.QValue{Kind: qvalue.QValueKindBoolean, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindBoolean), nil } } - case qvalue.QValueKindTimestamp, qvalue.QValueKindTimestampTZ, qvalue.QValueKindDate, - qvalue.QValueKindTime, qvalue.QValueKindTimeTZ: + case qvalue.QValueKindTimestamp: if t, ok := val.(*sql.NullTime); ok { if t.Valid { - return qvalue.QValue{ - Kind: kind, - Value: t.Time, + return qvalue.QValueTimestamp{Val: t.Time}, nil + } else { + return qvalue.QValueNull(kind), nil + } + } + case qvalue.QValueKindTimestampTZ: + if t, ok := val.(*sql.NullTime); ok { + if t.Valid { + return qvalue.QValueTimestampTZ{Val: t.Time}, nil + } else { + return qvalue.QValueNull(kind), nil + } + } + case qvalue.QValueKindDate: + if t, ok := val.(*sql.NullTime); ok { + if t.Valid { + return qvalue.QValueDate{Val: t.Time}, nil + } else { + return qvalue.QValueNull(kind), nil + } + } + case qvalue.QValueKindTime: + if t, ok := val.(*sql.NullTime); ok { + if t.Valid { + tt := t.Time + // anchor on unix epoch, some drivers anchor on 0001-01-01 + return qvalue.QValueTimeTZ{ + Val: time.Date(1970, time.January, 1, tt.Hour(), tt.Minute(), tt.Second(), tt.Nanosecond(), time.UTC), }, nil } else { - return qvalue.QValue{ - Kind: kind, - Value: nil, + return qvalue.QValueNull(kind), nil + } + } + case qvalue.QValueKindTimeTZ: + if t, ok := val.(*sql.NullTime); ok { + if t.Valid { + tt := t.Time + // anchor on unix epoch, some drivers anchor on 0001-01-01 + return qvalue.QValueTimeTZ{ + Val: time.Date(1970, time.January, 1, tt.Hour(), tt.Minute(), tt.Second(), tt.Nanosecond(), tt.Location()), }, nil + } else { + return qvalue.QValueNull(kind), nil } } case qvalue.QValueKindNumeric: if v, ok := val.(*sql.Null[decimal.Decimal]); ok { if v.Valid { - return qvalue.QValue{Kind: qvalue.QValueKindNumeric, Value: v.V}, nil + return qvalue.QValueNumeric{Val: v.V}, nil } else { - return qvalue.QValue{Kind: qvalue.QValueKindNumeric, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindNumeric), nil } } - case qvalue.QValueKindBytes, qvalue.QValueKindBit: + case qvalue.QValueKindBytes: + if v, ok := val.(*[]byte); ok && v != nil { + return qvalue.QValueBytes{Val: *v}, nil + } + case qvalue.QValueKindBit: if v, ok := val.(*[]byte); ok && v != nil { - return qvalue.QValue{Kind: kind, Value: *v}, nil + return qvalue.QValueBit{Val: *v}, nil } case qvalue.QValueKindUUID: @@ -409,13 +447,9 @@ func toQValue(kind qvalue.QValueKind, val interface{}) (qvalue.QValue, error) { // convert byte array to string uuidVal, err := uuid.FromBytes(*v) if err != nil { - return qvalue.QValue{}, fmt.Errorf("failed to parse uuid: %v", *v) + return nil, fmt.Errorf("failed to parse uuid: %v", *v) } - return qvalue.QValue{Kind: qvalue.QValueKindString, Value: uuidVal.String()}, nil - } - - if v, ok := val.(*[16]byte); ok && v != nil { - return qvalue.QValue{Kind: qvalue.QValueKindString, Value: *v}, nil + return qvalue.QValueUUID{Val: [16]byte(uuidVal)}, nil } case qvalue.QValueKindJSON: @@ -430,7 +464,7 @@ func toQValue(kind qvalue.QValueKind, val interface{}) (qvalue.QValue, error) { var v []interface{} err := json.Unmarshal([]byte(vstring), &v) if err != nil { - return qvalue.QValue{}, fmt.Errorf("failed to parse json array: %v", vstring) + return nil, fmt.Errorf("failed to parse json array: %v", vstring) } // assume all elements in the array are of the same type @@ -456,10 +490,16 @@ func toQValue(kind qvalue.QValueKind, val interface{}) (qvalue.QValue, error) { } } - return qvalue.QValue{Kind: qvalue.QValueKindJSON, Value: vstring}, nil + return qvalue.QValueJSON{Val: vstring}, nil case qvalue.QValueKindHStore: - return qvalue.QValue{Kind: qvalue.QValueKindHStore, Value: val}, nil + vraw := val.(*interface{}) + vstring, ok := (*vraw).(string) + if !ok { + slog.Warn("A parsed hstore value was not a string. Likely a null field value") + } + + return qvalue.QValueHStore{Val: vstring}, nil case qvalue.QValueKindArrayFloat32, qvalue.QValueKindArrayFloat64, qvalue.QValueKindArrayInt16, @@ -469,96 +509,95 @@ func toQValue(kind qvalue.QValueKind, val interface{}) (qvalue.QValue, error) { } // If type is unsupported or doesn't match the specified kind, return error - return qvalue.QValue{}, fmt.Errorf("unsupported type %T for kind %s", val, kind) + return nil, fmt.Errorf("unsupported type %T for kind %s", val, kind) } func toQValueArray(kind qvalue.QValueKind, value interface{}) (qvalue.QValue, error) { - var result interface{} switch kind { case qvalue.QValueKindArrayFloat32: switch v := value.(type) { case []float32: - result = v + return qvalue.QValueArrayFloat32{Val: v}, nil case []interface{}: float32Array := make([]float32, len(v)) for i, val := range v { float32Array[i] = val.(float32) } - result = float32Array + return qvalue.QValueArrayFloat32{Val: float32Array}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse array float32: %v", value) + return nil, fmt.Errorf("failed to parse array float32: %v", value) } case qvalue.QValueKindArrayFloat64: switch v := value.(type) { case []float64: - result = v + return qvalue.QValueArrayFloat64{Val: v}, nil case []interface{}: float64Array := make([]float64, len(v)) for i, val := range v { float64Array[i] = val.(float64) } - result = float64Array + return qvalue.QValueArrayFloat64{Val: float64Array}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse array float64: %v", value) + return nil, fmt.Errorf("failed to parse array float64: %v", value) } case qvalue.QValueKindArrayInt16: switch v := value.(type) { case []int16: - result = v + return qvalue.QValueArrayInt16{Val: v}, nil case []interface{}: int16Array := make([]int16, len(v)) for i, val := range v { int16Array[i] = val.(int16) } - result = int16Array + return qvalue.QValueArrayInt16{Val: int16Array}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse array int16: %v", value) + return nil, fmt.Errorf("failed to parse array int16: %v", value) } case qvalue.QValueKindArrayInt32: switch v := value.(type) { case []int32: - result = v + return qvalue.QValueArrayInt32{Val: v}, nil case []interface{}: int32Array := make([]int32, len(v)) for i, val := range v { int32Array[i] = val.(int32) } - result = int32Array + return qvalue.QValueArrayInt32{Val: int32Array}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse array int32: %v", value) + return nil, fmt.Errorf("failed to parse array int32: %v", value) } case qvalue.QValueKindArrayInt64: switch v := value.(type) { case []int64: - result = v + return qvalue.QValueArrayInt64{Val: v}, nil case []interface{}: int64Array := make([]int64, len(v)) for i, val := range v { int64Array[i] = val.(int64) } - result = int64Array + return qvalue.QValueArrayInt64{Val: int64Array}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse array int64: %v", value) + return nil, fmt.Errorf("failed to parse array int64: %v", value) } case qvalue.QValueKindArrayString: switch v := value.(type) { case []string: - result = v + return qvalue.QValueArrayString{Val: v}, nil case []interface{}: stringArray := make([]string, len(v)) for i, val := range v { stringArray[i] = val.(string) } - result = stringArray + return qvalue.QValueArrayString{Val: stringArray}, nil default: - return qvalue.QValue{}, fmt.Errorf("failed to parse array string: %v", value) + return nil, fmt.Errorf("failed to parse array string: %v", value) } } - return qvalue.QValue{Kind: kind, Value: result}, nil + return qvalue.QValueNull(kind), nil } diff --git a/flow/connectors/utils/cdc_records/cdc_records_storage.go b/flow/connectors/utils/cdc_records/cdc_records_storage.go index e4a8561aea..1de0a6d2cd 100644 --- a/flow/connectors/utils/cdc_records/cdc_records_storage.go +++ b/flow/connectors/utils/cdc_records/cdc_records_storage.go @@ -16,6 +16,7 @@ import ( "go.temporal.io/sdk/log" "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" ) @@ -73,6 +74,45 @@ func (c *cdcRecordsStore) initPebbleDB() error { gob.Register(&model.DeleteRecord{}) gob.Register(time.Time{}) gob.Register(decimal.Decimal{}) + gob.Register(qvalue.QValueNull("")) + gob.Register(qvalue.QValueInvalid{}) + gob.Register(qvalue.QValueFloat32{}) + gob.Register(qvalue.QValueFloat64{}) + gob.Register(qvalue.QValueInt16{}) + gob.Register(qvalue.QValueInt32{}) + gob.Register(qvalue.QValueInt64{}) + gob.Register(qvalue.QValueBoolean{}) + gob.Register(qvalue.QValueStruct{}) + gob.Register(qvalue.QValueQChar{}) + gob.Register(qvalue.QValueString{}) + gob.Register(qvalue.QValueTimestamp{}) + gob.Register(qvalue.QValueTimestampTZ{}) + gob.Register(qvalue.QValueDate{}) + gob.Register(qvalue.QValueTime{}) + gob.Register(qvalue.QValueTimeTZ{}) + gob.Register(qvalue.QValueInterval{}) + gob.Register(qvalue.QValueNumeric{}) + gob.Register(qvalue.QValueBytes{}) + gob.Register(qvalue.QValueUUID{}) + gob.Register(qvalue.QValueJSON{}) + gob.Register(qvalue.QValueBit{}) + gob.Register(qvalue.QValueHStore{}) + gob.Register(qvalue.QValueGeography{}) + gob.Register(qvalue.QValueGeometry{}) + gob.Register(qvalue.QValuePoint{}) + gob.Register(qvalue.QValueCIDR{}) + gob.Register(qvalue.QValueINET{}) + gob.Register(qvalue.QValueMacaddr{}) + gob.Register(qvalue.QValueArrayFloat32{}) + gob.Register(qvalue.QValueArrayFloat64{}) + gob.Register(qvalue.QValueArrayInt16{}) + gob.Register(qvalue.QValueArrayInt32{}) + gob.Register(qvalue.QValueArrayInt64{}) + gob.Register(qvalue.QValueArrayString{}) + gob.Register(qvalue.QValueArrayDate{}) + gob.Register(qvalue.QValueArrayTimestamp{}) + gob.Register(qvalue.QValueArrayTimestampTZ{}) + gob.Register(qvalue.QValueArrayBoolean{}) var err error // we don't want a WAL since cache, we don't want to overwrite another DB either diff --git a/flow/connectors/utils/cdc_records/cdc_records_storage_test.go b/flow/connectors/utils/cdc_records/cdc_records_storage_test.go index 5acbc5962a..0d0b6da9e2 100644 --- a/flow/connectors/utils/cdc_records/cdc_records_storage_test.go +++ b/flow/connectors/utils/cdc_records/cdc_records_storage_test.go @@ -61,18 +61,9 @@ func genKeyAndRec(t *testing.T) (model.TableWithPkey, model.Record) { "rv": 2, }, Values: []qvalue.QValue{ - { - Kind: qvalue.QValueKindInt64, - Value: 1, - }, - { - Kind: qvalue.QValueKindTime, - Value: tv, - }, - { - Kind: qvalue.QValueKindNumeric, - Value: rv, - }, + qvalue.QValueInt64{Val: 1}, + qvalue.QValueTime{Val: tv}, + qvalue.QValueNumeric{Val: rv}, }, }, } diff --git a/flow/connectors/utils/stream.go b/flow/connectors/utils/stream.go index c2d146c062..d6729ca242 100644 --- a/flow/connectors/utils/stream.go +++ b/flow/connectors/utils/stream.go @@ -11,7 +11,7 @@ import ( "github.com/PeerDB-io/peer-flow/model/qvalue" ) -func RecordsToRawTableStream(req *model.RecordsToStreamRequest) (*model.RecordsToStreamResponse, error) { +func RecordsToRawTableStream(req *model.RecordsToStreamRequest) (*model.QRecordStream, error) { recordStream := model.NewQRecordStream(1 << 17) err := recordStream.SetSchema(&model.QRecordSchema{ Fields: []model.QField{ @@ -70,9 +70,7 @@ func RecordsToRawTableStream(req *model.RecordsToStreamRequest) (*model.RecordsT close(recordStream.Records) }() - return &model.RecordsToStreamResponse{ - Stream: recordStream, - }, nil + return recordStream, nil } func recordToQRecordOrError(batchID int64, record model.Record) model.QRecordOrError { @@ -87,23 +85,10 @@ func recordToQRecordOrError(batchID int64, record model.Record) model.QRecordOrE } } - entries[3] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: itemsJSON, - } - entries[4] = qvalue.QValue{ - Kind: qvalue.QValueKindInt64, - Value: 0, - } - entries[5] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: "", - } - entries[7] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: "", - } - + entries[3] = qvalue.QValueString{Val: itemsJSON} + entries[4] = qvalue.QValueInt64{Val: 0} + entries[5] = qvalue.QValueString{Val: ""} + entries[7] = qvalue.QValueString{Val: ""} case *model.UpdateRecord: newItemsJSON, err := typedRecord.NewItems.ToJSON() if err != nil { @@ -118,22 +103,10 @@ func recordToQRecordOrError(batchID int64, record model.Record) model.QRecordOrE } } - entries[3] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: newItemsJSON, - } - entries[4] = qvalue.QValue{ - Kind: qvalue.QValueKindInt64, - Value: 1, - } - entries[5] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: oldItemsJSON, - } - entries[7] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: KeysToString(typedRecord.UnchangedToastColumns), - } + entries[3] = qvalue.QValueString{Val: newItemsJSON} + entries[4] = qvalue.QValueInt64{Val: 1} + entries[5] = qvalue.QValueString{Val: oldItemsJSON} + entries[7] = qvalue.QValueString{Val: KeysToString(typedRecord.UnchangedToastColumns)} case *model.DeleteRecord: itemsJSON, err := typedRecord.Items.ToJSON() @@ -143,22 +116,10 @@ func recordToQRecordOrError(batchID int64, record model.Record) model.QRecordOrE } } - entries[3] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: itemsJSON, - } - entries[4] = qvalue.QValue{ - Kind: qvalue.QValueKindInt64, - Value: 2, - } - entries[5] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: itemsJSON, - } - entries[7] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: KeysToString(typedRecord.UnchangedToastColumns), - } + entries[3] = qvalue.QValueString{Val: itemsJSON} + entries[4] = qvalue.QValueInt64{Val: 2} + entries[5] = qvalue.QValueString{Val: itemsJSON} + entries[7] = qvalue.QValueString{Val: KeysToString(typedRecord.UnchangedToastColumns)} default: return model.QRecordOrError{ @@ -166,22 +127,10 @@ func recordToQRecordOrError(batchID int64, record model.Record) model.QRecordOrE } } - entries[0] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: uuid.New().String(), - } - entries[1] = qvalue.QValue{ - Kind: qvalue.QValueKindInt64, - Value: time.Now().UnixNano(), - } - entries[2] = qvalue.QValue{ - Kind: qvalue.QValueKindString, - Value: record.GetDestinationTableName(), - } - entries[6] = qvalue.QValue{ - Kind: qvalue.QValueKindInt64, - Value: batchID, - } + entries[0] = qvalue.QValueString{Val: uuid.New().String()} + entries[1] = qvalue.QValueInt64{Val: time.Now().UnixNano()} + entries[2] = qvalue.QValueString{Val: record.GetDestinationTableName()} + entries[6] = qvalue.QValueInt64{Val: batchID} return model.QRecordOrError{ Record: entries[:], diff --git a/flow/e2e/bigquery/bigquery_helper.go b/flow/e2e/bigquery/bigquery_helper.go index 7c8ab5257c..cb8558866a 100644 --- a/flow/e2e/bigquery/bigquery_helper.go +++ b/flow/e2e/bigquery/bigquery_helper.go @@ -209,37 +209,40 @@ func (b *BigQueryTestHelper) countRowsWithDataset(dataset, tableName string, non func toQValue(bqValue bigquery.Value) (qvalue.QValue, error) { // Based on the real type of the bigquery.Value, we create a qvalue.QValue switch v := bqValue.(type) { - case int, int32: - return qvalue.QValue{Kind: qvalue.QValueKindInt32, Value: v}, nil + case int: + return qvalue.QValueInt32{Val: int32(v)}, nil + case int32: + return qvalue.QValueInt32{Val: v}, nil case int64: - return qvalue.QValue{Kind: qvalue.QValueKindInt64, Value: v}, nil + return qvalue.QValueInt64{Val: v}, nil case float32: - return qvalue.QValue{Kind: qvalue.QValueKindFloat32, Value: v}, nil + return qvalue.QValueFloat32{Val: v}, nil case float64: - return qvalue.QValue{Kind: qvalue.QValueKindFloat64, Value: v}, nil + return qvalue.QValueFloat64{Val: v}, nil case string: - return qvalue.QValue{Kind: qvalue.QValueKindString, Value: v}, nil + return qvalue.QValueString{Val: v}, nil case bool: - return qvalue.QValue{Kind: qvalue.QValueKindBoolean, Value: v}, nil + return qvalue.QValueBoolean{Val: v}, nil case civil.Date: - return qvalue.QValue{Kind: qvalue.QValueKindDate, Value: v.In(time.UTC)}, nil + return qvalue.QValueDate{Val: v.In(time.UTC)}, nil case civil.Time: - return qvalue.QValue{Kind: qvalue.QValueKindTime, Value: v}, nil + tm := time.Unix(int64(v.Hour)*3600+int64(v.Minute)*60+int64(v.Second), int64(v.Nanosecond)) + return qvalue.QValueTime{Val: tm}, nil case time.Time: - return qvalue.QValue{Kind: qvalue.QValueKindTimestamp, Value: v}, nil + return qvalue.QValueTimestamp{Val: v}, nil case *big.Rat: val, err := decimal.NewFromString(v.FloatString(32)) if err != nil { - return qvalue.QValue{}, fmt.Errorf("bqHelper failed to parse as decimal %v", v) + return nil, fmt.Errorf("bqHelper failed to parse as decimal %v", v) } - return qvalue.QValue{Kind: qvalue.QValueKindNumeric, Value: val}, nil + return qvalue.QValueNumeric{Val: val}, nil case []uint8: - return qvalue.QValue{Kind: qvalue.QValueKindBytes, Value: v}, nil + return qvalue.QValueBytes{Val: v}, nil case []bigquery.Value: // If the type is an array, we need to convert each element // we can assume all elements are of the same type, let us use first element if len(v) == 0 { - return qvalue.QValue{Kind: qvalue.QValueKindInvalid, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindInvalid), nil } firstElement := v[0] @@ -249,60 +252,59 @@ func toQValue(bqValue bigquery.Value) (qvalue.QValue, error) { for _, val := range v { arr = append(arr, val.(int32)) } - return qvalue.QValue{Kind: qvalue.QValueKindArrayInt32, Value: arr}, nil + return qvalue.QValueArrayInt32{Val: arr}, nil case int64: var arr []int64 for _, val := range v { arr = append(arr, val.(int64)) } - return qvalue.QValue{Kind: qvalue.QValueKindArrayInt64, Value: arr}, nil + return qvalue.QValueArrayInt64{Val: arr}, nil case float32: var arr []float32 for _, val := range v { arr = append(arr, val.(float32)) } - return qvalue.QValue{Kind: qvalue.QValueKindArrayFloat32, Value: arr}, nil + return qvalue.QValueArrayFloat32{Val: arr}, nil case float64: var arr []float64 for _, val := range v { arr = append(arr, val.(float64)) } - return qvalue.QValue{Kind: qvalue.QValueKindArrayFloat64, Value: arr}, nil + return qvalue.QValueArrayFloat64{Val: arr}, nil case string: var arr []string for _, val := range v { arr = append(arr, val.(string)) } - return qvalue.QValue{Kind: qvalue.QValueKindArrayString, Value: arr}, nil + return qvalue.QValueArrayString{Val: arr}, nil case time.Time: var arr []time.Time for _, val := range v { arr = append(arr, val.(time.Time)) } - return qvalue.QValue{Kind: qvalue.QValueKindArrayTimestamp, Value: arr}, nil + return qvalue.QValueArrayTimestamp{Val: arr}, nil case civil.Date: - var arr []civil.Date + var arr []time.Time for _, val := range v { - arr = append(arr, val.(civil.Date)) + arr = append(arr, val.(civil.Date).In(time.UTC)) } - return qvalue.QValue{Kind: qvalue.QValueKindArrayDate, Value: arr}, nil + return qvalue.QValueArrayDate{Val: arr}, nil case bool: var arr []bool - for _, val := range v { arr = append(arr, val.(bool)) } - return qvalue.QValue{Kind: qvalue.QValueKindArrayBoolean, Value: arr}, nil + return qvalue.QValueArrayBoolean{Val: arr}, nil default: // If type is unsupported, return error - return qvalue.QValue{}, fmt.Errorf("bqHelper unsupported type %T", et) + return nil, fmt.Errorf("bqHelper unsupported type %T", et) } case nil: - return qvalue.QValue{Kind: qvalue.QValueKindInvalid, Value: nil}, nil + return qvalue.QValueNull(qvalue.QValueKindInvalid), nil default: // If type is unsupported, return error - return qvalue.QValue{}, fmt.Errorf("bqHelper unsupported type %T", v) + return nil, fmt.Errorf("bqHelper unsupported type %T", v) } } @@ -512,5 +514,13 @@ func (b *BigQueryTestHelper) RunInt64Query(query string) (int64, error) { return 0, fmt.Errorf("expected only 1 record, got %d", len(recordBatch.Records)) } - return recordBatch.Records[0][0].Value.(int64), nil + switch v := recordBatch.Records[0][0].(type) { + case qvalue.QValueInt16: + return int64(v.Val), nil + case qvalue.QValueInt32: + return int64(v.Val), nil + case qvalue.QValueInt64: + return v.Val, nil + } + return 0, fmt.Errorf("non-integer result: %T", recordBatch.Records[0][0]) } diff --git a/flow/e2e/bigquery/peer_flow_bq_test.go b/flow/e2e/bigquery/peer_flow_bq_test.go index 51ba631e60..206f71ea27 100644 --- a/flow/e2e/bigquery/peer_flow_bq_test.go +++ b/flow/e2e/bigquery/peer_flow_bq_test.go @@ -29,14 +29,14 @@ func (s PeerFlowE2ETestSuiteBQ) checkJSONValue(tableName, colName, fieldName, va "SELECT `%s`.%s FROM `%s.%s`;", colName, fieldName, s.bqHelper.Config.DatasetId, tableName)) if err != nil { - return fmt.Errorf("json value check failed: %v", err) + return fmt.Errorf("json value check failed: %w", err) } if len(res.Records) == 0 { return fmt.Errorf("bad json: empty result set from %s", tableName) } - jsonVal := res.Records[0][0].Value + jsonVal := res.Records[0][0].Value() if jsonVal != value { return fmt.Errorf("bad json value in field %s of column %s: %v. expected: %v", fieldName, colName, jsonVal, value) } @@ -69,20 +69,8 @@ func (s *PeerFlowE2ETestSuiteBQ) checkPeerdbColumns(dstQualified string, softDel for _, record := range recordBatch.Records { for _, entry := range record { - if entry.Kind == qvalue.QValueKindBoolean { - isDeleteVal, ok := entry.Value.(bool) - if !(ok && isDeleteVal) { - return errors.New("peerdb column failed: _PEERDB_IS_DELETED is not true") - } - recordCount += 1 - } - - if entry.Kind == qvalue.QValueKindTimestamp { - _, ok := entry.Value.(time.Time) - if !ok { - return errors.New("peerdb column failed: _PEERDB_SYNCED_AT is not valid") - } - + switch entry.(type) { + case qvalue.QValueBoolean, qvalue.QValueTimestamp: recordCount += 1 } } @@ -455,14 +443,17 @@ func (s PeerFlowE2ETestSuiteBQ) Test_Types_BQ() { // check if JSON on bigquery side is a good JSON if err := s.checkJSONValue(dstTableName, "c17", "sai", "-8.021390374331551"); err != nil { + s.t.Log(err) return false } // check if HSTORE on bigquery side is a good JSON if err := s.checkJSONValue(dstTableName, "c46", "key1", "\"value1\""); err != nil { + s.t.Log(err) return false } if err := s.checkJSONValue(dstTableName, "c46", "key2", "null"); err != nil { + s.t.Log(err) return false } diff --git a/flow/e2e/snowflake/qrep_flow_sf_test.go b/flow/e2e/snowflake/qrep_flow_sf_test.go index d7ce60d81b..2d0d8c5d3a 100644 --- a/flow/e2e/snowflake/qrep_flow_sf_test.go +++ b/flow/e2e/snowflake/qrep_flow_sf_test.go @@ -29,7 +29,7 @@ func (s PeerFlowE2ETestSuiteSF) checkJSONValue(tableName, colName, fieldName, va return fmt.Errorf("bad json: empty result set from %s", tableName) } - jsonVal := res.Records[0][0].Value + jsonVal := res.Records[0][0].Value() if jsonVal != value { return fmt.Errorf("bad json value in field %s of column %s: %v. expected: %v", fieldName, colName, jsonVal, value) } diff --git a/flow/e2e/snowflake/snowflake_helper.go b/flow/e2e/snowflake/snowflake_helper.go index 14ca9dc35f..c2a6001b01 100644 --- a/flow/e2e/snowflake/snowflake_helper.go +++ b/flow/e2e/snowflake/snowflake_helper.go @@ -6,9 +6,6 @@ import ( "errors" "fmt" "os" - "time" - - "github.com/shopspring/decimal" connsnowflake "github.com/PeerDB-io/peer-flow/connectors/snowflake" "github.com/PeerDB-io/peer-flow/e2eshared" @@ -177,16 +174,15 @@ func (s *SnowflakeTestHelper) RunIntQuery(query string) (int, error) { return 0, fmt.Errorf("failed to execute query: %s, returned %d != 1 columns", query, len(rec)) } - switch rec[0].Kind { - case qvalue.QValueKindInt32: - return int(rec[0].Value.(int32)), nil - case qvalue.QValueKindInt64: - return int(rec[0].Value.(int64)), nil - case qvalue.QValueKindNumeric: - val := rec[0].Value.(decimal.Decimal) - return int(val.IntPart()), nil + switch v := rec[0].(type) { + case qvalue.QValueInt32: + return int(v.Val), nil + case qvalue.QValueInt64: + return int(v.Val), nil + case qvalue.QValueNumeric: + return int(v.Val.IntPart()), nil default: - return 0, fmt.Errorf("failed to execute query: %s, returned value of type %s", query, rec[0].Kind) + return 0, fmt.Errorf("failed to execute query: %s, returned value of type %s", query, rec[0].Kind()) } } @@ -199,12 +195,9 @@ func (s *SnowflakeTestHelper) checkSyncedAt(query string) error { for _, record := range recordBatch.Records { for _, entry := range record { - if entry.Kind != qvalue.QValueKindTimestamp { - return errors.New("synced_at column check failed: _PEERDB_SYNCED_AT is not timestamp") - } - _, ok := entry.Value.(time.Time) + _, ok := entry.(qvalue.QValueTimestamp) if !ok { - return errors.New("synced_at column failed: _PEERDB_SYNCED_AT is not valid") + return errors.New("synced_at column failed: _PEERDB_SYNCED_AT is not a timestamp") } } } diff --git a/flow/e2eshared/e2eshared.go b/flow/e2eshared/e2eshared.go index 087ff58014..9b63b41286 100644 --- a/flow/e2eshared/e2eshared.go +++ b/flow/e2eshared/e2eshared.go @@ -69,8 +69,8 @@ func CheckQRecordEquality(t *testing.T, q []qvalue.QValue, other []qvalue.QValue for i, entry := range q { otherEntry := other[i] - if !entry.Equals(otherEntry) { - t.Logf("entry %d: %T %v != %T %v", i, entry.Value, entry, otherEntry.Value, otherEntry) + if !qvalue.Equals(entry, otherEntry) { + t.Logf("entry %d: %T %+v != %T %+v", i, entry, entry, otherEntry, otherEntry) return false } } diff --git a/flow/hstore/hstore.go b/flow/hstore/hstore.go index cbb7d60c8a..aca1412ba0 100644 --- a/flow/hstore/hstore.go +++ b/flow/hstore/hstore.go @@ -14,9 +14,8 @@ import ( "strings" ) -type text struct { - String string - Valid bool +func text(s string) *string { + return &s } type hstore map[string]*string @@ -150,35 +149,35 @@ func (p *hstoreParser) consumeKVSeparator() error { return p.consumeExpected2('=', '>') } -// consumeDoubleQuotedOrNull consumes the Hstore key/value separator "=>" or returns an error. -func (p *hstoreParser) consumeDoubleQuotedOrNull() (text, error) { +// consumeDoubleQuotedOrNull consumes the string or returns an error. +func (p *hstoreParser) consumeDoubleQuotedOrNull() (*string, error) { // peek at the next byte if p.atEnd() { - return text{}, errors.New("found end instead of value") + return nil, errors.New("found end instead of value") } next := p.str[p.pos] if next == 'N' { // must be the exact string NULL: use consumeExpected2 twice err := p.consumeExpected2('N', 'U') if err != nil { - return text{}, err + return nil, err } err = p.consumeExpected2('L', 'L') if err != nil { - return text{}, err + return nil, err } - return text{String: "", Valid: false}, nil + return nil, nil } else if next != '"' { - return text{}, unexpectedByteErr(next, '"') + return nil, unexpectedByteErr(next, '"') } // skip the double quote p.pos += 1 s, err := p.consumeDoubleQuoted() if err != nil { - return text{}, err + return nil, err } - return text{String: s, Valid: true}, nil + return text(s), nil } func ParseHstore(s string) (string, error) { @@ -217,11 +216,7 @@ func ParseHstore(s string) (string, error) { if err != nil { return "", err } - if value.Valid { - result[key] = &value.String - } else { - result[key] = nil - } + result[key] = value } jsonBytes, err := json.Marshal(result) diff --git a/flow/model/conversion_avro.go b/flow/model/conversion_avro.go index 39e3579f8f..94ea7ddfc3 100644 --- a/flow/model/conversion_avro.go +++ b/flow/model/conversion_avro.go @@ -40,14 +40,12 @@ func (qac *QRecordAvroConverter) Convert() (map[string]interface{}, error) { key := qac.ColNames[idx] _, nullable := qac.NullableFields[key] - avroConverter := qvalue.NewQValueAvroConverter( + avroVal, err := qvalue.QValueToAvro( val, qac.TargetDWH, nullable, qac.logger, ) - - avroVal, err := avroConverter.ToAvroValue() if err != nil { return nil, fmt.Errorf("failed to convert QValue to Avro-compatible value: %w", err) } diff --git a/flow/model/model.go b/flow/model/model.go index 10fe95d5a7..0754db0c66 100644 --- a/flow/model/model.go +++ b/flow/model/model.go @@ -62,7 +62,7 @@ type ToJSONOptions struct { HStoreAsJSON bool } -func NewToJSONOptions(unnestCols []string, hstoreAsJSON bool) *ToJSONOptions { +func NewToJSONOptions(unnestCols []string, hstoreAsJSON bool) ToJSONOptions { var unnestColumns map[string]struct{} if len(unnestCols) != 0 { unnestColumns = make(map[string]struct{}, len(unnestCols)) @@ -70,7 +70,7 @@ func NewToJSONOptions(unnestCols []string, hstoreAsJSON bool) *ToJSONOptions { unnestColumns[col] = struct{}{} } } - return &ToJSONOptions{ + return ToJSONOptions{ UnnestColumns: unnestColumns, HStoreAsJSON: hstoreAsJSON, } diff --git a/flow/model/qrecord_batch.go b/flow/model/qrecord_batch.go index dd55ef7ecc..eabd187ade 100644 --- a/flow/model/qrecord_batch.go +++ b/flow/model/qrecord_batch.go @@ -9,7 +9,6 @@ import ( "github.com/google/uuid" "github.com/jackc/pgx/v5/pgtype" - "github.com/shopspring/decimal" "github.com/PeerDB-io/peer-flow/geo" "github.com/PeerDB-io/peer-flow/model/qvalue" @@ -42,7 +41,7 @@ func (q *QRecordBatch) ToQRecordStream(buffer int) (*QRecordStream, error) { } func constructArray[T any](qValue qvalue.QValue, typeName string) (*pgtype.Array[T], error) { - v, ok := qValue.Value.([]T) + v, ok := qValue.Value().([]T) if !ok { return nil, fmt.Errorf("invalid %s value", typeName) } @@ -93,154 +92,67 @@ func (src *QRecordBatchCopyFromSource) Values() ([]interface{}, error) { values := make([]interface{}, numEntries) for i, qValue := range record { - if qValue.Value == nil { + if qValue.Value() == nil { values[i] = nil continue } - switch qValue.Kind { - case qvalue.QValueKindFloat32: - v, ok := qValue.Value.(float32) - if !ok { - src.err = errors.New("invalid float32 value") - return nil, src.err - } - values[i] = v - - case qvalue.QValueKindFloat64: - v, ok := qValue.Value.(float64) - if !ok { - src.err = errors.New("invalid float64 value") - return nil, src.err - } - values[i] = v - - case qvalue.QValueKindInt16, qvalue.QValueKindInt32: - v, ok := qValue.Value.(int32) - if !ok { - src.err = errors.New("invalid int32 value") - return nil, src.err - } - values[i] = v - - case qvalue.QValueKindInt64: - v, ok := qValue.Value.(int64) - if !ok { - src.err = errors.New("invalid int64 value") - return nil, src.err - } - values[i] = v - - case qvalue.QValueKindBoolean: - v, ok := qValue.Value.(bool) - if !ok { - src.err = errors.New("invalid boolean value") - return nil, src.err - } - values[i] = v - - case qvalue.QValueKindQChar: - v, ok := qValue.Value.(uint8) - if !ok { - src.err = errors.New("invalid \"char\" value") - return nil, src.err - } - values[i] = rune(v) - - case qvalue.QValueKindString: - v, ok := qValue.Value.(string) - if !ok { - src.err = errors.New("invalid string value") - return nil, src.err - } - values[i] = v - - case qvalue.QValueKindCIDR, qvalue.QValueKindINET: - v, ok := qValue.Value.(string) + switch v := qValue.(type) { + case qvalue.QValueFloat32: + values[i] = v.Val + case qvalue.QValueFloat64: + values[i] = v.Val + case qvalue.QValueInt16: + values[i] = v.Val + case qvalue.QValueInt32: + values[i] = v.Val + case qvalue.QValueInt64: + values[i] = v.Val + case qvalue.QValueBoolean: + values[i] = v.Val + case qvalue.QValueQChar: + values[i] = rune(v.Val) + case qvalue.QValueString: + values[i] = v.Val + case qvalue.QValueCIDR, qvalue.QValueINET: + str, ok := v.Value().(string) if !ok { src.err = errors.New("invalid INET/CIDR value") return nil, src.err } - values[i] = v + values[i] = str - case qvalue.QValueKindTime: - t, ok := qValue.Value.(time.Time) - if !ok { - src.err = errors.New("invalid Time value") - return nil, src.err - } - time := pgtype.Time{Microseconds: t.UnixMicro(), Valid: true} - values[i] = time - - case qvalue.QValueKindTimestamp: - t, ok := qValue.Value.(time.Time) - if !ok { - src.err = errors.New("invalid ExtendedTime value") - return nil, src.err - } - timestamp := pgtype.Timestamp{Time: t, Valid: true} - values[i] = timestamp - - case qvalue.QValueKindTimestampTZ: - t, ok := qValue.Value.(time.Time) - if !ok { - src.err = errors.New("invalid ExtendedTime value") - return nil, src.err - } - timestampTZ := pgtype.Timestamptz{Time: t, Valid: true} - values[i] = timestampTZ - - case qvalue.QValueKindUUID: - v, ok := qValue.Value.([16]byte) // treat it as byte slice - if !ok { - src.err = fmt.Errorf("invalid UUID value %v", qValue.Value) - return nil, src.err - } - values[i] = uuid.UUID(v) - - case qvalue.QValueKindNumeric: - v, ok := qValue.Value.(decimal.Decimal) - if !ok { - src.err = fmt.Errorf("invalid Numeric value %v", qValue.Value) - return nil, src.err - } - values[i] = v - - case qvalue.QValueKindBytes, qvalue.QValueKindBit: - v, ok := qValue.Value.([]byte) + case qvalue.QValueTime: + values[i] = pgtype.Time{Microseconds: v.Val.UnixMicro(), Valid: true} + case qvalue.QValueTimestamp: + values[i] = pgtype.Timestamp{Time: v.Val, Valid: true} + case qvalue.QValueTimestampTZ: + values[i] = pgtype.Timestamptz{Time: v.Val, Valid: true} + case qvalue.QValueUUID: + values[i] = uuid.UUID(v.Val) + case qvalue.QValueNumeric: + values[i] = v.Val + case qvalue.QValueBytes, qvalue.QValueBit: + bytes, ok := v.Value().([]byte) if !ok { src.err = errors.New("invalid Bytes value") return nil, src.err } - values[i] = v - - case qvalue.QValueKindDate: - t, ok := qValue.Value.(time.Time) - if !ok { - src.err = errors.New("invalid Date value") - return nil, src.err - } - date := pgtype.Date{Time: t, Valid: true} - values[i] = date + values[i] = bytes - case qvalue.QValueKindHStore: - v, ok := qValue.Value.(string) - if !ok { - src.err = errors.New("invalid HStore value") - return nil, src.err - } - - values[i] = v - case qvalue.QValueKindGeography, qvalue.QValueKindGeometry, qvalue.QValueKindPoint: - v, ok := qValue.Value.(string) + case qvalue.QValueDate: + values[i] = pgtype.Date{Time: v.Val, Valid: true} + case qvalue.QValueHStore: + values[i] = v.Val + case qvalue.QValueGeography, qvalue.QValueGeometry, qvalue.QValuePoint: + geoWkt, ok := v.Value().(string) if !ok { src.err = errors.New("invalid Geospatial value") return nil, src.err } - geoWkt := v - if strings.HasPrefix(v, "SRID=") { - _, wkt, found := strings.Cut(v, ";") + if strings.HasPrefix(geoWkt, "SRID=") { + _, wkt, found := strings.Cut(geoWkt, ";") if found { geoWkt = wkt } @@ -253,79 +165,74 @@ func (src *QRecordBatchCopyFromSource) Values() ([]interface{}, error) { } values[i] = wkb - case qvalue.QValueKindArrayString: - v, err := constructArray[string](qValue, "ArrayString") + case qvalue.QValueArrayString: + a, err := constructArray[string](qValue, "ArrayString") if err != nil { src.err = err return nil, src.err } - values[i] = v + values[i] = a - case qvalue.QValueKindArrayDate, qvalue.QValueKindArrayTimestamp, qvalue.QValueKindArrayTimestampTZ: - v, err := constructArray[time.Time](qValue, "ArrayTime") + case qvalue.QValueArrayDate, qvalue.QValueArrayTimestamp, qvalue.QValueArrayTimestampTZ: + a, err := constructArray[time.Time](qValue, "ArrayTime") if err != nil { src.err = err return nil, src.err } - values[i] = v + values[i] = a - case qvalue.QValueKindArrayInt16: - v, err := constructArray[int16](qValue, "ArrayInt16") + case qvalue.QValueArrayInt16: + a, err := constructArray[int16](qValue, "ArrayInt16") if err != nil { src.err = err return nil, src.err } - values[i] = v + values[i] = a - case qvalue.QValueKindArrayInt32: - v, err := constructArray[int32](qValue, "ArrayInt32") + case qvalue.QValueArrayInt32: + a, err := constructArray[int32](qValue, "ArrayInt32") if err != nil { src.err = err return nil, src.err } - values[i] = v + values[i] = a - case qvalue.QValueKindArrayInt64: - v, err := constructArray[int64](qValue, "ArrayInt64") + case qvalue.QValueArrayInt64: + a, err := constructArray[int64](qValue, "ArrayInt64") if err != nil { src.err = err return nil, src.err } - values[i] = v + values[i] = a - case qvalue.QValueKindArrayFloat32: - v, err := constructArray[float32](qValue, "ArrayFloat32") + case qvalue.QValueArrayFloat32: + a, err := constructArray[float32](qValue, "ArrayFloat32") if err != nil { src.err = err return nil, src.err } - values[i] = v + values[i] = a - case qvalue.QValueKindArrayFloat64: - v, err := constructArray[float64](qValue, "ArrayFloat64") + case qvalue.QValueArrayFloat64: + a, err := constructArray[float64](qValue, "ArrayFloat64") if err != nil { src.err = err return nil, src.err } - values[i] = v - case qvalue.QValueKindArrayBoolean: - v, err := constructArray[bool](qValue, "ArrayBool") + values[i] = a + case qvalue.QValueArrayBoolean: + a, err := constructArray[bool](qValue, "ArrayBool") if err != nil { src.err = err return nil, src.err } - values[i] = v - case qvalue.QValueKindJSON: - v, ok := qValue.Value.(string) - if !ok { - src.err = errors.New("invalid JSON value") - return nil, src.err - } - values[i] = v + values[i] = a + case qvalue.QValueJSON: + values[i] = v.Val // And so on for the other types... default: - src.err = fmt.Errorf("unsupported value type %s", qValue.Kind) + src.err = fmt.Errorf("unsupported value type %T", qValue) return nil, src.err } } diff --git a/flow/model/qrecord_stream.go b/flow/model/qrecord_stream.go index 97546ce247..0feafe5502 100644 --- a/flow/model/qrecord_stream.go +++ b/flow/model/qrecord_stream.go @@ -51,10 +51,6 @@ func (r *RecordsToStreamRequest) GetRecords() <-chan Record { return r.records } -type RecordsToStreamResponse struct { - Stream *QRecordStream -} - func NewQRecordStream(buffer int) *QRecordStream { return &QRecordStream{ schema: make(chan QRecordSchemaOrError, 1), diff --git a/flow/model/qrecord_test.go b/flow/model/qrecord_test.go index e6c769fd69..a373452b9e 100644 --- a/flow/model/qrecord_test.go +++ b/flow/model/qrecord_test.go @@ -23,26 +23,26 @@ func TestEquals(t *testing.T) { }{ { name: "Equal - Same UUID", - q1: []qvalue.QValue{{Kind: qvalue.QValueKindUUID, Value: uuidVal1}}, - q2: []qvalue.QValue{{Kind: qvalue.QValueKindString, Value: uuidVal1.String()}}, + q1: []qvalue.QValue{qvalue.QValueUUID{Val: uuidVal1}}, + q2: []qvalue.QValue{qvalue.QValueString{Val: uuidVal1.String()}}, want: true, }, { name: "Not Equal - Different UUID", - q1: []qvalue.QValue{{Kind: qvalue.QValueKindUUID, Value: uuidVal1}}, - q2: []qvalue.QValue{{Kind: qvalue.QValueKindUUID, Value: uuidVal2}}, + q1: []qvalue.QValue{qvalue.QValueUUID{Val: uuidVal1}}, + q2: []qvalue.QValue{qvalue.QValueUUID{Val: uuidVal2}}, want: false, }, { name: "Equal - Same numeric", - q1: []qvalue.QValue{{Kind: qvalue.QValueKindNumeric, Value: decimal.NewFromInt(5)}}, - q2: []qvalue.QValue{{Kind: qvalue.QValueKindString, Value: "5"}}, + q1: []qvalue.QValue{qvalue.QValueNumeric{Val: decimal.NewFromInt(5)}}, + q2: []qvalue.QValue{qvalue.QValueString{Val: "5"}}, want: true, }, { name: "Not Equal - Different numeric", - q1: []qvalue.QValue{{Kind: qvalue.QValueKindNumeric, Value: decimal.NewFromInt(5)}}, - q2: []qvalue.QValue{{Kind: qvalue.QValueKindString, Value: "4.99"}}, + q1: []qvalue.QValue{qvalue.QValueNumeric{Val: decimal.NewFromInt(5)}}, + q2: []qvalue.QValue{qvalue.QValueString{Val: "4.99"}}, want: false, }, } diff --git a/flow/model/qvalue/avro_converter.go b/flow/model/qvalue/avro_converter.go index 3df8738209..536e705db6 100644 --- a/flow/model/qvalue/avro_converter.go +++ b/flow/model/qvalue/avro_converter.go @@ -162,34 +162,30 @@ func GetAvroSchemaFromQValueKind(kind QValueKind, targetDWH QDWHType, precision } type QValueAvroConverter struct { - QValue TargetDWH QDWHType Nullable bool logger log.Logger } -func NewQValueAvroConverter(value QValue, targetDWH QDWHType, nullable bool, logger log.Logger) *QValueAvroConverter { - return &QValueAvroConverter{ - QValue: value, +func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Logger) (interface{}, error) { + if nullable && value.Value() == nil { + return nil, nil + } + + c := &QValueAvroConverter{ TargetDWH: targetDWH, Nullable: nullable, logger: logger, } -} - -func (c *QValueAvroConverter) ToAvroValue() (interface{}, error) { - if c.Nullable && c.Value == nil { - return nil, nil - } - switch c.Kind { - case QValueKindInvalid: + switch v := value.(type) { + case QValueInvalid: // we will attempt to convert invalid to a string - return c.processNullableUnion("string", c.Value) - case QValueKindTime: - t, err := c.processGoTime() - if err != nil || t == nil { - return t, err + return c.processNullableUnion("string", v.Val) + case QValueTime: + t := c.processGoTime(v.Val) + if t == nil { + return nil, nil } if c.TargetDWH == QDWHTypeSnowflake { @@ -211,10 +207,10 @@ func (c *QValueAvroConverter) ToAvroValue() (interface{}, error) { return goavro.Union("long.time-micros", t.(int64)), nil } return t.(int64), nil - case QValueKindTimeTZ: - t, err := c.processGoTimeTZ() - if err != nil || t == nil { - return t, err + case QValueTimeTZ: + t := c.processGoTimeTZ(v.Val) + if t == nil { + return nil, nil } if c.TargetDWH == QDWHTypeSnowflake { if c.Nullable { @@ -235,10 +231,10 @@ func (c *QValueAvroConverter) ToAvroValue() (interface{}, error) { return goavro.Union("long.time-micros", t.(int64)), nil } return t.(int64), nil - case QValueKindTimestamp: - t, err := c.processGoTimestamp() - if err != nil || t == nil { - return t, err + case QValueTimestamp: + t := c.processGoTimestamp(v.Val) + if t == nil { + return nil, nil } if c.TargetDWH == QDWHTypeSnowflake { if c.Nullable { @@ -252,10 +248,10 @@ func (c *QValueAvroConverter) ToAvroValue() (interface{}, error) { return goavro.Union("long.timestamp-micros", t.(int64)), nil } return t.(int64), nil - case QValueKindTimestampTZ: - t, err := c.processGoTimestampTZ() - if err != nil || t == nil { - return t, err + case QValueTimestampTZ: + t := c.processGoTimestampTZ(v.Val) + if t == nil { + return nil, nil } if c.TargetDWH == QDWHTypeSnowflake { if c.Nullable { @@ -269,10 +265,10 @@ func (c *QValueAvroConverter) ToAvroValue() (interface{}, error) { return goavro.Union("long.timestamp-micros", t.(int64)), nil } return t.(int64), nil - case QValueKindDate: - t, err := c.processGoDate() - if err != nil || t == nil { - return t, err + case QValueDate: + t := c.processGoDate(v.Val) + if t == nil { + return nil, nil } if c.TargetDWH == QDWHTypeSnowflake { @@ -287,191 +283,135 @@ func (c *QValueAvroConverter) ToAvroValue() (interface{}, error) { return goavro.Union("int.date", t), nil } return t, nil - case QValueKindQChar: - return c.processNullableUnion("string", string(c.Value.(uint8))) - case QValueKindString, QValueKindCIDR, QValueKindINET, QValueKindMacaddr, QValueKindInterval: - if c.TargetDWH == QDWHTypeSnowflake && c.Value != nil && - (len(c.Value.(string)) > 15*1024*1024) { + case QValueQChar: + return c.processNullableUnion("string", string(v.Val)) + case QValueString, QValueCIDR, QValueINET, QValueMacaddr, QValueInterval: + if c.TargetDWH == QDWHTypeSnowflake && v.Value() != nil && + (len(v.Value().(string)) > 15*1024*1024) { slog.Warn("Truncating TEXT value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") return c.processNullableUnion("string", "") } - return c.processNullableUnion("string", c.Value) - case QValueKindFloat32: + return c.processNullableUnion("string", v.Value()) + case QValueFloat32: if c.TargetDWH == QDWHTypeBigQuery { - return c.processNullableUnion("double", c.Value) - } - return c.processNullableUnion("float", c.Value) - case QValueKindFloat64: - if c.TargetDWH == QDWHTypeSnowflake || c.TargetDWH == QDWHTypeBigQuery { - if f32Val, ok := c.Value.(float32); ok { - return c.processNullableUnion("double", float64(f32Val)) - } - } - return c.processNullableUnion("double", c.Value) - case QValueKindInt16, QValueKindInt32, QValueKindInt64: - return c.processNullableUnion("long", c.Value) - case QValueKindBoolean: - return c.processNullableUnion("boolean", c.Value) - case QValueKindStruct: - return nil, errors.New("QValueKindStruct not supported") - case QValueKindNumeric: - return c.processNumeric() - case QValueKindBytes, QValueKindBit: - return c.processBytes() - case QValueKindJSON: - return c.processJSON() - case QValueKindHStore: - return c.processHStore() - case QValueKindArrayFloat32: - return c.processArrayFloat32() - case QValueKindArrayFloat64: - return c.processArrayFloat64() - case QValueKindArrayInt16: - return c.processArrayInt16() - case QValueKindArrayInt32: - return c.processArrayInt32() - case QValueKindArrayInt64: - return c.processArrayInt64() - case QValueKindArrayString: - return c.processArrayString() - case QValueKindArrayBoolean: - return c.processArrayBoolean() - case QValueKindArrayTimestamp, QValueKindArrayTimestampTZ: - arrayTime, err := c.processArrayTime() - if err != nil || arrayTime == nil { - return arrayTime, err - } - - return arrayTime, nil - case QValueKindArrayDate: - arrayDate, err := c.processArrayDate() - if err != nil || arrayDate == nil { - return arrayDate, err - } - - return arrayDate, nil - case QValueKindUUID: - return c.processUUID() - case QValueKindGeography, QValueKindGeometry, QValueKindPoint: - return c.processGeospatial() + return c.processNullableUnion("double", float64(v.Val)) + } + return c.processNullableUnion("float", v.Val) + case QValueFloat64: + return c.processNullableUnion("double", v.Val) + case QValueInt16: + return c.processNullableUnion("long", int32(v.Val)) + case QValueInt32, QValueInt64: + return c.processNullableUnion("long", v.Value()) + case QValueBoolean: + return c.processNullableUnion("boolean", v.Val) + case QValueStruct: + return nil, errors.New("QValueStruct not supported") + case QValueNumeric: + return c.processNumeric(v.Val), nil + case QValueBytes: + return c.processBytes(v.Val), nil + case QValueBit: + return c.processBytes(v.Val), nil + case QValueJSON: + return c.processJSON(v.Val) + case QValueHStore: + return c.processHStore(v.Val) + case QValueArrayFloat32: + return c.processArrayFloat32(v.Val), nil + case QValueArrayFloat64: + return c.processArrayFloat64(v.Val), nil + case QValueArrayInt16: + return c.processArrayInt16(v.Val), nil + case QValueArrayInt32: + return c.processArrayInt32(v.Val), nil + case QValueArrayInt64: + return c.processArrayInt64(v.Val), nil + case QValueArrayString: + return c.processArrayString(v.Val), nil + case QValueArrayBoolean: + return c.processArrayBoolean(v.Val), nil + case QValueArrayTimestamp, QValueArrayTimestampTZ: + return c.processArrayTime(v.Value().([]time.Time)), nil + case QValueArrayDate: + return c.processArrayDate(v.Val), nil + case QValueUUID: + return c.processUUID(v.Val), nil + case QValueGeography, QValueGeometry, QValuePoint: + return c.processGeospatial(v.Value().(string)), nil default: - return nil, fmt.Errorf("[toavro] unsupported QValueKind: %s", c.Kind) + return nil, fmt.Errorf("[toavro] unsupported %T", value) } } -func (c *QValueAvroConverter) processGoTimeTZ() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - t, ok := c.Value.(time.Time) - if !ok { - return nil, errors.New("invalid TimeTZ value") - } - +func (c *QValueAvroConverter) processGoTimeTZ(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file if c.TargetDWH == QDWHTypeSnowflake { - return t.Format("15:04:05.999999-0700"), nil + return t.Format("15:04:05.999999-0700") } - return t.UnixMicro(), nil + return t.UnixMicro() } -func (c *QValueAvroConverter) processGoTime() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - t, ok := c.Value.(time.Time) - if !ok { - return nil, errors.New("invalid Time value") - } - +func (c *QValueAvroConverter) processGoTime(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file if c.TargetDWH == QDWHTypeSnowflake { - return t.Format("15:04:05.999999"), nil + return t.Format("15:04:05.999999") } if c.TargetDWH == QDWHTypeClickhouse { - return t.Format("15:04:05.999999"), nil + return t.Format("15:04:05.999999") } - return t.UnixMicro(), nil + return t.UnixMicro() } -func (c *QValueAvroConverter) processGoTimestampTZ() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - t, ok := c.Value.(time.Time) - if !ok { - return nil, errors.New("invalid TimestampTZ value") - } - +func (c *QValueAvroConverter) processGoTimestampTZ(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file if c.TargetDWH == QDWHTypeSnowflake { - return t.Format("2006-01-02 15:04:05.999999-0700"), nil + return t.Format("2006-01-02 15:04:05.999999-0700") } // Bigquery will not allow timestamp if it is less than 1AD and more than 9999AD // So make such timestamps null if DisallowedTimestamp(c.TargetDWH, t, c.logger) { - return nil, nil + return nil } - return t.UnixMicro(), nil + return t.UnixMicro() } -func (c *QValueAvroConverter) processGoTimestamp() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - t, ok := c.Value.(time.Time) - if !ok { - return nil, errors.New("invalid Timestamp value") - } - +func (c *QValueAvroConverter) processGoTimestamp(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file if c.TargetDWH == QDWHTypeSnowflake { - return t.Format("2006-01-02 15:04:05.999999"), nil + return t.Format("2006-01-02 15:04:05.999999") } // Bigquery will not allow timestamp if it is less than 1AD and more than 9999AD // So make such timestamps null if DisallowedTimestamp(c.TargetDWH, t, c.logger) { - return nil, nil + return nil } - return t.UnixMicro(), nil + return t.UnixMicro() } -func (c *QValueAvroConverter) processGoDate() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - t, ok := c.Value.(time.Time) - if !ok { - return nil, errors.New("invalid Time value for Date") - } - +func (c *QValueAvroConverter) processGoDate(t time.Time) interface{} { // Bigquery will not allow Date if it is less than 1AD and more than 9999AD // So make such Dates null if DisallowedTimestamp(c.TargetDWH, t, c.logger) { - return nil, nil + return nil } // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file if c.TargetDWH == QDWHTypeSnowflake { - return t.Format("2006-01-02"), nil + return t.Format("2006-01-02") } - return t, nil + return t } func (c *QValueAvroConverter) processNullableUnion( @@ -487,63 +427,22 @@ func (c *QValueAvroConverter) processNullableUnion( return value, nil } -func (c *QValueAvroConverter) processNumeric() (interface{}, error) { - if c.Value == nil { - return nil, nil - } - - num, ok := c.Value.(decimal.Decimal) - if !ok { - return nil, fmt.Errorf("invalid Numeric value: expected decimal.Decimal, got %T", c.Value) - } +func (c *QValueAvroConverter) processNumeric(num decimal.Decimal) interface{} { rat := num.Rat() - if c.Nullable { - return goavro.Union("bytes.decimal", rat), nil + return goavro.Union("bytes.decimal", rat) } - - return rat, nil + return rat } -func (c *QValueAvroConverter) processBytes() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - if c.TargetDWH == QDWHTypeClickhouse { - bigNum, ok := c.Value.(decimal.Decimal) - if !ok { - return nil, fmt.Errorf("invalid Numeric value: expected float64, got %T", c.Value) - } - num, ok := bigNum.Float64() - if !ok { - return nil, fmt.Errorf("not able to convert bigNum to float64 %+v", bigNum) - } - return goavro.Union("double", num), nil - } - - byteData, ok := c.Value.([]byte) - if !ok { - return nil, errors.New("invalid Bytes value") - } - +func (c *QValueAvroConverter) processBytes(byteData []byte) interface{} { if c.Nullable { - return goavro.Union("bytes", byteData), nil + return goavro.Union("bytes", byteData) } - - return byteData, nil + return byteData } -func (c *QValueAvroConverter) processJSON() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - jsonString, ok := c.Value.(string) - if !ok { - return nil, fmt.Errorf("invalid JSON value %v", c.Value) - } - +func (c *QValueAvroConverter) processJSON(jsonString string) (interface{}, error) { if c.Nullable { if c.TargetDWH == QDWHTypeSnowflake && len(jsonString) > 15*1024*1024 { slog.Warn("Truncating JSON value > 15MB for Snowflake!") @@ -561,33 +460,15 @@ func (c *QValueAvroConverter) processJSON() (interface{}, error) { return jsonString, nil } -func (c *QValueAvroConverter) processArrayBoolean() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayData, ok := c.Value.([]bool) - if !ok { - return nil, errors.New("invalid Boolean array value") - } - +func (c *QValueAvroConverter) processArrayBoolean(arrayData []bool) interface{} { if c.Nullable { - return goavro.Union("array", arrayData), nil + return goavro.Union("array", arrayData) } - return arrayData, nil + return arrayData } -func (c *QValueAvroConverter) processArrayTime() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayTime, ok := c.Value.([]time.Time) - if !ok { - return nil, errors.New("invalid Timestamp array value") - } - +func (c *QValueAvroConverter) processArrayTime(arrayTime []time.Time) interface{} { transformedTimeArr := make([]interface{}, 0, len(arrayTime)) for _, t := range arrayTime { // Snowflake has issues with avro timestamp types, returning as string form @@ -600,22 +481,13 @@ func (c *QValueAvroConverter) processArrayTime() (interface{}, error) { } if c.Nullable { - return goavro.Union("array", transformedTimeArr), nil + return goavro.Union("array", transformedTimeArr) } - return transformedTimeArr, nil + return transformedTimeArr } -func (c *QValueAvroConverter) processArrayDate() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayDate, ok := c.Value.([]time.Time) - if !ok { - return nil, errors.New("invalid Date array value") - } - +func (c *QValueAvroConverter) processArrayDate(arrayDate []time.Time) interface{} { transformedTimeArr := make([]interface{}, 0, len(arrayDate)) for _, t := range arrayDate { if c.TargetDWH == QDWHTypeSnowflake { @@ -626,25 +498,16 @@ func (c *QValueAvroConverter) processArrayDate() (interface{}, error) { } if c.Nullable { - return goavro.Union("array", transformedTimeArr), nil + return goavro.Union("array", transformedTimeArr) } - return transformedTimeArr, nil + return transformedTimeArr } -func (c *QValueAvroConverter) processHStore() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - hstoreString, ok := c.Value.(string) - if !ok { - return nil, fmt.Errorf("invalid HSTORE value %v", c.Value) - } - - jsonString, err := hstore_util.ParseHstore(hstoreString) +func (c *QValueAvroConverter) processHStore(hstore string) (interface{}, error) { + jsonString, err := hstore_util.ParseHstore(hstore) if err != nil { - return "", err + return "", fmt.Errorf("cannot parse %s: %w", hstore, err) } if c.Nullable { @@ -664,60 +527,22 @@ func (c *QValueAvroConverter) processHStore() (interface{}, error) { return jsonString, nil } -func (c *QValueAvroConverter) processUUID() (interface{}, error) { - if c.Value == nil { - return nil, nil - } - - byteData, ok := c.Value.([16]byte) - if !ok { - // attempt to convert google.uuid to [16]byte - byteData, ok = c.Value.(uuid.UUID) - if !ok { - return nil, fmt.Errorf("[conversion] invalid UUID value %v", c.Value) - } - } - - u, err := uuid.FromBytes(byteData[:]) - if err != nil { - return nil, fmt.Errorf("[conversion] conversion of invalid UUID value: %w", err) - } - - uuidString := u.String() - +func (c *QValueAvroConverter) processUUID(byteData [16]byte) interface{} { + uuidString := uuid.UUID(byteData).String() if c.Nullable { - return goavro.Union("string", uuidString), nil + return goavro.Union("string", uuidString) } - - return uuidString, nil + return uuidString } -func (c *QValueAvroConverter) processGeospatial() (interface{}, error) { - if c.Value == nil { - return nil, nil - } - - geoString, ok := c.Value.(string) - if !ok { - return nil, fmt.Errorf("[conversion] invalid geospatial value %v", c.Value) - } - +func (c *QValueAvroConverter) processGeospatial(geoString string) interface{} { if c.Nullable { - return goavro.Union("string", geoString), nil + return goavro.Union("string", geoString) } - return geoString, nil + return geoString } -func (c *QValueAvroConverter) processArrayInt16() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayData, ok := c.Value.([]int16) - if !ok { - return nil, errors.New("invalid Int16 array value") - } - +func (c *QValueAvroConverter) processArrayInt16(arrayData []int16) interface{} { // cast to int32 int32Data := make([]int32, 0, len(arrayData)) for _, v := range arrayData { @@ -725,93 +550,43 @@ func (c *QValueAvroConverter) processArrayInt16() (interface{}, error) { } if c.Nullable { - return goavro.Union("array", int32Data), nil + return goavro.Union("array", int32Data) } - return int32Data, nil + return int32Data } -func (c *QValueAvroConverter) processArrayInt32() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayData, ok := c.Value.([]int32) - if !ok { - return nil, errors.New("invalid Int32 array value") - } - +func (c *QValueAvroConverter) processArrayInt32(arrayData []int32) interface{} { if c.Nullable { - return goavro.Union("array", arrayData), nil + return goavro.Union("array", arrayData) } - - return arrayData, nil + return arrayData } -func (c *QValueAvroConverter) processArrayInt64() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayData, ok := c.Value.([]int64) - if !ok { - return nil, errors.New("invalid Int64 array value") - } - +func (c *QValueAvroConverter) processArrayInt64(arrayData []int64) interface{} { if c.Nullable { - return goavro.Union("array", arrayData), nil + return goavro.Union("array", arrayData) } - - return arrayData, nil + return arrayData } -func (c *QValueAvroConverter) processArrayFloat32() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayData, ok := c.Value.([]float32) - if !ok { - return nil, errors.New("invalid Float32 array value") - } - +func (c *QValueAvroConverter) processArrayFloat32(arrayData []float32) interface{} { if c.Nullable { - return goavro.Union("array", arrayData), nil + return goavro.Union("array", arrayData) } - - return arrayData, nil + return arrayData } -func (c *QValueAvroConverter) processArrayFloat64() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayData, ok := c.Value.([]float64) - if !ok { - return nil, errors.New("invalid Float64 array value") - } - +func (c *QValueAvroConverter) processArrayFloat64(arrayData []float64) interface{} { if c.Nullable { - return goavro.Union("array", arrayData), nil + return goavro.Union("array", arrayData) } - - return arrayData, nil + return arrayData } -func (c *QValueAvroConverter) processArrayString() (interface{}, error) { - if c.Value == nil && c.Nullable { - return nil, nil - } - - arrayData, ok := c.Value.([]string) - if !ok { - return nil, errors.New("invalid String array value") - } - +func (c *QValueAvroConverter) processArrayString(arrayData []string) interface{} { if c.Nullable { - return goavro.Union("array", arrayData), nil + return goavro.Union("array", arrayData) } - - return arrayData, nil + return arrayData } diff --git a/flow/model/qvalue/equals.go b/flow/model/qvalue/equals.go new file mode 100644 index 0000000000..713f71134a --- /dev/null +++ b/flow/model/qvalue/equals.go @@ -0,0 +1,485 @@ +package qvalue + +import ( + "bytes" + "math" + "math/big" + "reflect" + "slices" + "strconv" + "strings" + "time" + + "github.com/google/uuid" + "github.com/shopspring/decimal" + geom "github.com/twpayne/go-geos" + + hstore_util "github.com/PeerDB-io/peer-flow/hstore" +) + +func valueEmpty(value any) bool { + return value == nil || value == "" || value == "null" || + (reflect.TypeOf(value).Kind() == reflect.Slice && reflect.ValueOf(value).Len() == 0) +} + +func Equals(qv QValue, other QValue) bool { + qvValue := qv.Value() + otherValue := other.Value() + if valueEmpty(qvValue) && valueEmpty(otherValue) { + return true + } + + switch q := qv.(type) { + case QValueInvalid: + return true + case QValueFloat32: + return q.compareFloat32(other) + case QValueFloat64: + return q.compareFloat64(other) + case QValueInt16: + return q.compareInt16(other) + case QValueInt32: + return q.compareInt32(other) + case QValueInt64: + return q.compareInt64(other) + case QValueBoolean: + if otherVal, ok := other.(QValueBoolean); ok { + return q.Val == otherVal.Val + } + return false + case QValueStruct: + if otherVal, ok := other.(QValueStruct); ok { + return q.compareStruct(otherVal) + } + return false + case QValueQChar: + if otherVal, ok := other.(QValueQChar); ok { + return q.Val == otherVal.Val + } + return false + case QValueString: + return compareString(q.Val, otherValue) + case QValueINET: + return compareString(q.Val, otherValue) + case QValueCIDR: + return compareString(q.Val, otherValue) + // all internally represented as a Golang time.Time + case QValueDate, QValueTimestamp, QValueTimestampTZ, QValueTime, QValueTimeTZ: + return compareGoTime(qvValue, otherValue) + case QValueNumeric: + return compareNumeric(q.Val, otherValue) + case QValueBytes: + return compareBytes(qvValue, otherValue) + case QValueUUID: + return compareUUID(qvValue, otherValue) + case QValueJSON: + // TODO (kaushik): fix for tests + return true + case QValueBit: + return compareBytes(qvValue, otherValue) + case QValueGeometry: + return compareGeometry(q.Val, otherValue) + case QValueGeography: + return compareGeometry(q.Val, otherValue) + case QValueHStore: + return compareHStore(q.Val, otherValue) + case QValueArrayInt32, QValueArrayInt16, QValueArrayInt64, QValueArrayFloat32, QValueArrayFloat64: + return compareNumericArrays(qvValue, otherValue) + case QValueArrayDate: + return compareDateArrays(q.Val, otherValue) + case QValueArrayTimestamp, QValueArrayTimestampTZ: + return compareTimeArrays(qvValue, otherValue) + case QValueArrayBoolean: + return compareBoolArrays(q.Val, otherValue) + case QValueArrayString: + return compareArrayString(q.Val, otherValue) + default: + return false + } +} + +func (v QValueInt16) compareInt16(value2 QValue) bool { + int2, ok2 := getInt16(value2.Value()) + return ok2 && v.Val == int2 +} + +func (v QValueInt32) compareInt32(value2 QValue) bool { + int2, ok2 := getInt32(value2.Value()) + return ok2 && v.Val == int2 +} + +func (v QValueInt64) compareInt64(value2 QValue) bool { + int2, ok2 := getInt64(value2.Value()) + return ok2 && v.Val == int2 +} + +func (v QValueFloat32) compareFloat32(value2 QValue) bool { + float2, ok2 := getFloat32(value2.Value()) + return ok2 && v.Val == float2 +} + +func (v QValueFloat64) compareFloat64(value2 QValue) bool { + float2, ok2 := getFloat64(value2.Value()) + return ok2 && v.Val == float2 +} + +func compareString(s1 string, value2 interface{}) bool { + s2, ok := value2.(string) + return ok && s1 == s2 +} + +func compareGoTime(value1, value2 interface{}) bool { + et1, ok1 := value1.(time.Time) + et2, ok2 := value2.(time.Time) + + if !ok1 || !ok2 { + return false + } + + // TODO: this is a hack, we should be comparing the actual time values + // currently this is only used for testing so that is OK. + t1 := et1.UnixMicro() + t2 := et2.UnixMicro() + + return t1 == t2 +} + +func compareUUID(value1, value2 interface{}) bool { + uuid1, ok1 := getUUID(value1) + uuid2, ok2 := getUUID(value2) + + return ok1 && ok2 && uuid1 == uuid2 +} + +func compareBytes(value1, value2 interface{}) bool { + bytes1, ok1 := getBytes(value1) + bytes2, ok2 := getBytes(value2) + + return ok1 && ok2 && bytes.Equal(bytes1, bytes2) +} + +func compareNumeric(value1, value2 interface{}) bool { + num1, ok1 := getDecimal(value1) + num2, ok2 := getDecimal(value2) + + if !ok1 || !ok2 { + return false + } + + return num1.Equal(num2) +} + +func compareHStore(str1 string, value2 interface{}) bool { + str2 := value2.(string) + if str1 == str2 { + return true + } + parsedHStore1, err := hstore_util.ParseHstore(str1) + if err != nil { + panic(err) + } + return parsedHStore1 == strings.ReplaceAll(strings.ReplaceAll(str2, " ", ""), "\n", "") +} + +func compareGeometry(geoWkt string, value2 interface{}) bool { + geo2, err := geom.NewGeomFromWKT(value2.(string)) + if err != nil { + panic(err) + } + + if strings.HasPrefix(geoWkt, "SRID=") { + _, wkt, found := strings.Cut(geoWkt, ";") + if found { + geoWkt = wkt + } + } + + geo1, err := geom.NewGeomFromWKT(geoWkt) + if err != nil { + panic(err) + } + return geo1.Equals(geo2) +} + +func (v QValueStruct) compareStruct(value2 QValueStruct) bool { + struct1 := v.Val + struct2 := value2.Val + if len(struct1) != len(struct2) { + return false + } + for k, v1 := range struct1 { + v2, ok := struct2[k] + if !ok { + return false + } + q1, ok1 := v1.(QValue) + q2, ok2 := v2.(QValue) + if !ok1 || !ok2 || !Equals(q1, q2) { + return false + } + } + return true +} + +func compareNumericArrays(value1, value2 interface{}) bool { + // Helper function to convert a value to float64 + convertToFloat64 := func(val interface{}) []float64 { + switch v := val.(type) { + case []int16: + result := make([]float64, len(v)) + for i, value := range v { + result[i] = float64(value) + } + return result + case []int32: + result := make([]float64, len(v)) + for i, value := range v { + result[i] = float64(value) + } + return result + case []int64: + result := make([]float64, len(v)) + for i, value := range v { + result[i] = float64(value) + } + return result + case []float32: + result := make([]float64, len(v)) + for i, value := range v { + result[i] = float64(value) + } + return result + case []float64: + return v + default: + return nil + } + } + + array1 := convertToFloat64(value1) + array2 := convertToFloat64(value2) + + if array1 == nil || array2 == nil || len(array1) != len(array2) { + return false + } + + for i := range array1 { + if math.Abs(array1[i]-array2[i]) >= 1e9 { + return false + } + } + + return true +} + +func compareTimeArrays(value1, value2 interface{}) bool { + array1, ok1 := value1.([]time.Time) + array2, ok2 := value2.([]time.Time) + + if !ok1 || !ok2 || len(array1) != len(array2) { + return false + } + + for i := range array1 { + if !array1[i].Equal(array2[i]) { + return false + } + } + return true +} + +func compareDateArrays(value1, value2 interface{}) bool { + array1, ok1 := value1.([]time.Time) + array2, ok2 := value2.([]time.Time) + + if !ok1 || !ok2 || len(array1) != len(array2) { + return false + } + + for i := range array1 { + if array1[i].Year() != array2[i].Year() || + array1[i].Month() != array2[i].Month() || + array1[i].Day() != array2[i].Day() { + return false + } + } + return true +} + +func compareBoolArrays(value1, value2 interface{}) bool { + array1, ok1 := value1.([]bool) + array2, ok2 := value2.([]bool) + + if !ok1 || !ok2 || len(array1) != len(array2) { + return false + } + + for i := range array1 { + if array1[i] != array2[i] { + return false + } + } + return true +} + +func compareArrayString(value1, value2 interface{}) bool { + array1, ok1 := value1.([]string) + array2, ok2 := value2.([]string) + + if !ok1 || !ok2 { + return false + } + + return slices.Compare(array1, array2) == 0 +} + +func getInt16(v interface{}) (int16, bool) { + switch value := v.(type) { + case int16: + return value, true + case int32: + return int16(value), true + case int64: + return int16(value), true + case decimal.Decimal: + return int16(value.IntPart()), true + case string: + parsed, err := strconv.ParseInt(value, 10, 16) + if err == nil { + return int16(parsed), true + } + } + return 0, false +} + +func getInt32(v interface{}) (int32, bool) { + switch value := v.(type) { + case int32: + return value, true + case int64: + return int32(value), true + case decimal.Decimal: + return int32(value.IntPart()), true + case string: + parsed, err := strconv.ParseInt(value, 10, 32) + if err == nil { + return int32(parsed), true + } + } + return 0, false +} + +func getInt64(v interface{}) (int64, bool) { + switch value := v.(type) { + case int64: + return value, true + case int32: + return int64(value), true + case decimal.Decimal: + return value.IntPart(), true + case string: + parsed, err := strconv.ParseInt(value, 10, 64) + if err == nil { + return parsed, true + } + } + return 0, false +} + +func getFloat32(v interface{}) (float32, bool) { + switch value := v.(type) { + case float32: + return value, true + case float64: + return float32(value), true + case string: + parsed, err := strconv.ParseFloat(value, 32) + if err == nil { + return float32(parsed), true + } + } + return 0, false +} + +func getFloat64(v interface{}) (float64, bool) { + switch value := v.(type) { + case float64: + return value, true + case float32: + return float64(value), true + case string: + parsed, err := strconv.ParseFloat(value, 64) + if err == nil { + return parsed, true + } + } + return 0, false +} + +func getBytes(v interface{}) ([]byte, bool) { + switch value := v.(type) { + case []byte: + return value, true + case string: + return []byte(value), true + case nil: + return nil, true + default: + return nil, false + } +} + +func getUUID(v interface{}) (uuid.UUID, bool) { + switch value := v.(type) { + case uuid.UUID: + return value, true + case string: + parsed, err := uuid.Parse(value) + if err == nil { + return parsed, true + } + case [16]byte: + return uuid.UUID(value), true + } + + return uuid.UUID{}, false +} + +// getDecimal attempts to parse a decimal from an interface +func getDecimal(v interface{}) (decimal.Decimal, bool) { + switch value := v.(type) { + case decimal.Decimal: + return value, true + case string: + parsed, err := decimal.NewFromString(value) + if err != nil { + panic(err) + } + return parsed, true + case float64: + return decimal.NewFromFloat(value), true + case int64: + return decimal.NewFromInt(value), true + case uint64: + return decimal.NewFromBigInt(new(big.Int).SetUint64(value), 0), true + case float32: + return decimal.NewFromFloat32(value), true + case int32: + return decimal.NewFromInt(int64(value)), true + case uint32: + return decimal.NewFromInt(int64(value)), true + case int: + return decimal.NewFromInt(int64(value)), true + case uint: + return decimal.NewFromInt(int64(value)), true + case int8: + return decimal.NewFromInt(int64(value)), true + case uint8: + return decimal.NewFromInt(int64(value)), true + case int16: + return decimal.NewFromInt(int64(value)), true + case uint16: + return decimal.NewFromInt(int64(value)), true + } + return decimal.Decimal{}, false +} diff --git a/flow/model/qvalue/kind.go b/flow/model/qvalue/kind.go index 9ed9ac0beb..f07df58383 100644 --- a/flow/model/qvalue/kind.go +++ b/flow/model/qvalue/kind.go @@ -8,7 +8,6 @@ import ( type QValueKind string const ( - QValueKindEmpty QValueKind = "" QValueKindInvalid QValueKind = "invalid" QValueKindFloat32 QValueKind = "float32" QValueKindFloat64 QValueKind = "float64" diff --git a/flow/model/qvalue/qvalue.go b/flow/model/qvalue/qvalue.go index bedc3decec..40ac4b6fc5 100644 --- a/flow/model/qvalue/qvalue.go +++ b/flow/model/qvalue/qvalue.go @@ -1,652 +1,479 @@ package qvalue import ( - "bytes" - "encoding/json" - "fmt" - "math" - "math/big" - "reflect" - "strconv" - "strings" "time" - "cloud.google.com/go/civil" - "github.com/google/uuid" - "github.com/jackc/pgx/v5/pgtype" "github.com/shopspring/decimal" - geom "github.com/twpayne/go-geos" - - hstore_util "github.com/PeerDB-io/peer-flow/hstore" ) // if new types are added, register them in gob - cdc_records_storage.go -type QValue struct { - Kind QValueKind - Value interface{} -} - -func (q QValue) Equals(other QValue) bool { - if q.Kind == QValueKindJSON { - return true // TODO fix - } else if q.Value == nil && other.Value == nil { - return true - } - - switch q.Kind { - case QValueKindEmpty: - return other.Kind == QValueKindEmpty - case QValueKindInvalid: - return true - case QValueKindFloat32: - return compareFloat32(q.Value, other.Value) - case QValueKindFloat64: - return compareFloat64(q.Value, other.Value) - case QValueKindInt16: - return compareInt16(q.Value, other.Value) - case QValueKindInt32: - return compareInt32(q.Value, other.Value) - case QValueKindInt64: - return compareInt64(q.Value, other.Value) - case QValueKindBoolean: - return compareBoolean(q.Value, other.Value) - case QValueKindStruct: - return compareStruct(q.Value, other.Value) - case QValueKindQChar: - if (q.Value == nil) == (other.Value == nil) { - return q.Value == nil || q.Value.(uint8) == other.Value.(uint8) - } else { - return false - } - case QValueKindString, QValueKindINET, QValueKindCIDR: - return compareString(q.Value, other.Value) - // all internally represented as a Golang time.Time - case QValueKindDate, - QValueKindTimestamp, QValueKindTimestampTZ: - return compareGoTime(q.Value, other.Value) - case QValueKindTime, QValueKindTimeTZ: - return compareGoCivilTime(q.Value, other.Value) - case QValueKindNumeric: - return compareNumeric(q.Value, other.Value) - case QValueKindBytes: - return compareBytes(q.Value, other.Value) - case QValueKindUUID: - return compareUUID(q.Value, other.Value) - case QValueKindJSON: - return compareJSON(q.Value, other.Value) - case QValueKindBit: - return compareBit(q.Value, other.Value) - case QValueKindGeometry, QValueKindGeography: - return compareGeometry(q.Value, other.Value) - case QValueKindHStore: - return compareHstore(q.Value, other.Value) - case QValueKindArrayFloat32: - return compareNumericArrays(q.Value, other.Value) - case QValueKindArrayFloat64: - return compareNumericArrays(q.Value, other.Value) - case QValueKindArrayInt32, QValueKindArrayInt16: - return compareNumericArrays(q.Value, other.Value) - case QValueKindArrayInt64: - return compareNumericArrays(q.Value, other.Value) - case QValueKindArrayDate: - return compareDateArrays(q.Value, other.Value) - case QValueKindArrayTimestamp, QValueKindArrayTimestampTZ: - return compareTimeArrays(q.Value, other.Value) - case QValueKindArrayBoolean: - return compareBoolArrays(q.Value, other.Value) - case QValueKindArrayString: - return compareArrayString(q.Value, other.Value) - default: - return false - } -} - -func (q QValue) GoTimeConvert() (string, error) { - if q.Kind == QValueKindTime || q.Kind == QValueKindTimeTZ { - return q.Value.(time.Time).Format("15:04:05.999999"), nil - // no connector supports time with timezone yet - // } else if q.Kind == QValueKindTimeTZ { - // return q.Value.(time.Time).Format("15:04:05.999999-0700"), nil - } else if q.Kind == QValueKindDate { - return q.Value.(time.Time).Format("2006-01-02"), nil - } else if q.Kind == QValueKindTimestamp { - return q.Value.(time.Time).Format("2006-01-02 15:04:05.999999"), nil - } else if q.Kind == QValueKindTimestampTZ { - return q.Value.(time.Time).Format("2006-01-02 15:04:05.999999-0700"), nil - } else { - return "", fmt.Errorf("unsupported QValueKind: %s", q.Kind) - } -} - -func compareInt16(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - int1, ok1 := getInt16(value1) - int2, ok2 := getInt16(value2) - return ok1 && ok2 && int1 == int2 -} - -func compareInt32(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - int1, ok1 := getInt32(value1) - int2, ok2 := getInt32(value2) - return ok1 && ok2 && int1 == int2 -} - -func compareInt64(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - int1, ok1 := getInt64(value1) - int2, ok2 := getInt64(value2) - return ok1 && ok2 && int1 == int2 -} - -func compareFloat32(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - float1, ok1 := getFloat32(value1) - float2, ok2 := getFloat32(value2) - return ok1 && ok2 && float1 == float2 -} - -func compareFloat64(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - float1, ok1 := getFloat64(value1) - float2, ok2 := getFloat64(value2) - return ok1 && ok2 && float1 == float2 -} - -func compareGoTime(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - et1, ok1 := value1.(time.Time) - et2, ok2 := value2.(time.Time) - - if !ok1 || !ok2 { - return false - } - - // TODO: this is a hack, we should be comparing the actual time values - // currently this is only used for testing so that is OK. - t1 := et1.UnixMicro() - t2 := et2.UnixMicro() - - return t1 == t2 -} - -func compareGoCivilTime(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - t1, ok1 := value1.(time.Time) - t2, ok2 := value2.(time.Time) - - if !ok1 || !ok2 { - if !ok2 { - // For BigQuery, we need to compare civil.Time with time.Time - ct2, ok3 := value2.(civil.Time) - if !ok3 { - return false - } - return t1.Hour() == ct2.Hour && t1.Minute() == ct2.Minute && t1.Second() == ct2.Second - } - return false - } - - return t1.Hour() == t2.Hour() && t1.Minute() == t2.Minute() && t1.Second() == t2.Second() -} +type QValue interface { + Kind() QValueKind + Value() any +} + +type QValueNull QValueKind + +func (v QValueNull) Kind() QValueKind { + return QValueKind(v) +} + +func (QValueNull) Value() any { + return nil +} + +type QValueInvalid struct { + Val string +} + +func (QValueInvalid) Kind() QValueKind { + return QValueKindInvalid +} + +func (v QValueInvalid) Value() any { + return v.Val +} + +type QValueFloat32 struct { + Val float32 +} + +func (QValueFloat32) Kind() QValueKind { + return QValueKindFloat32 +} + +func (v QValueFloat32) Value() any { + return v.Val +} + +type QValueFloat64 struct { + Val float64 +} + +func (QValueFloat64) Kind() QValueKind { + return QValueKindFloat64 +} + +func (v QValueFloat64) Value() any { + return v.Val +} + +type QValueInt16 struct { + Val int16 +} + +func (QValueInt16) Kind() QValueKind { + return QValueKindInt16 +} + +func (v QValueInt16) Value() any { + return v.Val +} + +type QValueInt32 struct { + Val int32 +} + +func (QValueInt32) Kind() QValueKind { + return QValueKindInt32 +} + +func (v QValueInt32) Value() any { + return v.Val +} + +type QValueInt64 struct { + Val int64 +} + +func (QValueInt64) Kind() QValueKind { + return QValueKindInt64 +} + +func (v QValueInt64) Value() any { + return v.Val +} + +type QValueBoolean struct { + Val bool +} + +func (QValueBoolean) Kind() QValueKind { + return QValueKindBoolean +} + +func (v QValueBoolean) Value() any { + return v.Val +} + +type QValueStruct struct { + Val map[string]interface{} +} + +func (QValueStruct) Kind() QValueKind { + return QValueKindStruct +} + +func (v QValueStruct) Value() any { + return v.Val +} + +type QValueQChar struct { + Val uint8 +} + +func (QValueQChar) Kind() QValueKind { + return QValueKindQChar +} + +func (v QValueQChar) Value() any { + return v.Val +} + +type QValueString struct { + Val string +} + +func (QValueString) Kind() QValueKind { + return QValueKindString +} + +func (v QValueString) Value() any { + return v.Val +} + +type QValueTimestamp struct { + Val time.Time +} + +func (QValueTimestamp) Kind() QValueKind { + return QValueKindTimestamp +} + +func (v QValueTimestamp) Value() any { + return v.Val +} + +type QValueTimestampTZ struct { + Val time.Time +} + +func (QValueTimestampTZ) Kind() QValueKind { + return QValueKindTimestampTZ +} + +func (v QValueTimestampTZ) Value() any { + return v.Val +} + +type QValueDate struct { + Val time.Time +} + +func (QValueDate) Kind() QValueKind { + return QValueKindDate +} + +func (v QValueDate) Value() any { + return v.Val +} + +type QValueTime struct { + Val time.Time +} + +func (QValueTime) Kind() QValueKind { + return QValueKindTime +} + +func (v QValueTime) Value() any { + return v.Val +} + +type QValueTimeTZ struct { + Val time.Time +} + +func (QValueTimeTZ) Kind() QValueKind { + return QValueKindTimeTZ +} + +func (v QValueTimeTZ) Value() any { + return v.Val +} + +type QValueInterval struct { + Val string +} + +func (QValueInterval) Kind() QValueKind { + return QValueKindInterval +} + +func (v QValueInterval) Value() any { + return v.Val +} + +type QValueNumeric struct { + Val decimal.Decimal +} + +func (QValueNumeric) Kind() QValueKind { + return QValueKindNumeric +} + +func (v QValueNumeric) Value() any { + return v.Val +} + +type QValueBytes struct { + Val []byte +} + +func (QValueBytes) Kind() QValueKind { + return QValueKindBytes +} + +func (v QValueBytes) Value() any { + return v.Val +} + +type QValueUUID struct { + Val [16]byte +} + +func (QValueUUID) Kind() QValueKind { + return QValueKindUUID +} + +func (v QValueUUID) Value() any { + return v.Val +} + +type QValueJSON struct { + Val string +} + +func (QValueJSON) Kind() QValueKind { + return QValueKindJSON +} + +func (v QValueJSON) Value() any { + return v.Val +} + +type QValueBit struct { + Val []byte +} + +func (QValueBit) Kind() QValueKind { + return QValueKindBit +} + +func (v QValueBit) Value() any { + return v.Val +} + +type QValueHStore struct { + Val string +} + +func (QValueHStore) Kind() QValueKind { + return QValueKindHStore +} + +func (v QValueHStore) Value() any { + return v.Val +} + +type QValueGeography struct { + Val string +} + +func (QValueGeography) Kind() QValueKind { + return QValueKindGeography +} + +func (v QValueGeography) Value() any { + return v.Val +} + +type QValueGeometry struct { + Val string +} + +func (QValueGeometry) Kind() QValueKind { + return QValueKindGeometry +} + +func (v QValueGeometry) Value() any { + return v.Val +} + +type QValuePoint struct { + Val string +} + +func (QValuePoint) Kind() QValueKind { + return QValueKindPoint +} + +func (v QValuePoint) Value() any { + return v.Val +} + +type QValueCIDR struct { + Val string +} + +func (QValueCIDR) Kind() QValueKind { + return QValueKindCIDR +} + +func (v QValueCIDR) Value() any { + return v.Val +} + +type QValueINET struct { + Val string +} + +func (QValueINET) Kind() QValueKind { + return QValueKindINET +} + +func (v QValueINET) Value() any { + return v.Val +} + +type QValueMacaddr struct { + Val string +} + +func (QValueMacaddr) Kind() QValueKind { + return QValueKindMacaddr +} + +func (v QValueMacaddr) Value() any { + return v.Val +} + +type QValueArrayFloat32 struct { + Val []float32 +} + +func (QValueArrayFloat32) Kind() QValueKind { + return QValueKindArrayFloat32 +} + +func (v QValueArrayFloat32) Value() any { + return v.Val +} + +type QValueArrayFloat64 struct { + Val []float64 +} + +func (QValueArrayFloat64) Kind() QValueKind { + return QValueKindArrayFloat64 +} + +func (v QValueArrayFloat64) Value() any { + return v.Val +} + +type QValueArrayInt16 struct { + Val []int16 +} + +func (QValueArrayInt16) Kind() QValueKind { + return QValueKindInt16 +} + +func (v QValueArrayInt16) Value() any { + return v.Val +} + +type QValueArrayInt32 struct { + Val []int32 +} + +func (QValueArrayInt32) Kind() QValueKind { + return QValueKindInt32 +} + +func (v QValueArrayInt32) Value() any { + return v.Val +} + +type QValueArrayInt64 struct { + Val []int64 +} + +func (QValueArrayInt64) Kind() QValueKind { + return QValueKindArrayInt64 +} -func compareUUID(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } +func (v QValueArrayInt64) Value() any { + return v.Val +} + +type QValueArrayString struct { + Val []string +} + +func (QValueArrayString) Kind() QValueKind { + return QValueKindArrayString +} + +func (v QValueArrayString) Value() any { + return v.Val +} + +type QValueArrayDate struct { + Val []time.Time +} + +func (QValueArrayDate) Kind() QValueKind { + return QValueKindArrayDate +} + +func (v QValueArrayDate) Value() any { + return v.Val +} + +type QValueArrayTimestamp struct { + Val []time.Time +} + +func (QValueArrayTimestamp) Kind() QValueKind { + return QValueKindArrayTimestamp +} + +func (v QValueArrayTimestamp) Value() any { + return v.Val +} + +type QValueArrayTimestampTZ struct { + Val []time.Time +} + +func (QValueArrayTimestampTZ) Kind() QValueKind { + return QValueKindArrayTimestampTZ +} + +func (v QValueArrayTimestampTZ) Value() any { + return v.Val +} + +type QValueArrayBoolean struct { + Val []bool +} + +func (QValueArrayBoolean) Kind() QValueKind { + return QValueKindArrayBoolean +} - uuid1, ok1 := getUUID(value1) - uuid2, ok2 := getUUID(value2) - - return ok1 && ok2 && uuid1 == uuid2 -} - -func compareBoolean(value1, value2 interface{}) bool { - bool1, ok1 := value1.(bool) - bool2, ok2 := value2.(bool) - - return ok1 && ok2 && bool1 == bool2 -} - -func compareBytes(value1, value2 interface{}) bool { - bytes1, ok1 := getBytes(value1) - bytes2, ok2 := getBytes(value2) - - return ok1 && ok2 && bytes.Equal(bytes1, bytes2) -} - -func compareNumeric(value1, value2 interface{}) bool { - num1, ok1 := getDecimal(value1) - num2, ok2 := getDecimal(value2) - - if !ok1 || !ok2 { - return false - } - - return num1.Equal(num2) -} - -func compareString(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - str1, ok1 := value1.(string) - str2, ok2 := value2.(string) - if !ok1 || !ok2 { - return false - } - return str1 == str2 -} - -func compareHstore(value1, value2 interface{}) bool { - str2 := value2.(string) - switch v1 := value1.(type) { - case pgtype.Hstore: - bytes, err := json.Marshal(v1) - if err != nil { - panic(err) - } - return string(bytes) == str2 - case string: - if v1 == str2 { - return true - } - parsedHStore1, err := hstore_util.ParseHstore(v1) - if err != nil { - panic(err) - } - return parsedHStore1 == strings.ReplaceAll(strings.ReplaceAll(str2, " ", ""), "\n", "") - default: - panic(fmt.Sprintf("invalid hstore value type %T: %v", value1, value1)) - } -} - -func compareGeometry(value1, value2 interface{}) bool { - geo2, err := geom.NewGeomFromWKT(value2.(string)) - if err != nil { - panic(err) - } - - switch v1 := value1.(type) { - case *geom.Geom: - return v1.Equals(geo2) - case string: - geoWkt := v1 - if strings.HasPrefix(geoWkt, "SRID=") { - _, wkt, found := strings.Cut(geoWkt, ";") - if found { - geoWkt = wkt - } - } - - geo1, err := geom.NewGeomFromWKT(geoWkt) - if err != nil { - panic(err) - } - return geo1.Equals(geo2) - default: - panic(fmt.Sprintf("invalid geometry value type %T: %v", value1, value1)) - } -} - -func compareStruct(value1, value2 interface{}) bool { - struct1, ok1 := value1.(map[string]interface{}) - struct2, ok2 := value2.(map[string]interface{}) - if !ok1 || !ok2 || len(struct1) != len(struct2) { - return false - } - for k, v1 := range struct1 { - v2, ok := struct2[k] - if !ok { - return false - } - q1, ok1 := v1.(QValue) - q2, ok2 := v2.(QValue) - if !ok1 || !ok2 || !q1.Equals(q2) { - return false - } - } - return true -} - -func compareJSON(value1, value2 interface{}) bool { - // TODO (kaushik): fix for tests - return true -} - -func compareBit(value1, value2 interface{}) bool { - bit1, ok1 := value1.(int) - bit2, ok2 := value2.(int) - - if !ok1 || !ok2 { - return false - } - - return bit1 == bit2 -} - -func compareNumericArrays(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - if value1 == nil && value2 == "null" { - return true - } - - if value1 == nil && value2 == "" { - return true - } - - // Helper function to convert a value to float64 - convertToFloat64 := func(val interface{}) []float64 { - switch v := val.(type) { - case []int16: - result := make([]float64, len(v)) - for i, value := range v { - result[i] = float64(value) - } - return result - case []int32: - result := make([]float64, len(v)) - for i, value := range v { - result[i] = float64(value) - } - return result - case []int64: - result := make([]float64, len(v)) - for i, value := range v { - result[i] = float64(value) - } - return result - case []float32: - result := make([]float64, len(v)) - for i, value := range v { - result[i] = float64(value) - } - return result - case []float64: - return v - default: - return nil - } - } - - array1 := convertToFloat64(value1) - array2 := convertToFloat64(value2) - - if array1 == nil || array2 == nil || len(array1) != len(array2) { - return false - } - - for i := range array1 { - if math.Abs(array1[i]-array2[i]) >= 1e9 { - return false - } - } - - return true -} - -func compareTimeArrays(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - array1, ok1 := value1.([]time.Time) - array2, ok2 := value2.([]time.Time) - - if !ok1 || !ok2 { - return false - } - - if len(array1) != len(array2) { - return false - } - - for i := range array1 { - if !array1[i].Equal(array2[i]) { - return false - } - } - - return true -} - -func compareDateArrays(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - array1, ok1 := value1.([]time.Time) - array2, ok2 := value2.([]civil.Date) - - if !ok1 || !ok2 || len(array1) != len(array2) { - return false - } - - for i := range array1 { - if array1[i].Year() != array2[i].Year || - array1[i].Month() != array2[i].Month || - array1[i].Day() != array2[i].Day { - return false - } - } - - return true -} - -func compareBoolArrays(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - array1, ok1 := value1.([]bool) - array2, ok2 := value2.([]bool) - - if !ok1 || !ok2 || len(array1) != len(array2) { - return false - } - - for i := range array1 { - if array1[i] != array2[i] { - return false - } - } - - return true -} - -func compareArrayString(value1, value2 interface{}) bool { - if value1 == nil && value2 == nil { - return true - } - - // also return true if value2 is string null - if value1 == nil && value2 == "null" { - return true - } - - // nulls end up as empty 'variants' in snowflake - if value1 == nil && value2 == "" { - return true - } - - array1, ok1 := value1.([]string) - array2, ok2 := value2.([]string) - - if !ok1 || !ok2 { - return false - } - - return reflect.DeepEqual(array1, array2) -} - -func getInt16(v interface{}) (int16, bool) { - switch value := v.(type) { - case int16: - return value, true - case int32: - return int16(value), true - case int64: - return int16(value), true - case decimal.Decimal: - return int16(value.IntPart()), true - case string: - parsed, err := strconv.ParseInt(value, 10, 16) - if err == nil { - return int16(parsed), true - } - } - return 0, false -} - -func getInt32(v interface{}) (int32, bool) { - switch value := v.(type) { - case int32: - return value, true - case int64: - return int32(value), true - case decimal.Decimal: - return int32(value.IntPart()), true - case string: - parsed, err := strconv.ParseInt(value, 10, 32) - if err == nil { - return int32(parsed), true - } - } - return 0, false -} - -func getInt64(v interface{}) (int64, bool) { - switch value := v.(type) { - case int64: - return value, true - case int32: - return int64(value), true - case decimal.Decimal: - return value.IntPart(), true - case string: - parsed, err := strconv.ParseInt(value, 10, 64) - if err == nil { - return parsed, true - } - } - return 0, false -} - -func getFloat32(v interface{}) (float32, bool) { - switch value := v.(type) { - case float32: - return value, true - case float64: - return float32(value), true - case string: - parsed, err := strconv.ParseFloat(value, 32) - if err == nil { - return float32(parsed), true - } - } - return 0, false -} - -func getFloat64(v interface{}) (float64, bool) { - switch value := v.(type) { - case float64: - return value, true - case float32: - return float64(value), true - case string: - parsed, err := strconv.ParseFloat(value, 64) - if err == nil { - return parsed, true - } - } - return 0, false -} - -func getBytes(v interface{}) ([]byte, bool) { - switch value := v.(type) { - case []byte: - return value, true - case string: - return []byte(value), true - case nil: - return nil, true - default: - return nil, false - } -} - -func getUUID(v interface{}) (uuid.UUID, bool) { - switch value := v.(type) { - case uuid.UUID: - return value, true - case string: - parsed, err := uuid.Parse(value) - if err == nil { - return parsed, true - } - case [16]byte: - return uuid.UUID(value), true - } - - return uuid.UUID{}, false -} - -// getDecimal attempts to parse a decimal from an interface -func getDecimal(v interface{}) (decimal.Decimal, bool) { - switch value := v.(type) { - case decimal.Decimal: - return value, true - case string: - parsed, err := decimal.NewFromString(value) - if err != nil { - panic(err) - } - return parsed, true - case float64: - return decimal.NewFromFloat(value), true - case int64: - return decimal.NewFromInt(value), true - case uint64: - return decimal.NewFromBigInt(new(big.Int).SetUint64(value), 0), true - case float32: - return decimal.NewFromFloat32(value), true - case int32: - return decimal.NewFromInt(int64(value)), true - case uint32: - return decimal.NewFromInt(int64(value)), true - case int: - return decimal.NewFromInt(int64(value)), true - case uint: - return decimal.NewFromInt(int64(value)), true - case int8: - return decimal.NewFromInt(int64(value)), true - case uint8: - return decimal.NewFromInt(int64(value)), true - case int16: - return decimal.NewFromInt(int64(value)), true - case uint16: - return decimal.NewFromInt(int64(value)), true - } - return decimal.Decimal{}, false +func (v QValueArrayBoolean) Value() any { + return v.Val } diff --git a/flow/model/record_items.go b/flow/model/record_items.go index a258f78be5..5482cf3973 100644 --- a/flow/model/record_items.go +++ b/flow/model/record_items.go @@ -5,9 +5,8 @@ import ( "errors" "fmt" "math" - "time" - "github.com/shopspring/decimal" + "github.com/google/uuid" hstore_util "github.com/PeerDB-io/peer-flow/hstore" "github.com/PeerDB-io/peer-flow/model/qvalue" @@ -48,7 +47,7 @@ func (r *RecordItems) GetColumnValue(col string) qvalue.QValue { if idx, ok := r.ColToValIdx[col]; ok { return r.Values[idx] } - return qvalue.QValue{} + return nil } // UpdateIfNotExists takes in a RecordItems as input and updates the values of the @@ -70,7 +69,7 @@ func (r *RecordItems) UpdateIfNotExists(input *RecordItems) []string { func (r *RecordItems) GetValueByColName(colName string) (qvalue.QValue, error) { idx, ok := r.ColToValIdx[colName] if !ok { - return qvalue.QValue{}, fmt.Errorf("column name %s not found", colName) + return nil, fmt.Errorf("column name %s not found", colName) } return r.Values[idx], nil } @@ -79,26 +78,22 @@ func (r *RecordItems) Len() int { return len(r.Values) } -func (r *RecordItems) toMap(hstoreAsJSON bool) (map[string]interface{}, error) { +func (r *RecordItems) toMap(hstoreAsJSON bool, opts ToJSONOptions) (map[string]interface{}, error) { if r.ColToValIdx == nil { return nil, errors.New("colToValIdx is nil") } jsonStruct := make(map[string]interface{}, len(r.ColToValIdx)) for col, idx := range r.ColToValIdx { - v := r.Values[idx] - if v.Value == nil { + qv := r.Values[idx] + if qv == nil { jsonStruct[col] = nil continue } - var err error - switch v.Kind { - case qvalue.QValueKindBit, qvalue.QValueKindBytes: - bitVal, ok := v.Value.([]byte) - if !ok { - return nil, errors.New("expected []byte value") - } + switch v := qv.(type) { + case qvalue.QValueBit: + bitVal := v.Val // convert to binary string because // json.Marshal stores byte arrays as @@ -109,36 +104,55 @@ func (r *RecordItems) toMap(hstoreAsJSON bool) (map[string]interface{}, error) { } jsonStruct[col] = binStr - case qvalue.QValueKindQChar: - ch, ok := v.Value.(uint8) - if !ok { - return nil, fmt.Errorf("expected \"char\" value for column %s for %T", col, v.Value) - } + case qvalue.QValueBytes: + bitVal := v.Val - jsonStruct[col] = string(ch) - case qvalue.QValueKindString, qvalue.QValueKindJSON: - strVal, ok := v.Value.(string) - if !ok { - return nil, fmt.Errorf("expected string value for column %s for %T", col, v.Value) + // convert to binary string because + // json.Marshal stores byte arrays as + // base64 + binStr := "" + for _, b := range bitVal { + binStr += fmt.Sprintf("%08b", b) } + jsonStruct[col] = binStr + case qvalue.QValueUUID: + jsonStruct[col] = uuid.UUID(v.Val) + case qvalue.QValueQChar: + jsonStruct[col] = string(v.Val) + case qvalue.QValueString: + strVal := v.Val + if len(strVal) > 15*1024*1024 { jsonStruct[col] = "" } else { jsonStruct[col] = strVal } - case qvalue.QValueKindHStore: - hstoreVal, ok := v.Value.(string) - if !ok { - return nil, fmt.Errorf("expected string value for hstore column %s for value %T", col, v.Value) + case qvalue.QValueJSON: + if len(v.Val) > 15*1024*1024 { + jsonStruct[col] = "" + } else if _, ok := opts.UnnestColumns[col]; ok { + var unnestStruct map[string]interface{} + err := json.Unmarshal([]byte(v.Val), &unnestStruct) + if err != nil { + return nil, err + } + + for k, v := range unnestStruct { + jsonStruct[k] = v + } + } else { + jsonStruct[col] = v.Val } + case qvalue.QValueHStore: + hstoreVal := v.Val if !hstoreAsJSON { jsonStruct[col] = hstoreVal } else { jsonVal, err := hstore_util.ParseHstore(hstoreVal) if err != nil { - return nil, fmt.Errorf("unable to convert hstore column %s to json for value %T", col, v.Value) + return nil, fmt.Errorf("unable to convert hstore column %s to json for value %T: %w", col, v, err) } if len(jsonVal) > 15*1024*1024 { @@ -148,55 +162,39 @@ func (r *RecordItems) toMap(hstoreAsJSON bool) (map[string]interface{}, error) { } } - case qvalue.QValueKindTimestamp, qvalue.QValueKindTimestampTZ, qvalue.QValueKindDate, - qvalue.QValueKindTime, qvalue.QValueKindTimeTZ: - jsonStruct[col], err = v.GoTimeConvert() - if err != nil { - return nil, err - } - case qvalue.QValueKindArrayDate: - dateArr, ok := v.Value.([]time.Time) - if !ok { - return nil, errors.New("expected []time.Time value") - } + case qvalue.QValueTimestamp: + jsonStruct[col] = v.Val.Format("2006-01-02 15:04:05.999999") + case qvalue.QValueTimestampTZ: + jsonStruct[col] = v.Val.Format("2006-01-02 15:04:05.999999-0700") + case qvalue.QValueDate: + jsonStruct[col] = v.Val.Format("2006-01-02") + case qvalue.QValueTime: + jsonStruct[col] = v.Val.Format("15:04:05.999999") + case qvalue.QValueTimeTZ: + jsonStruct[col] = v.Val.Format("15:04:05.999999") + case qvalue.QValueArrayDate: + dateArr := v.Val formattedDateArr := make([]string, 0, len(dateArr)) for _, val := range dateArr { formattedDateArr = append(formattedDateArr, val.Format("2006-01-02")) } jsonStruct[col] = formattedDateArr - case qvalue.QValueKindNumeric: - val, ok := v.Value.(decimal.Decimal) - if !ok { - return nil, errors.New("expected decimal.Decimal value") - } - - jsonStruct[col] = val.String() - case qvalue.QValueKindFloat64: - floatVal, ok := v.Value.(float64) - if !ok { - return nil, errors.New("expected float64 value") - } - if math.IsNaN(floatVal) || math.IsInf(floatVal, 0) { + case qvalue.QValueNumeric: + jsonStruct[col] = v.Val.String() + case qvalue.QValueFloat64: + if math.IsNaN(v.Val) || math.IsInf(v.Val, 0) { jsonStruct[col] = nil } else { - jsonStruct[col] = floatVal - } - case qvalue.QValueKindFloat32: - floatVal, ok := v.Value.(float32) - if !ok { - return nil, errors.New("expected float32 value") + jsonStruct[col] = v.Val } - if math.IsNaN(float64(floatVal)) || math.IsInf(float64(floatVal), 0) { + case qvalue.QValueFloat32: + if math.IsNaN(float64(v.Val)) || math.IsInf(float64(v.Val), 0) { jsonStruct[col] = nil } else { - jsonStruct[col] = floatVal + jsonStruct[col] = v.Val } - case qvalue.QValueKindArrayFloat64: - floatArr, ok := v.Value.([]float64) - if !ok { - return nil, errors.New("expected []float64 value") - } - + case qvalue.QValueArrayFloat64: + floatArr := v.Val nullableFloatArr := make([]interface{}, 0, len(floatArr)) for _, val := range floatArr { if math.IsNaN(val) || math.IsInf(val, 0) { @@ -206,11 +204,8 @@ func (r *RecordItems) toMap(hstoreAsJSON bool) (map[string]interface{}, error) { } } jsonStruct[col] = nullableFloatArr - case qvalue.QValueKindArrayFloat32: - floatArr, ok := v.Value.([]float32) - if !ok { - return nil, errors.New("expected []float32 value") - } + case qvalue.QValueArrayFloat32: + floatArr := v.Val nullableFloatArr := make([]interface{}, 0, len(floatArr)) for _, val := range floatArr { if math.IsNaN(float64(val)) || math.IsInf(float64(val), 0) { @@ -222,7 +217,7 @@ func (r *RecordItems) toMap(hstoreAsJSON bool) (map[string]interface{}, error) { jsonStruct[col] = nullableFloatArr default: - jsonStruct[col] = v.Value + jsonStruct[col] = v.Value() } } @@ -231,7 +226,7 @@ func (r *RecordItems) toMap(hstoreAsJSON bool) (map[string]interface{}, error) { // a separate method like gives flexibility // for us to handle some data types differently -func (r *RecordItems) ToJSONWithOptions(options *ToJSONOptions) (string, error) { +func (r *RecordItems) ToJSONWithOptions(options ToJSONOptions) (string, error) { return r.ToJSONWithOpts(options) } @@ -239,30 +234,12 @@ func (r *RecordItems) ToJSON() (string, error) { return r.ToJSONWithOpts(NewToJSONOptions(nil, true)) } -func (r *RecordItems) ToJSONWithOpts(opts *ToJSONOptions) (string, error) { - jsonStruct, err := r.toMap(opts.HStoreAsJSON) +func (r *RecordItems) ToJSONWithOpts(opts ToJSONOptions) (string, error) { + jsonStruct, err := r.toMap(opts.HStoreAsJSON, opts) if err != nil { return "", err } - for col, idx := range r.ColToValIdx { - v := r.Values[idx] - if v.Kind == qvalue.QValueKindJSON { - if _, ok := opts.UnnestColumns[col]; ok { - var unnestStruct map[string]interface{} - err := json.Unmarshal([]byte(v.Value.(string)), &unnestStruct) - if err != nil { - return "", err - } - - for k, v := range unnestStruct { - jsonStruct[k] = v - } - delete(jsonStruct, col) - } - } - } - jsonBytes, err := json.Marshal(jsonStruct) if err != nil { return "", err diff --git a/flow/pua/peerdb.go b/flow/pua/peerdb.go index 778cfd366e..197be4b461 100644 --- a/flow/pua/peerdb.go +++ b/flow/pua/peerdb.go @@ -108,7 +108,7 @@ func GetRowQ(ls *lua.LState, row *model.RecordItems, col string) qvalue.QValue { qv, err := row.GetValueByColName(col) if err != nil { ls.RaiseError(err.Error()) - return qvalue.QValue{} + return nil } return qv } @@ -148,7 +148,7 @@ func LuaRowColumns(ls *lua.LState) int { func LuaRowColumnKind(ls *lua.LState) int { row, key := LuaRow.StartIndex(ls) - ls.Push(lua.LString(GetRowQ(ls, row, key).Kind)) + ls.Push(lua.LString(GetRowQ(ls, row, key).Kind())) return 1 } @@ -222,13 +222,13 @@ func qvToLTable[T any](ls *lua.LState, s []T, f func(x T) lua.LValue) *lua.LTabl } func LuaQValue(ls *lua.LState, qv qvalue.QValue) lua.LValue { - switch v := qv.Value.(type) { + switch v := qv.Value().(type) { case nil: return lua.LNil case bool: return lua.LBool(v) case uint8: - if qv.Kind == qvalue.QValueKindQChar { + if qv.Kind() == qvalue.QValueKindQChar { return lua.LString(rune(v)) } else { return lua.LNumber(v) @@ -244,12 +244,6 @@ func LuaQValue(ls *lua.LState, qv qvalue.QValue) lua.LValue { case float64: return lua.LNumber(v) case string: - if qv.Kind == qvalue.QValueKindUUID { - u, err := uuid.Parse(v) - if err != nil { - return LuaUuid.New(ls, u) - } - } return lua.LString(v) case time.Time: return LuaTime.New(ls, v) @@ -292,7 +286,7 @@ func LuaQValue(ls *lua.LState, qv qvalue.QValue) lua.LValue { return lua.LBool(x) }) default: - return lua.LString(fmt.Sprint(qv.Value)) + return lua.LString(fmt.Sprint(qv.Value())) } } From 9dbc73a59ec6cb6feebc6d17cc806f35e206d17f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 26 Mar 2024 04:05:11 +0000 Subject: [PATCH 12/48] lua: add msgpack preload, remove peerdb.RowToJSON (#1535) Implement json marshaling for `*RecordItems` so `json.encode(row)` works --- flow/connectors/eventhub/eventhub.go | 2 +- flow/go.mod | 3 ++- flow/go.sum | 6 ++++-- flow/model/record_items.go | 22 ++++++++++------------ flow/pua/peerdb.go | 25 +++++++++++++------------ flow/pua/peerdb_test.go | 15 ++++++++++++++- 6 files changed, 44 insertions(+), 29 deletions(-) diff --git a/flow/connectors/eventhub/eventhub.go b/flow/connectors/eventhub/eventhub.go index d58530da54..1a3e01456a 100644 --- a/flow/connectors/eventhub/eventhub.go +++ b/flow/connectors/eventhub/eventhub.go @@ -135,7 +135,7 @@ func (c *EventHubConnector) processBatch( lastSeenLSN = recordLSN } - json, err := record.GetItems().ToJSONWithOpts(toJSONOpts) + json, err := record.GetItems().ToJSONWithOptions(toJSONOpts) if err != nil { c.logger.Info("failed to convert record to json", slog.Any("error", err)) return 0, err diff --git a/flow/go.mod b/flow/go.mod index 9af5d00ef5..11533a667f 100644 --- a/flow/go.mod +++ b/flow/go.mod @@ -14,7 +14,8 @@ require ( github.com/PeerDB-io/glua64 v1.0.1 github.com/PeerDB-io/gluabit32 v1.0.2 github.com/PeerDB-io/gluaflatbuffers v1.0.1 - github.com/PeerDB-io/gluajson v1.0.0 + github.com/PeerDB-io/gluajson v1.0.1 + github.com/PeerDB-io/gluamsgpack v0.0.0-20240326021100-65fbc328e820 github.com/aws/aws-sdk-go-v2 v1.26.0 github.com/aws/aws-sdk-go-v2/config v1.27.9 github.com/aws/aws-sdk-go-v2/credentials v1.17.9 diff --git a/flow/go.sum b/flow/go.sum index 83e6849a74..4ad96ce804 100644 --- a/flow/go.sum +++ b/flow/go.sum @@ -64,8 +64,10 @@ github.com/PeerDB-io/gluabit32 v1.0.2 h1:AGI1Z7dwDVotakpuOOuyTX4/QGi5HUYsipL/Vfo github.com/PeerDB-io/gluabit32 v1.0.2/go.mod h1:tsHStN1XG5uGVWEA8d/RameB7el3PE3sVkvk8e3+FJg= github.com/PeerDB-io/gluaflatbuffers v1.0.1 h1:Oxlv0VlMYoQ05Q5n/k4hXAsvtDnuVNC99JBUf927br0= github.com/PeerDB-io/gluaflatbuffers v1.0.1/go.mod h1:unZOM4Mm2Sn+aAFuVjoJDZ2Dji7jlDWrt4Hvq79as2g= -github.com/PeerDB-io/gluajson v1.0.0 h1:+W3nZ2WNqyCDIjRM7XtFKZLoZeB6rvsiAE4Ci1jHmzQ= -github.com/PeerDB-io/gluajson v1.0.0/go.mod h1:arRzpblxlLiWfBAluxP9Xibf6J8UkUIfoY4FPHTsz4Q= +github.com/PeerDB-io/gluajson v1.0.1 h1:MBrTCRD2FVQBCZ7ruK1fZZG6jdL+zAprGAoTWE074Ss= +github.com/PeerDB-io/gluajson v1.0.1/go.mod h1:arRzpblxlLiWfBAluxP9Xibf6J8UkUIfoY4FPHTsz4Q= +github.com/PeerDB-io/gluamsgpack v0.0.0-20240326021100-65fbc328e820 h1:bBcFQrZ+fdASDz/8XGRs8vfCz0aKaHF3zSGAUPfWdno= +github.com/PeerDB-io/gluamsgpack v0.0.0-20240326021100-65fbc328e820/go.mod h1:8hJ3nYdOKLQNAoDubZL2tdu0sNEGN7BM7NWeuZlBNb0= github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= diff --git a/flow/model/record_items.go b/flow/model/record_items.go index 5482cf3973..1feb2598c8 100644 --- a/flow/model/record_items.go +++ b/flow/model/record_items.go @@ -224,26 +224,24 @@ func (r *RecordItems) toMap(hstoreAsJSON bool, opts ToJSONOptions) (map[string]i return jsonStruct, nil } -// a separate method like gives flexibility -// for us to handle some data types differently func (r *RecordItems) ToJSONWithOptions(options ToJSONOptions) (string, error) { - return r.ToJSONWithOpts(options) + bytes, err := r.MarshalJSONWithOptions(options) + return string(bytes), err } func (r *RecordItems) ToJSON() (string, error) { - return r.ToJSONWithOpts(NewToJSONOptions(nil, true)) + return r.ToJSONWithOptions(NewToJSONOptions(nil, true)) } -func (r *RecordItems) ToJSONWithOpts(opts ToJSONOptions) (string, error) { - jsonStruct, err := r.toMap(opts.HStoreAsJSON, opts) - if err != nil { - return "", err - } +func (r *RecordItems) MarshalJSON() ([]byte, error) { + return r.MarshalJSONWithOptions(NewToJSONOptions(nil, true)) +} - jsonBytes, err := json.Marshal(jsonStruct) +func (r *RecordItems) MarshalJSONWithOptions(opts ToJSONOptions) ([]byte, error) { + jsonStruct, err := r.toMap(opts.HStoreAsJSON, opts) if err != nil { - return "", err + return nil, err } - return string(jsonBytes), nil + return json.Marshal(jsonStruct) } diff --git a/flow/pua/peerdb.go b/flow/pua/peerdb.go index 197be4b461..bbfd461d5f 100644 --- a/flow/pua/peerdb.go +++ b/flow/pua/peerdb.go @@ -14,6 +14,7 @@ import ( "github.com/PeerDB-io/glua64" "github.com/PeerDB-io/gluabit32" "github.com/PeerDB-io/gluajson" + "github.com/PeerDB-io/gluamsgpack" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/peerdbenv" @@ -40,6 +41,7 @@ func RegisterTypes(ls *lua.LState) { ls.PreloadModule("bit32", gluabit32.Loader) ls.PreloadModule("json", gluajson.Loader) + ls.PreloadModule("msgpack", gluamsgpack.Loader) mt := LuaRecord.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaRecordIndex)) @@ -51,6 +53,7 @@ func RegisterTypes(ls *lua.LState) { mt = LuaUuid.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaUuidIndex)) mt.RawSetString("__tostring", ls.NewFunction(LuaUuidString)) + mt.RawSetString("__msgpack", ls.NewFunction(LuaUuidMsgpack)) mt = LuaTime.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaTimeIndex)) @@ -66,7 +69,6 @@ func RegisterTypes(ls *lua.LState) { mt.RawSetString("__tostring", ls.NewFunction(LuaDecimalString)) peerdb := ls.NewTable() - peerdb.RawSetString("RowToJSON", ls.NewFunction(LuaRowToJSON)) peerdb.RawSetString("RowColumns", ls.NewFunction(LuaRowColumns)) peerdb.RawSetString("RowColumnKind", ls.NewFunction(LuaRowColumnKind)) peerdb.RawSetString("Now", ls.NewFunction(LuaNow)) @@ -125,17 +127,6 @@ func LuaRowLen(ls *lua.LState) int { return 1 } -func LuaRowToJSON(ls *lua.LState) int { - _, row := LuaRow.Check(ls, 1) - json, err := row.ToJSON() - if err != nil { - ls.RaiseError("failed to serialize json: %s", err.Error()) - return 0 - } - ls.Push(lua.LString(json)) - return 1 -} - func LuaRowColumns(ls *lua.LState) int { _, row := LuaRow.Check(ls, 1) tbl := ls.CreateTable(len(row.ColToValIdx), 0) @@ -307,6 +298,16 @@ func LuaUuidString(ls *lua.LState) int { return 1 } +func LuaUuidMsgpack(ls *lua.LState) int { + val := LuaUuid.StartMethod(ls) + ls.Push(&lua.LUserData{ + Value: gluamsgpack.Bin(val[:]), + Env: ls.Env, + Metatable: nil, + }) + return 1 +} + func LuaNow(ls *lua.LState) int { ls.Push(LuaTime.New(ls, time.Now())) return 1 diff --git a/flow/pua/peerdb_test.go b/flow/pua/peerdb_test.go index b2a752a16b..63cb7c6743 100644 --- a/flow/pua/peerdb_test.go +++ b/flow/pua/peerdb_test.go @@ -5,6 +5,9 @@ import ( "github.com/google/uuid" "github.com/yuin/gopher-lua" + + "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/model/qvalue" ) func assert(t *testing.T, ls *lua.LState, source string) { @@ -16,12 +19,16 @@ func assert(t *testing.T, ls *lua.LState, source string) { } } -func Test_Lua(t *testing.T) { +func Test(t *testing.T) { t.Parallel() ls := lua.NewState(lua.Options{}) RegisterTypes(ls) + row := model.NewRecordItems(1) + row.AddColumn("a", qvalue.QValueInt64{Val: 5040}) + ls.Env.RawSetString("row", LuaRow.New(ls, row)) + id := uuid.UUID([16]byte{2, 3, 5, 7, 11, 13, 17, 19, 127, 131, 137, 139, 149, 151, 241, 251}) ls.Env.RawSetString("uuid", LuaUuid.New(ls, id)) @@ -46,5 +53,11 @@ assert(uuid[12] == 149) assert(uuid[13] == 151) assert(uuid[14] == 241) assert(uuid[15] == 251) + +local msgpack = require "msgpack" +assert(msgpack.encode(uuid) == string.char(0xc4, 16, 2, 3, 5, 7, 11, 13, 17, 19, 127, 131, 137, 139, 149, 151, 241, 251)) + +local json = require "json" +assert(json.encode(row) == "{\"a\":5040}") `) } From d3d85f29d414046bdf0815d706ca12e3e0e3e0f4 Mon Sep 17 00:00:00 2001 From: Amogh Bharadwaj Date: Tue, 26 Mar 2024 19:27:10 +0530 Subject: [PATCH 13/48] UI: remove columns mistakenly added for a stats table in prisma schema (#1539) Unnecessary columns in `cdc_batches` table in Prisma schema which were later moved to `cdc_batch_table`. This makes UI fail --- ui/prisma/schema.prisma | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/prisma/schema.prisma b/ui/prisma/schema.prisma index a690445e36..4e3309aa80 100644 --- a/ui/prisma/schema.prisma +++ b/ui/prisma/schema.prisma @@ -90,9 +90,6 @@ model cdc_batches { end_time DateTime? @db.Timestamp(6) metadata Json? id Int @id @default(autoincrement()) - insert_count Int @default(0) - update_count Int @default(0) - delete_count Int @default(0) cdc_flows cdc_flows @relation(fields: [flow_name], references: [flow_name], onDelete: Cascade, onUpdate: NoAction, map: "fk_cdc_batches_flow_name") @@index([batch_id], map: "idx_cdc_batches_batch_id") @@ -143,6 +140,8 @@ model qrep_runs { metadata Json? config_proto Bytes? id Int @id @default(autoincrement()) + destination_table String? + source_table String? fetch_complete Boolean? @default(false) consolidate_complete Boolean? @default(false) qrep_partitions qrep_partitions[] From e55b7e80b2db1e82c16429f60ef1af95295bd3a7 Mon Sep 17 00:00:00 2001 From: Yasin Zaehringer Date: Tue, 26 Mar 2024 14:11:02 +0000 Subject: [PATCH 14/48] configurable maximum concurrency of the temporal activity & workflow workers (#1537) This allows to configure these temporal worker parameters: 1. `MaxConcurrentActivityExecutionSize` via the `TEMPORAL_MAX_CONCURRENT_ACTIVITIES` environment variable and an equivalent CLI flag 2. `MaxConcurrentWorkflowTaskExecutionSize` via the `TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASKS` environment variable and an equivalent CLI flag --- flow/cmd/worker.go | 25 ++++++++++++++++++------- flow/main.go | 30 ++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/flow/cmd/worker.go b/flow/cmd/worker.go index a499a26e2d..c9e3ed14f1 100644 --- a/flow/cmd/worker.go +++ b/flow/cmd/worker.go @@ -23,12 +23,14 @@ import ( ) type WorkerOptions struct { - TemporalHostPort string - EnableProfiling bool - PyroscopeServer string - TemporalNamespace string - TemporalCert string - TemporalKey string + TemporalHostPort string + EnableProfiling bool + PyroscopeServer string + TemporalNamespace string + TemporalCert string + TemporalKey string + TemporalMaxConcurrentActivities int + TemporalMaxConcurrentWorkflowTasks int } func setupPyroscope(opts *WorkerOptions) { @@ -110,8 +112,17 @@ func WorkerMain(opts *WorkerOptions) (client.Client, worker.Worker, error) { slog.Info("Created temporal client") taskQueue := peerdbenv.PeerFlowTaskQueueName(shared.PeerFlowTaskQueue) + slog.Info( + fmt.Sprintf("Creating temporal worker for queue %v: %v workflow workers %v activity workers", + taskQueue, + opts.TemporalMaxConcurrentWorkflowTasks, + opts.TemporalMaxConcurrentActivities, + ), + ) w := worker.New(c, taskQueue, worker.Options{ - EnableSessionWorker: true, + EnableSessionWorker: true, + MaxConcurrentActivityExecutionSize: opts.TemporalMaxConcurrentActivities, + MaxConcurrentWorkflowTaskExecutionSize: opts.TemporalMaxConcurrentWorkflowTasks, OnFatalError: func(err error) { slog.Error("Peerflow Worker failed", slog.Any("error", err)) }, diff --git a/flow/main.go b/flow/main.go index 34c66f57a0..06843b9254 100644 --- a/flow/main.go +++ b/flow/main.go @@ -62,6 +62,20 @@ func main() { Sources: cli.EnvVars("PEERDB_TEMPORAL_NAMESPACE"), } + temporalMaxConcurrentActivitiesFlag := &cli.IntFlag{ + Name: "temporal-max-concurrent-activities", + Value: 1000, + Usage: "Temporal: maximum number of concurrent activities", + Sources: cli.EnvVars("TEMPORAL_MAX_CONCURRENT_ACTIVITIES"), + } + + temporalMaxConcurrentWorkflowTasksFlag := &cli.IntFlag{ + Name: "temporal-max-concurrent-workflow-tasks", + Value: 1000, + Usage: "Temporal: maximum number of concurrent workflows", + Sources: cli.EnvVars("TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASKS"), + } + app := &cli.Command{ Name: "PeerDB Flows CLI", Commands: []*cli.Command{ @@ -70,12 +84,14 @@ func main() { Action: func(ctx context.Context, clicmd *cli.Command) error { temporalHostPort := clicmd.String("temporal-host-port") c, w, err := cmd.WorkerMain(&cmd.WorkerOptions{ - TemporalHostPort: temporalHostPort, - EnableProfiling: clicmd.Bool("enable-profiling"), - PyroscopeServer: clicmd.String("pyroscope-server-address"), - TemporalNamespace: clicmd.String("temporal-namespace"), - TemporalCert: clicmd.String("temporal-cert"), - TemporalKey: clicmd.String("temporal-key"), + TemporalHostPort: temporalHostPort, + EnableProfiling: clicmd.Bool("enable-profiling"), + PyroscopeServer: clicmd.String("pyroscope-server-address"), + TemporalNamespace: clicmd.String("temporal-namespace"), + TemporalCert: clicmd.String("temporal-cert"), + TemporalKey: clicmd.String("temporal-key"), + TemporalMaxConcurrentActivities: int(clicmd.Int("temporal-max-concurrent-activities")), + TemporalMaxConcurrentWorkflowTasks: int(clicmd.Int("temporal-max-concurrent-workflow-tasks")), }) if err != nil { return err @@ -90,6 +106,8 @@ func main() { temporalNamespaceFlag, &temporalCertFlag, &temporalKeyFlag, + temporalMaxConcurrentActivitiesFlag, + temporalMaxConcurrentWorkflowTasksFlag, }, }, { From ceddb0c57055a1c5a40257e851e5c694987d69c2 Mon Sep 17 00:00:00 2001 From: Yasin Zaehringer Date: Tue, 26 Mar 2024 14:24:39 +0000 Subject: [PATCH 15/48] qrep: wait for new rows as a temporal workflow (#1538) This is a relatively big change to the fundamental logic of query replication. Beforehand: QRep waits inside an activity and keeps the database connection open while it's doing that - this consumes a temporal activity worker slot just per QRep - this consumes a database connection per QRep Both are not desirable. The design I landed on here is: 1. there is a new activity `flowable.QRepHasNewRows` (replacing the old `flowable.QRepWaitUntilNewRows`) 2. there is a new workflow `QRepWaitForNewRowsWorkflow` which runs `flowable.QRepHasNewRows` and: a. if there is a new row completes the workflow b. if there is no new row it waits for the given time and then replaces itself using the temporal continue as new feature This has the benefit that the history size doesn't explode and that waiting for new rows across many QReps is nicely load balanced via temporal. Also, the number of open database connections is managed carefully: The other PR I opened let's one manage the maximum number of concurrent temporal activities. Hence you can control the maximum number of database connections easily. Note: For high frequency scenarios (thousands of QReps synced multiple times a minute) temporal accumulates a lot of history in the `history_nodes` tables. For that one needs to set the retention to 1h and force temporal to clean up more often than the default value (which is twice a day). I also changed that activities back off (exponential factor 2) when encountering errors. --- flow/activities/flowable.go | 57 +++++--------- flow/workflows/qrep_flow.go | 143 ++++++++++++++++++++++++++++-------- flow/workflows/register.go | 1 + 3 files changed, 129 insertions(+), 72 deletions(-) diff --git a/flow/activities/flowable.go b/flow/activities/flowable.go index 22f11f80c9..0765abfd89 100644 --- a/flow/activities/flowable.go +++ b/flow/activities/flowable.go @@ -945,60 +945,37 @@ func (a *FlowableActivity) RecordSlotSizes(ctx context.Context) error { return nil } -func (a *FlowableActivity) QRepWaitUntilNewRows(ctx context.Context, +type QRepWaitUntilNewRowsResult struct { + Found bool +} + +func (a *FlowableActivity) QRepHasNewRows(ctx context.Context, config *protos.QRepConfig, last *protos.QRepPartition, -) error { +) (QRepWaitUntilNewRowsResult, error) { ctx = context.WithValue(ctx, shared.FlowNameKey, config.FlowJobName) logger := log.With(activity.GetLogger(ctx), slog.String(string(shared.FlowNameKey), config.FlowJobName)) if config.SourcePeer.Type != protos.DBType_POSTGRES || last.Range == nil { - return nil - } - waitBetweenBatches := 5 * time.Second - if config.WaitBetweenBatchesSeconds > 0 { - waitBetweenBatches = time.Duration(config.WaitBetweenBatchesSeconds) * time.Second + return QRepWaitUntilNewRowsResult{Found: false}, nil } + logger.Info(fmt.Sprintf("current last partition value is %v", last)) + activity.RecordHeartbeat(ctx, "QRepHasNewRows") + srcConn, err := connectors.GetQRepPullConnector(ctx, config.SourcePeer) if err != nil { a.Alerter.LogFlowError(ctx, config.FlowJobName, err) - return fmt.Errorf("failed to get qrep source connector: %w", err) + return QRepWaitUntilNewRowsResult{Found: false}, fmt.Errorf("failed to get qrep source connector: %w", err) } - defer connectors.CloseConnector(ctx, srcConn) pgSrcConn := srcConn.(*connpostgres.PostgresConnector) - logger.Info(fmt.Sprintf("current last partition value is %v", last)) - attemptCount := 1 - for { - activity.RecordHeartbeat(ctx, fmt.Sprintf("no new rows yet, attempt #%d", attemptCount)) - waitUntil := time.Now().Add(waitBetweenBatches) - for { - sleep := time.Until(waitUntil) - if sleep > 15*time.Second { - sleep = 15 * time.Second - } - time.Sleep(sleep) - - activity.RecordHeartbeat(ctx, "heartbeat while waiting before next batch") - if err := ctx.Err(); err != nil { - return fmt.Errorf("cancelled while waiting for new rows: %w", err) - } else if time.Now().After(waitUntil) { - break - } - } - - result, err := pgSrcConn.CheckForUpdatedMaxValue(ctx, config, last) - if err != nil { - a.Alerter.LogFlowError(ctx, config.FlowJobName, err) - return fmt.Errorf("failed to check for new rows: %w", err) - } - if result { - break - } - - attemptCount += 1 + result, err := pgSrcConn.CheckForUpdatedMaxValue(ctx, config, last) + connectors.CloseConnector(ctx, srcConn) + if err != nil { + a.Alerter.LogFlowError(ctx, config.FlowJobName, err) + return QRepWaitUntilNewRowsResult{Found: false}, fmt.Errorf("failed to check for new rows: %w", err) } - return nil + return QRepWaitUntilNewRowsResult{Found: result}, nil } func (a *FlowableActivity) RenameTables(ctx context.Context, config *protos.RenameTablesInput) ( diff --git a/flow/workflows/qrep_flow.go b/flow/workflows/qrep_flow.go index 2f0124e717..15fce3b21b 100644 --- a/flow/workflows/qrep_flow.go +++ b/flow/workflows/qrep_flow.go @@ -3,6 +3,7 @@ package peerflow import ( "fmt" + "github.com/PeerDB-io/peer-flow/activities" "log/slog" "strings" "time" @@ -75,6 +76,13 @@ func (q *QRepFlowExecution) SetupMetadataTables(ctx workflow.Context) error { ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 5 * time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, }) if err := workflow.ExecuteActivity(ctx, flowable.SetupQRepMetadataTables, q.config).Get(ctx, nil); err != nil { @@ -90,6 +98,13 @@ func (q *QRepFlowExecution) getTableSchema(ctx workflow.Context, tableName strin ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 5 * time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, }) tableSchemaInput := &protos.GetTableSchemaBatchInput{ @@ -114,6 +129,13 @@ func (q *QRepFlowExecution) SetupWatermarkTableOnDestination(ctx workflow.Contex ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 5 * time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, }) // fetch the schema for the watermark table @@ -153,6 +175,13 @@ func (q *QRepFlowExecution) GetPartitions( ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 5 * time.Hour, HeartbeatTimeout: time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, }) partitionsFuture := workflow.ExecuteActivity(ctx, flowable.GetQRepPartitions, q.config, last, q.runUUID) @@ -172,6 +201,13 @@ func (q *QRepPartitionFlowExecution) ReplicatePartitions(ctx workflow.Context, ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 24 * 5 * time.Hour, HeartbeatTimeout: time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, }) msg := fmt.Sprintf("replicating partition batch - %d", partitions.BatchId) @@ -259,6 +295,13 @@ func (q *QRepFlowExecution) consolidatePartitions(ctx workflow.Context) error { ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 24 * time.Hour, HeartbeatTimeout: time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, }) if err := workflow.ExecuteActivity(ctx, flowable.ConsolidateQRepPartitions, q.config, @@ -278,39 +321,16 @@ func (q *QRepFlowExecution) consolidatePartitions(ctx workflow.Context) error { return nil } -func (q *QRepFlowExecution) waitForNewRows( - ctx workflow.Context, - signalChan model.TypedReceiveChannel[model.CDCFlowSignal], - lastPartition *protos.QRepPartition, -) error { - q.logger.Info("idling until new rows are detected") - - var done bool - var doneErr error - selector := workflow.NewNamedSelector(ctx, "WaitForNewRows") - - ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ - StartToCloseTimeout: 16 * 365 * 24 * time.Hour, // 16 years - HeartbeatTimeout: time.Minute, - }) - fWait := workflow.ExecuteActivity(ctx, flowable.QRepWaitUntilNewRows, q.config, lastPartition) - selector.AddReceive(ctx.Done(), func(_ workflow.ReceiveChannel, _ bool) {}) - selector.AddFuture(fWait, func(f workflow.Future) { - doneErr = f.Get(ctx, nil) - done = true - }) - signalChan.AddToSelector(selector, func(val model.CDCFlowSignal, _ bool) { - q.activeSignal = model.FlowSignalHandler(q.activeSignal, val, q.logger) - }) - - for ctx.Err() == nil && ((!done && q.activeSignal != model.PauseSignal) || selector.HasPending()) { - selector.Select(ctx) +func (q *QRepFlowExecution) waitForNewRows(ctx workflow.Context, lastPartition *protos.QRepPartition) workflow.ChildWorkflowFuture { + cwOptions := workflow.ChildWorkflowOptions{ + ParentClosePolicy: enums.PARENT_CLOSE_POLICY_REQUEST_CANCEL, + SearchAttributes: map[string]interface{}{ + shared.MirrorNameSearchAttribute: q.config.FlowJobName, + }, } + ctx = workflow.WithChildOptions(ctx, cwOptions) - if err := ctx.Err(); err != nil { - return err - } - return doneErr + return workflow.ExecuteChildWorkflow(ctx, QRepWaitForNewRowsWorkflow, q.config, lastPartition) } func (q *QRepFlowExecution) handleTableCreationForResync(ctx workflow.Context, state *protos.QRepFlowState) error { @@ -319,6 +339,13 @@ func (q *QRepFlowExecution) handleTableCreationForResync(ctx workflow.Context, s createTablesFromExistingCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 10 * time.Minute, HeartbeatTimeout: time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, }) createTablesFromExistingFuture := workflow.ExecuteActivity( createTablesFromExistingCtx, flowable.CreateTablesFromExisting, &protos.CreateTablesFromExistingInput{ @@ -359,6 +386,13 @@ func (q *QRepFlowExecution) handleTableRenameForResync(ctx workflow.Context, sta renameTablesCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 30 * time.Minute, HeartbeatTimeout: time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, }) renameTablesFuture := workflow.ExecuteActivity(renameTablesCtx, flowable.RenameTables, renameOpts) if err := renameTablesFuture.Get(renameTablesCtx, nil); err != nil { @@ -407,6 +441,49 @@ func setWorkflowQueries(ctx workflow.Context, state *protos.QRepFlowState) error return nil } +func QRepWaitForNewRowsWorkflow(ctx workflow.Context, config *protos.QRepConfig, lastPartition *protos.QRepPartition) error { + logger := log.With(workflow.GetLogger(ctx), slog.String(string(shared.FlowNameKey), config.FlowJobName)) + + ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ + StartToCloseTimeout: 16 * 365 * 24 * time.Hour, // 16 years + HeartbeatTimeout: time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Minute, + BackoffCoefficient: 2., + MaximumInterval: time.Hour, + MaximumAttempts: 0, + NonRetryableErrorTypes: nil, + }, + }) + + var result activities.QRepWaitUntilNewRowsResult + err := workflow.ExecuteActivity(ctx, flowable.QRepHasNewRows, config, lastPartition).Get(ctx, &result) + if err != nil { + return fmt.Errorf("error checking for new rows: %w", err) + } + hasNewRows := result.Found + + // If no new rows are found, continue as new + if !hasNewRows { + waitBetweenBatches := 5 * time.Second + if config.WaitBetweenBatchesSeconds > 0 { + waitBetweenBatches = time.Duration(config.WaitBetweenBatchesSeconds) * time.Second + } + + if sleepErr := workflow.Sleep(ctx, waitBetweenBatches); sleepErr != nil { + return sleepErr + } + + logger.Info(fmt.Sprintf("QRepWaitForNewRowsWorkflow: continuing the loop")) + return workflow.NewContinueAsNewError(ctx, QRepWaitForNewRowsWorkflow, config, lastPartition) + } + + logger.Info(fmt.Sprintf("QRepWaitForNewRowsWorkflow: exiting the loop")) + + // New rows found, workflow can complete and allow the parent workflow to proceed + return nil +} + func QRepFlowWorkflow( ctx workflow.Context, config *protos.QRepConfig, @@ -505,7 +582,9 @@ func QRepFlowWorkflow( state.LastPartition = partitions.Partitions[len(partitions.Partitions)-1] } - err = q.waitForNewRows(ctx, signalChan, state.LastPartition) + // Let's wait for new rows + future := q.waitForNewRows(ctx, state.LastPartition) + err = future.Get(ctx, nil) if err != nil { return err } diff --git a/flow/workflows/register.go b/flow/workflows/register.go index 44c7cb00be..35adf135bf 100644 --- a/flow/workflows/register.go +++ b/flow/workflows/register.go @@ -11,6 +11,7 @@ func RegisterFlowWorkerWorkflows(w worker.WorkflowRegistry) { w.RegisterWorkflow(SetupFlowWorkflow) w.RegisterWorkflow(SyncFlowWorkflow) w.RegisterWorkflow(QRepFlowWorkflow) + w.RegisterWorkflow(QRepWaitForNewRowsWorkflow) w.RegisterWorkflow(QRepPartitionWorkflow) w.RegisterWorkflow(XminFlowWorkflow) From ac42ab17f7cd9bf2335344409e9b0eea70af46f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 26 Mar 2024 18:33:29 +0000 Subject: [PATCH 16/48] Fix CI (#1544) Recent improvement to qrep in #1538 got rid of selector logic necessary for proper pause/cancel handling --- flow/activities/flowable.go | 2 +- flow/workflows/qrep_flow.go | 109 +++++++++++++++++++++++------------- 2 files changed, 71 insertions(+), 40 deletions(-) diff --git a/flow/activities/flowable.go b/flow/activities/flowable.go index 0765abfd89..01c2789cdf 100644 --- a/flow/activities/flowable.go +++ b/flow/activities/flowable.go @@ -956,7 +956,7 @@ func (a *FlowableActivity) QRepHasNewRows(ctx context.Context, logger := log.With(activity.GetLogger(ctx), slog.String(string(shared.FlowNameKey), config.FlowJobName)) if config.SourcePeer.Type != protos.DBType_POSTGRES || last.Range == nil { - return QRepWaitUntilNewRowsResult{Found: false}, nil + return QRepWaitUntilNewRowsResult{Found: true}, nil } logger.Info(fmt.Sprintf("current last partition value is %v", last)) diff --git a/flow/workflows/qrep_flow.go b/flow/workflows/qrep_flow.go index 15fce3b21b..25cfa2cebb 100644 --- a/flow/workflows/qrep_flow.go +++ b/flow/workflows/qrep_flow.go @@ -1,9 +1,7 @@ -// This file corresponds to query based replication. package peerflow import ( "fmt" - "github.com/PeerDB-io/peer-flow/activities" "log/slog" "strings" "time" @@ -13,6 +11,7 @@ import ( "go.temporal.io/sdk/temporal" "go.temporal.io/sdk/workflow" + "github.com/PeerDB-io/peer-flow/activities" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/shared" @@ -185,7 +184,7 @@ func (q *QRepFlowExecution) GetPartitions( }) partitionsFuture := workflow.ExecuteActivity(ctx, flowable.GetQRepPartitions, q.config, last, q.runUUID) - partitions := &protos.QRepParitionResult{} + var partitions *protos.QRepParitionResult if err := partitionsFuture.Get(ctx, &partitions); err != nil { return nil, fmt.Errorf("failed to fetch partitions to replicate: %w", err) } @@ -321,16 +320,38 @@ func (q *QRepFlowExecution) consolidatePartitions(ctx workflow.Context) error { return nil } -func (q *QRepFlowExecution) waitForNewRows(ctx workflow.Context, lastPartition *protos.QRepPartition) workflow.ChildWorkflowFuture { - cwOptions := workflow.ChildWorkflowOptions{ +func (q *QRepFlowExecution) waitForNewRows( + ctx workflow.Context, + signalChan model.TypedReceiveChannel[model.CDCFlowSignal], + lastPartition *protos.QRepPartition, +) error { + ctx = workflow.WithChildOptions(ctx, workflow.ChildWorkflowOptions{ ParentClosePolicy: enums.PARENT_CLOSE_POLICY_REQUEST_CANCEL, SearchAttributes: map[string]interface{}{ shared.MirrorNameSearchAttribute: q.config.FlowJobName, }, - } - ctx = workflow.WithChildOptions(ctx, cwOptions) + }) + future := workflow.ExecuteChildWorkflow(ctx, QRepWaitForNewRowsWorkflow, q.config, lastPartition) + + var newRows bool + var waitErr error + waitSelector := workflow.NewNamedSelector(ctx, "WaitForRows") + signalChan.AddToSelector(waitSelector, func(val model.CDCFlowSignal, _ bool) { + q.activeSignal = model.FlowSignalHandler(q.activeSignal, val, q.logger) + }) + waitSelector.AddFuture(future, func(f workflow.Future) { + newRows = true + waitErr = f.Get(ctx, nil) + }) + waitSelector.AddReceive(ctx.Done(), func(_ workflow.ReceiveChannel, _ bool) {}) - return workflow.ExecuteChildWorkflow(ctx, QRepWaitForNewRowsWorkflow, q.config, lastPartition) + for ctx.Err() == nil && !newRows && q.activeSignal != model.PauseSignal { + waitSelector.Select(ctx) + } + if err := ctx.Err(); err != nil { + return err + } + return waitErr } func (q *QRepFlowExecution) handleTableCreationForResync(ctx workflow.Context, state *protos.QRepFlowState) error { @@ -474,11 +495,11 @@ func QRepWaitForNewRowsWorkflow(ctx workflow.Context, config *protos.QRepConfig, return sleepErr } - logger.Info(fmt.Sprintf("QRepWaitForNewRowsWorkflow: continuing the loop")) + logger.Info("QRepWaitForNewRowsWorkflow: continuing the loop") return workflow.NewContinueAsNewError(ctx, QRepWaitForNewRowsWorkflow, config, lastPartition) } - logger.Info(fmt.Sprintf("QRepWaitForNewRowsWorkflow: exiting the loop")) + logger.Info("QRepWaitForNewRowsWorkflow: exiting the loop") // New rows found, workflow can complete and allow the parent workflow to proceed return nil @@ -549,44 +570,54 @@ func QRepFlowWorkflow( return err } - logger.Info("fetching partitions to replicate for peer flow") - partitions, err := q.GetPartitions(ctx, state.LastPartition) - if err != nil { - return fmt.Errorf("failed to get partitions: %w", err) + if state.LastPartition != nil { + if err := q.waitForNewRows(ctx, signalChan, state.LastPartition); err != nil { + return err + } } - logger.Info(fmt.Sprintf("%d partitions to replicate", len(partitions.Partitions))) - if err := q.processPartitions(ctx, maxParallelWorkers, partitions.Partitions); err != nil { - return err - } + if q.activeSignal != model.PauseSignal { + logger.Info("fetching partitions to replicate for peer flow") + partitions, err := q.GetPartitions(ctx, state.LastPartition) + if err != nil { + return fmt.Errorf("failed to get partitions: %w", err) + } - logger.Info("consolidating partitions for peer flow") - if err := q.consolidatePartitions(ctx); err != nil { - return err - } + logger.Info(fmt.Sprintf("%d partitions to replicate", len(partitions.Partitions))) + if err := q.processPartitions(ctx, maxParallelWorkers, partitions.Partitions); err != nil { + return err + } - if config.InitialCopyOnly { - logger.Info("initial copy completed for peer flow") - return nil - } + logger.Info("consolidating partitions for peer flow") + if err := q.consolidatePartitions(ctx); err != nil { + return err + } - err = q.handleTableRenameForResync(ctx, state) - if err != nil { - return err - } + if config.InitialCopyOnly { + logger.Info("initial copy completed for peer flow") + return nil + } + + err = q.handleTableRenameForResync(ctx, state) + if err != nil { + return err + } - logger.Info(fmt.Sprintf("%d partitions processed", len(partitions.Partitions))) - state.NumPartitionsProcessed += uint64(len(partitions.Partitions)) + logger.Info(fmt.Sprintf("%d partitions processed", len(partitions.Partitions))) + state.NumPartitionsProcessed += uint64(len(partitions.Partitions)) - if len(partitions.Partitions) > 0 { - state.LastPartition = partitions.Partitions[len(partitions.Partitions)-1] + if len(partitions.Partitions) > 0 { + state.LastPartition = partitions.Partitions[len(partitions.Partitions)-1] + } } - // Let's wait for new rows - future := q.waitForNewRows(ctx, state.LastPartition) - err = future.Get(ctx, nil) - if err != nil { - return err + // flush signal, after this workflow must not yield + for { + val, ok := signalChan.ReceiveAsync() + if !ok { + break + } + q.activeSignal = model.FlowSignalHandler(q.activeSignal, val, q.logger) } logger.Info("Continuing as new workflow", From 77b167f19fcd03d532e8029ff172602de8b9967c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 26 Mar 2024 18:41:15 +0000 Subject: [PATCH 17/48] Replace qvalue.QDWHType with protos.DBType (#1543) --- flow/connectors/bigquery/qrep_avro_sync.go | 2 +- flow/connectors/clickhouse/normalize.go | 4 +- flow/connectors/clickhouse/qrep_avro_sync.go | 5 +- flow/connectors/clickhouse/qvalue_convert.go | 14 ----- flow/connectors/s3/qrep.go | 5 +- .../snowflake/avro_file_writer_test.go | 21 +++---- .../snowflake/merge_stmt_generator.go | 2 +- flow/connectors/snowflake/qrep_avro_sync.go | 8 +-- flow/connectors/snowflake/qvalue_convert.go | 9 --- flow/connectors/snowflake/snowflake.go | 4 +- flow/connectors/utils/avro/avro_writer.go | 6 +- flow/model/conversion_avro.go | 7 ++- flow/model/qvalue/avro_converter.go | 55 ++++++++++--------- flow/model/qvalue/dwh.go | 39 +++++++++++++ flow/model/qvalue/dwh_type.go | 28 ---------- flow/model/qvalue/kind.go | 8 ++- flow/model/qvalue/timestamp.go | 20 ------- 17 files changed, 104 insertions(+), 133 deletions(-) delete mode 100644 flow/connectors/clickhouse/qvalue_convert.go create mode 100644 flow/model/qvalue/dwh.go delete mode 100644 flow/model/qvalue/dwh_type.go delete mode 100644 flow/model/qvalue/timestamp.go diff --git a/flow/connectors/bigquery/qrep_avro_sync.go b/flow/connectors/bigquery/qrep_avro_sync.go index 2586436ab6..06c48391fd 100644 --- a/flow/connectors/bigquery/qrep_avro_sync.go +++ b/flow/connectors/bigquery/qrep_avro_sync.go @@ -412,7 +412,7 @@ func (s *QRepAvroSyncMethod) writeToStage( defer shutdown() var avroFile *avro.AvroFile - ocfWriter := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressNone, qvalue.QDWHTypeBigQuery) + ocfWriter := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressNone, protos.DBType_BIGQUERY) idLog := slog.Group("write-metadata", slog.String(string(shared.FlowNameKey), flowName), slog.String("batchOrPartitionID", syncID), diff --git a/flow/connectors/clickhouse/normalize.go b/flow/connectors/clickhouse/normalize.go index eb0c97ab85..de7bf66c6b 100644 --- a/flow/connectors/clickhouse/normalize.go +++ b/flow/connectors/clickhouse/normalize.go @@ -77,7 +77,7 @@ func generateCreateTableSQLForNormalizedTable( for _, column := range tableSchema.Columns { colName := column.Name colType := qvalue.QValueKind(column.Type) - clickhouseType, err := qValueKindToClickhouseType(colType) + clickhouseType, err := colType.ToDWHColumnType(protos.DBType_CLICKHOUSE) if err != nil { return "", fmt.Errorf("error while converting column type to clickhouse type: %w", err) } @@ -172,7 +172,7 @@ func (c *ClickhouseConnector) NormalizeRecords(ctx context.Context, req *model.N colSelector.WriteString(fmt.Sprintf("`%s`,", cn)) colType := qvalue.QValueKind(ct) - clickhouseType, err := qValueKindToClickhouseType(colType) + clickhouseType, err := colType.ToDWHColumnType(protos.DBType_CLICKHOUSE) if err != nil { return nil, fmt.Errorf("error while converting column type to clickhouse type: %w", err) } diff --git a/flow/connectors/clickhouse/qrep_avro_sync.go b/flow/connectors/clickhouse/qrep_avro_sync.go index 2a6d1f217e..93627ace71 100644 --- a/flow/connectors/clickhouse/qrep_avro_sync.go +++ b/flow/connectors/clickhouse/qrep_avro_sync.go @@ -14,7 +14,6 @@ import ( avro "github.com/PeerDB-io/peer-flow/connectors/utils/avro" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" - "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/shared" ) @@ -157,7 +156,7 @@ func (s *ClickhouseAvroSyncMethod) getAvroSchema( dstTableName string, schema *model.QRecordSchema, ) (*model.QRecordAvroSchemaDefinition, error) { - avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, qvalue.QDWHTypeClickhouse) + avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, protos.DBType_CLICKHOUSE) if err != nil { return nil, fmt.Errorf("failed to define Avro schema: %w", err) } @@ -172,7 +171,7 @@ func (s *ClickhouseAvroSyncMethod) writeToAvroFile( flowJobName string, ) (*avro.AvroFile, error) { stagingPath := s.connector.creds.BucketPath - ocfWriter := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressZstd, qvalue.QDWHTypeClickhouse) + ocfWriter := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressZstd, protos.DBType_CLICKHOUSE) s3o, err := utils.NewS3BucketAndPrefix(stagingPath) if err != nil { return nil, fmt.Errorf("failed to parse staging path: %w", err) diff --git a/flow/connectors/clickhouse/qvalue_convert.go b/flow/connectors/clickhouse/qvalue_convert.go deleted file mode 100644 index 97d39221dc..0000000000 --- a/flow/connectors/clickhouse/qvalue_convert.go +++ /dev/null @@ -1,14 +0,0 @@ -package connclickhouse - -import ( - "github.com/PeerDB-io/peer-flow/model/qvalue" -) - -func qValueKindToClickhouseType(colType qvalue.QValueKind) (string, error) { - val, err := colType.ToDWHColumnType(qvalue.QDWHTypeClickhouse) - if err != nil { - return "", err - } - - return val, err -} diff --git a/flow/connectors/s3/qrep.go b/flow/connectors/s3/qrep.go index 1d5684d060..0824776c77 100644 --- a/flow/connectors/s3/qrep.go +++ b/flow/connectors/s3/qrep.go @@ -9,7 +9,6 @@ import ( avro "github.com/PeerDB-io/peer-flow/connectors/utils/avro" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" - "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/shared" ) @@ -45,7 +44,7 @@ func getAvroSchema( dstTableName string, schema *model.QRecordSchema, ) (*model.QRecordAvroSchemaDefinition, error) { - avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, qvalue.QDWHTypeS3) + avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, protos.DBType_S3) if err != nil { return nil, fmt.Errorf("failed to define Avro schema: %w", err) } @@ -66,7 +65,7 @@ func (c *S3Connector) writeToAvroFile( } s3AvroFileKey := fmt.Sprintf("%s/%s/%s.avro", s3o.Prefix, jobName, partitionID) - writer := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressNone, qvalue.QDWHTypeSnowflake) + writer := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressNone, protos.DBType_SNOWFLAKE) avroFile, err := writer.WriteRecordsToS3(ctx, s3o.Bucket, s3AvroFileKey, c.creds) if err != nil { return 0, fmt.Errorf("failed to write records to S3: %w", err) diff --git a/flow/connectors/snowflake/avro_file_writer_test.go b/flow/connectors/snowflake/avro_file_writer_test.go index 0006513cbb..9c609a2dd2 100644 --- a/flow/connectors/snowflake/avro_file_writer_test.go +++ b/flow/connectors/snowflake/avro_file_writer_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" avro "github.com/PeerDB-io/peer-flow/connectors/utils/avro" + "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/qvalue" ) @@ -150,13 +151,13 @@ func TestWriteRecordsToAvroFileHappyPath(t *testing.T) { // Define sample data records, schema := generateRecords(t, true, 10, false) - avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, qvalue.QDWHTypeSnowflake) + avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, protos.DBType_SNOWFLAKE) require.NoError(t, err) t.Logf("[test] avroSchema: %v", avroSchema) // Call function - writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressNone, qvalue.QDWHTypeSnowflake) + writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressNone, protos.DBType_SNOWFLAKE) _, err = writer.WriteRecordsToAvroFile(context.Background(), tmpfile.Name()) require.NoError(t, err, "expected WriteRecordsToAvroFile to complete without errors") @@ -177,13 +178,13 @@ func TestWriteRecordsToZstdAvroFileHappyPath(t *testing.T) { // Define sample data records, schema := generateRecords(t, true, 10, false) - avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, qvalue.QDWHTypeSnowflake) + avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, protos.DBType_SNOWFLAKE) require.NoError(t, err) t.Logf("[test] avroSchema: %v", avroSchema) // Call function - writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressZstd, qvalue.QDWHTypeSnowflake) + writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressZstd, protos.DBType_SNOWFLAKE) _, err = writer.WriteRecordsToAvroFile(context.Background(), tmpfile.Name()) require.NoError(t, err, "expected WriteRecordsToAvroFile to complete without errors") @@ -204,13 +205,13 @@ func TestWriteRecordsToDeflateAvroFileHappyPath(t *testing.T) { // Define sample data records, schema := generateRecords(t, true, 10, false) - avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, qvalue.QDWHTypeSnowflake) + avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, protos.DBType_SNOWFLAKE) require.NoError(t, err) t.Logf("[test] avroSchema: %v", avroSchema) // Call function - writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressDeflate, qvalue.QDWHTypeSnowflake) + writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressDeflate, protos.DBType_SNOWFLAKE) _, err = writer.WriteRecordsToAvroFile(context.Background(), tmpfile.Name()) require.NoError(t, err, "expected WriteRecordsToAvroFile to complete without errors") @@ -230,13 +231,13 @@ func TestWriteRecordsToAvroFileNonNull(t *testing.T) { records, schema := generateRecords(t, false, 10, false) - avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, qvalue.QDWHTypeSnowflake) + avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, protos.DBType_SNOWFLAKE) require.NoError(t, err) t.Logf("[test] avroSchema: %v", avroSchema) // Call function - writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressNone, qvalue.QDWHTypeSnowflake) + writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressNone, protos.DBType_SNOWFLAKE) _, err = writer.WriteRecordsToAvroFile(context.Background(), tmpfile.Name()) require.NoError(t, err, "expected WriteRecordsToAvroFile to complete without errors") @@ -257,13 +258,13 @@ func TestWriteRecordsToAvroFileAllNulls(t *testing.T) { // Define sample data records, schema := generateRecords(t, true, 10, true) - avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, qvalue.QDWHTypeSnowflake) + avroSchema, err := model.GetAvroSchemaDefinition("not_applicable", schema, protos.DBType_SNOWFLAKE) require.NoError(t, err) t.Logf("[test] avroSchema: %v", avroSchema) // Call function - writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressNone, qvalue.QDWHTypeSnowflake) + writer := avro.NewPeerDBOCFWriter(records, avroSchema, avro.CompressNone, protos.DBType_SNOWFLAKE) _, err = writer.WriteRecordsToAvroFile(context.Background(), tmpfile.Name()) require.NoError(t, err, "expected WriteRecordsToAvroFile to complete without errors") diff --git a/flow/connectors/snowflake/merge_stmt_generator.go b/flow/connectors/snowflake/merge_stmt_generator.go index b25d465a74..be5b244398 100644 --- a/flow/connectors/snowflake/merge_stmt_generator.go +++ b/flow/connectors/snowflake/merge_stmt_generator.go @@ -33,7 +33,7 @@ func (m *mergeStmtGenerator) generateMergeStmt() (string, error) { for _, column := range columns { genericColumnType := column.Type qvKind := qvalue.QValueKind(genericColumnType) - sfType, err := qValueKindToSnowflakeType(qvKind) + sfType, err := qvKind.ToDWHColumnType(protos.DBType_SNOWFLAKE) if err != nil { return "", fmt.Errorf("failed to convert column type %s to snowflake type: %w", genericColumnType, err) } diff --git a/flow/connectors/snowflake/qrep_avro_sync.go b/flow/connectors/snowflake/qrep_avro_sync.go index 8babfad0b4..c4b248fc04 100644 --- a/flow/connectors/snowflake/qrep_avro_sync.go +++ b/flow/connectors/snowflake/qrep_avro_sync.go @@ -174,7 +174,7 @@ func (s *SnowflakeAvroSyncHandler) addMissingColumns( } for colName, colType := range colsToTypes { - sfColType, err := colType.ToDWHColumnType(qvalue.QDWHTypeSnowflake) + sfColType, err := colType.ToDWHColumnType(protos.DBType_SNOWFLAKE) if err != nil { return fmt.Errorf("failed to convert QValueKind to Snowflake column type: %w", err) } @@ -207,7 +207,7 @@ func (s *SnowflakeAvroSyncHandler) getAvroSchema( dstTableName string, schema *model.QRecordSchema, ) (*model.QRecordAvroSchemaDefinition, error) { - avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, qvalue.QDWHTypeSnowflake) + avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, protos.DBType_SNOWFLAKE) if err != nil { return nil, fmt.Errorf("failed to define Avro schema: %w", err) } @@ -224,7 +224,7 @@ func (s *SnowflakeAvroSyncHandler) writeToAvroFile( flowJobName string, ) (*avro.AvroFile, error) { if s.config.StagingPath == "" { - ocfWriter := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressZstd, qvalue.QDWHTypeSnowflake) + ocfWriter := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressZstd, protos.DBType_SNOWFLAKE) tmpDir := fmt.Sprintf("%s/peerdb-avro-%s", os.TempDir(), flowJobName) err := os.MkdirAll(tmpDir, os.ModePerm) if err != nil { @@ -240,7 +240,7 @@ func (s *SnowflakeAvroSyncHandler) writeToAvroFile( return avroFile, nil } else if strings.HasPrefix(s.config.StagingPath, "s3://") { - ocfWriter := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressZstd, qvalue.QDWHTypeSnowflake) + ocfWriter := avro.NewPeerDBOCFWriter(stream, avroSchema, avro.CompressZstd, protos.DBType_SNOWFLAKE) s3o, err := utils.NewS3BucketAndPrefix(s.config.StagingPath) if err != nil { return nil, fmt.Errorf("failed to parse staging path: %w", err) diff --git a/flow/connectors/snowflake/qvalue_convert.go b/flow/connectors/snowflake/qvalue_convert.go index 421281834c..87a026a68b 100644 --- a/flow/connectors/snowflake/qvalue_convert.go +++ b/flow/connectors/snowflake/qvalue_convert.go @@ -34,15 +34,6 @@ var snowflakeTypeToQValueKindMap = map[string]qvalue.QValueKind{ "GEOGRAPHY": qvalue.QValueKindGeography, } -func qValueKindToSnowflakeType(colType qvalue.QValueKind) (string, error) { - val, err := colType.ToDWHColumnType(qvalue.QDWHTypeSnowflake) - if err != nil { - return "", err - } - - return val, err -} - func snowflakeTypeToQValueKind(name string) (qvalue.QValueKind, error) { if val, ok := snowflakeTypeToQValueKindMap[name]; ok { return val, nil diff --git a/flow/connectors/snowflake/snowflake.go b/flow/connectors/snowflake/snowflake.go index 3844c321fc..449c9d699f 100644 --- a/flow/connectors/snowflake/snowflake.go +++ b/flow/connectors/snowflake/snowflake.go @@ -396,7 +396,7 @@ func (c *SnowflakeConnector) ReplayTableSchemaDeltas( } for _, addedColumn := range schemaDelta.AddedColumns { - sfColtype, err := qValueKindToSnowflakeType(qvalue.QValueKind(addedColumn.ColumnType)) + sfColtype, err := qvalue.QValueKind(addedColumn.ColumnType).ToDWHColumnType(protos.DBType_SNOWFLAKE) if err != nil { return fmt.Errorf("failed to convert column type %s to snowflake type: %w", addedColumn.ColumnType, err) @@ -691,7 +691,7 @@ func generateCreateTableSQLForNormalizedTable( for _, column := range sourceTableSchema.Columns { genericColumnType := column.Type normalizedColName := SnowflakeIdentifierNormalize(column.Name) - sfColType, err := qValueKindToSnowflakeType(qvalue.QValueKind(genericColumnType)) + sfColType, err := qvalue.QValueKind(genericColumnType).ToDWHColumnType(protos.DBType_SNOWFLAKE) if err != nil { slog.Warn(fmt.Sprintf("failed to convert column type %s to snowflake type", genericColumnType), slog.Any("error", err)) diff --git a/flow/connectors/utils/avro/avro_writer.go b/flow/connectors/utils/avro/avro_writer.go index 150cdb0a9e..2fd05009e8 100644 --- a/flow/connectors/utils/avro/avro_writer.go +++ b/flow/connectors/utils/avro/avro_writer.go @@ -20,9 +20,9 @@ import ( "github.com/linkedin/goavro/v2" "github.com/PeerDB-io/peer-flow/connectors/utils" + "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/logger" "github.com/PeerDB-io/peer-flow/model" - "github.com/PeerDB-io/peer-flow/model/qvalue" ) type ( @@ -48,7 +48,7 @@ type peerDBOCFWriter struct { avroSchema *model.QRecordAvroSchemaDefinition avroCompressionCodec AvroCompressionCodec writer io.WriteCloser - targetDWH qvalue.QDWHType + targetDWH protos.DBType } type AvroFile struct { @@ -70,7 +70,7 @@ func NewPeerDBOCFWriter( stream *model.QRecordStream, avroSchema *model.QRecordAvroSchemaDefinition, avroCompressionCodec AvroCompressionCodec, - targetDWH qvalue.QDWHType, + targetDWH protos.DBType, ) *peerDBOCFWriter { return &peerDBOCFWriter{ stream: stream, diff --git a/flow/model/conversion_avro.go b/flow/model/conversion_avro.go index 94ea7ddfc3..d3b328c26c 100644 --- a/flow/model/conversion_avro.go +++ b/flow/model/conversion_avro.go @@ -6,12 +6,13 @@ import ( "go.temporal.io/sdk/log" + "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model/qvalue" ) type QRecordAvroConverter struct { QRecord []qvalue.QValue - TargetDWH qvalue.QDWHType + TargetDWH protos.DBType NullableFields map[string]struct{} ColNames []string logger log.Logger @@ -19,7 +20,7 @@ type QRecordAvroConverter struct { func NewQRecordAvroConverter( q []qvalue.QValue, - targetDWH qvalue.QDWHType, + targetDWH protos.DBType, nullableFields map[string]struct{}, colNames []string, logger log.Logger, @@ -75,7 +76,7 @@ type QRecordAvroSchemaDefinition struct { func GetAvroSchemaDefinition( dstTableName string, qRecordSchema *QRecordSchema, - targetDWH qvalue.QDWHType, + targetDWH protos.DBType, ) (*QRecordAvroSchemaDefinition, error) { avroFields := make([]QRecordAvroField, 0, len(qRecordSchema.Fields)) nullableFields := make(map[string]struct{}) diff --git a/flow/model/qvalue/avro_converter.go b/flow/model/qvalue/avro_converter.go index 536e705db6..a3aa17911a 100644 --- a/flow/model/qvalue/avro_converter.go +++ b/flow/model/qvalue/avro_converter.go @@ -11,6 +11,7 @@ import ( "github.com/shopspring/decimal" "go.temporal.io/sdk/log" + "github.com/PeerDB-io/peer-flow/generated/protos" hstore_util "github.com/PeerDB-io/peer-flow/hstore" ) @@ -56,7 +57,7 @@ type AvroSchemaField struct { // // For example, QValueKindInt64 would return an AvroLogicalSchema of "long". Unsupported QValueKinds // will return an error. -func GetAvroSchemaFromQValueKind(kind QValueKind, targetDWH QDWHType, precision int16, scale int16) (interface{}, error) { +func GetAvroSchemaFromQValueKind(kind QValueKind, targetDWH protos.DBType, precision int16, scale int16) (interface{}, error) { switch kind { case QValueKindString: return "string", nil @@ -90,7 +91,7 @@ func GetAvroSchemaFromQValueKind(kind QValueKind, targetDWH QDWHType, precision Scale: avroNumericScale, }, nil case QValueKindTime, QValueKindTimeTZ, QValueKindDate: - if targetDWH == QDWHTypeClickhouse { + if targetDWH == protos.DBType_CLICKHOUSE { if kind == QValueKindTime { return "string", nil } @@ -104,7 +105,7 @@ func GetAvroSchemaFromQValueKind(kind QValueKind, targetDWH QDWHType, precision } return "string", nil case QValueKindTimestamp, QValueKindTimestampTZ: - if targetDWH == QDWHTypeClickhouse { + if targetDWH == protos.DBType_CLICKHOUSE { return AvroSchemaLogical{ Type: "long", LogicalType: "timestamp-micros", @@ -162,12 +163,12 @@ func GetAvroSchemaFromQValueKind(kind QValueKind, targetDWH QDWHType, precision } type QValueAvroConverter struct { - TargetDWH QDWHType - Nullable bool logger log.Logger + TargetDWH protos.DBType + Nullable bool } -func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Logger) (interface{}, error) { +func QValueToAvro(value QValue, targetDWH protos.DBType, nullable bool, logger log.Logger) (interface{}, error) { if nullable && value.Value() == nil { return nil, nil } @@ -188,7 +189,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo return nil, nil } - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { if c.Nullable { return c.processNullableUnion("string", t.(string)) } else { @@ -196,7 +197,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo } } - if c.TargetDWH == QDWHTypeClickhouse { + if c.TargetDWH == protos.DBType_CLICKHOUSE { if c.Nullable { return c.processNullableUnion("string", t.(string)) } else { @@ -212,7 +213,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo if t == nil { return nil, nil } - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { if c.Nullable { return c.processNullableUnion("string", t.(string)) } else { @@ -220,7 +221,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo } } - if c.TargetDWH == QDWHTypeClickhouse { + if c.TargetDWH == protos.DBType_CLICKHOUSE { if c.Nullable { return c.processNullableUnion("long", t.(int64)) } else { @@ -236,7 +237,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo if t == nil { return nil, nil } - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { if c.Nullable { return c.processNullableUnion("string", t.(string)) } else { @@ -253,7 +254,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo if t == nil { return nil, nil } - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { if c.Nullable { return c.processNullableUnion("string", t.(string)) } else { @@ -271,7 +272,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo return nil, nil } - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { if c.Nullable { return c.processNullableUnion("string", t.(string)) } else { @@ -286,7 +287,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo case QValueQChar: return c.processNullableUnion("string", string(v.Val)) case QValueString, QValueCIDR, QValueINET, QValueMacaddr, QValueInterval: - if c.TargetDWH == QDWHTypeSnowflake && v.Value() != nil && + if c.TargetDWH == protos.DBType_SNOWFLAKE && v.Value() != nil && (len(v.Value().(string)) > 15*1024*1024) { slog.Warn("Truncating TEXT value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") @@ -294,7 +295,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo } return c.processNullableUnion("string", v.Value()) case QValueFloat32: - if c.TargetDWH == QDWHTypeBigQuery { + if c.TargetDWH == protos.DBType_BIGQUERY { return c.processNullableUnion("double", float64(v.Val)) } return c.processNullableUnion("float", v.Val) @@ -348,7 +349,7 @@ func QValueToAvro(value QValue, targetDWH QDWHType, nullable bool, logger log.Lo func (c *QValueAvroConverter) processGoTimeTZ(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { return t.Format("15:04:05.999999-0700") } return t.UnixMicro() @@ -357,10 +358,10 @@ func (c *QValueAvroConverter) processGoTimeTZ(t time.Time) interface{} { func (c *QValueAvroConverter) processGoTime(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { return t.Format("15:04:05.999999") } - if c.TargetDWH == QDWHTypeClickhouse { + if c.TargetDWH == protos.DBType_CLICKHOUSE { return t.Format("15:04:05.999999") } @@ -370,7 +371,7 @@ func (c *QValueAvroConverter) processGoTime(t time.Time) interface{} { func (c *QValueAvroConverter) processGoTimestampTZ(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { return t.Format("2006-01-02 15:04:05.999999-0700") } @@ -386,7 +387,7 @@ func (c *QValueAvroConverter) processGoTimestampTZ(t time.Time) interface{} { func (c *QValueAvroConverter) processGoTimestamp(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { return t.Format("2006-01-02 15:04:05.999999") } @@ -408,7 +409,7 @@ func (c *QValueAvroConverter) processGoDate(t time.Time) interface{} { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { return t.Format("2006-01-02") } return t @@ -444,7 +445,7 @@ func (c *QValueAvroConverter) processBytes(byteData []byte) interface{} { func (c *QValueAvroConverter) processJSON(jsonString string) (interface{}, error) { if c.Nullable { - if c.TargetDWH == QDWHTypeSnowflake && len(jsonString) > 15*1024*1024 { + if c.TargetDWH == protos.DBType_SNOWFLAKE && len(jsonString) > 15*1024*1024 { slog.Warn("Truncating JSON value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") return goavro.Union("string", ""), nil @@ -452,7 +453,7 @@ func (c *QValueAvroConverter) processJSON(jsonString string) (interface{}, error return goavro.Union("string", jsonString), nil } - if c.TargetDWH == QDWHTypeSnowflake && len(jsonString) > 15*1024*1024 { + if c.TargetDWH == protos.DBType_SNOWFLAKE && len(jsonString) > 15*1024*1024 { slog.Warn("Truncating JSON value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") return "", nil @@ -473,7 +474,7 @@ func (c *QValueAvroConverter) processArrayTime(arrayTime []time.Time) interface{ for _, t := range arrayTime { // Snowflake has issues with avro timestamp types, returning as string form // See: https://stackoverflow.com/questions/66104762/snowflake-date-column-have-incorrect-date-from-avro-file - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { transformedTimeArr = append(transformedTimeArr, t.String()) } else { transformedTimeArr = append(transformedTimeArr, t) @@ -490,7 +491,7 @@ func (c *QValueAvroConverter) processArrayTime(arrayTime []time.Time) interface{ func (c *QValueAvroConverter) processArrayDate(arrayDate []time.Time) interface{} { transformedTimeArr := make([]interface{}, 0, len(arrayDate)) for _, t := range arrayDate { - if c.TargetDWH == QDWHTypeSnowflake { + if c.TargetDWH == protos.DBType_SNOWFLAKE { transformedTimeArr = append(transformedTimeArr, t.Format("2006-01-02")) } else { transformedTimeArr = append(transformedTimeArr, t) @@ -511,7 +512,7 @@ func (c *QValueAvroConverter) processHStore(hstore string) (interface{}, error) } if c.Nullable { - if c.TargetDWH == QDWHTypeSnowflake && len(jsonString) > 15*1024*1024 { + if c.TargetDWH == protos.DBType_SNOWFLAKE && len(jsonString) > 15*1024*1024 { slog.Warn("Truncating HStore equivalent JSON value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") return goavro.Union("string", ""), nil @@ -519,7 +520,7 @@ func (c *QValueAvroConverter) processHStore(hstore string) (interface{}, error) return goavro.Union("string", jsonString), nil } - if c.TargetDWH == QDWHTypeSnowflake && len(jsonString) > 15*1024*1024 { + if c.TargetDWH == protos.DBType_SNOWFLAKE && len(jsonString) > 15*1024*1024 { slog.Warn("Truncating HStore equivalent JSON value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") return "", nil diff --git a/flow/model/qvalue/dwh.go b/flow/model/qvalue/dwh.go new file mode 100644 index 0000000000..cd21e3182d --- /dev/null +++ b/flow/model/qvalue/dwh.go @@ -0,0 +1,39 @@ +package qvalue + +import ( + "time" + + "go.temporal.io/sdk/log" + + "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/PeerDB-io/peer-flow/model/numeric" +) + +func DetermineNumericSettingForDWH(precision int16, scale int16, dwh protos.DBType) (int16, int16) { + if dwh == protos.DBType_CLICKHOUSE { + if precision > numeric.PeerDBClickhousePrecision || precision <= 0 || + scale > precision || scale < 0 { + return numeric.PeerDBClickhousePrecision, numeric.PeerDBClickhouseScale + } + } else { + if precision > numeric.PeerDBNumericPrecision || precision <= 0 || + scale > numeric.PeerDBNumericScale || scale < 0 { + return numeric.PeerDBNumericPrecision, numeric.PeerDBNumericScale + } + } + + return precision, scale +} + +// Bigquery will not allow timestamp if it is less than 1AD and more than 9999AD +func DisallowedTimestamp(dwh protos.DBType, t time.Time, logger log.Logger) bool { + if dwh == protos.DBType_BIGQUERY { + year := t.Year() + if year < 1 || year > 9999 { + logger.Warn("Nulling Timestamp value for BigQuery as it exceeds allowed range", + "timestamp", t.String()) + return true + } + } + return false +} diff --git a/flow/model/qvalue/dwh_type.go b/flow/model/qvalue/dwh_type.go deleted file mode 100644 index b6e682be1b..0000000000 --- a/flow/model/qvalue/dwh_type.go +++ /dev/null @@ -1,28 +0,0 @@ -package qvalue - -import "github.com/PeerDB-io/peer-flow/model/numeric" - -type QDWHType int - -const ( - QDWHTypeS3 QDWHType = 1 - QDWHTypeSnowflake QDWHType = 2 - QDWHTypeBigQuery QDWHType = 3 - QDWHTypeClickhouse QDWHType = 4 -) - -func DetermineNumericSettingForDWH(precision int16, scale int16, dwh QDWHType) (int16, int16) { - if dwh == QDWHTypeClickhouse { - if precision > numeric.PeerDBClickhousePrecision || precision <= 0 || - scale > precision || scale < 0 { - return numeric.PeerDBClickhousePrecision, numeric.PeerDBClickhouseScale - } - } else { - if precision > numeric.PeerDBNumericPrecision || precision <= 0 || - scale > numeric.PeerDBNumericScale || scale < 0 { - return numeric.PeerDBNumericPrecision, numeric.PeerDBNumericScale - } - } - - return precision, scale -} diff --git a/flow/model/qvalue/kind.go b/flow/model/qvalue/kind.go index f07df58383..fa0a3c2235 100644 --- a/flow/model/qvalue/kind.go +++ b/flow/model/qvalue/kind.go @@ -3,6 +3,8 @@ package qvalue import ( "fmt" "strings" + + "github.com/PeerDB-io/peer-flow/generated/protos" ) type QValueKind string @@ -129,15 +131,15 @@ var QValueKindToClickhouseTypeMap = map[QValueKind]string{ QValueKindArrayInt16: "Array(Int16)", } -func (kind QValueKind) ToDWHColumnType(dwhType QDWHType) (string, error) { +func (kind QValueKind) ToDWHColumnType(dwhType protos.DBType) (string, error) { switch dwhType { - case QDWHTypeSnowflake: + case protos.DBType_SNOWFLAKE: if val, ok := QValueKindToSnowflakeTypeMap[kind]; ok { return val, nil } else { return "STRING", nil } - case QDWHTypeClickhouse: + case protos.DBType_CLICKHOUSE: if val, ok := QValueKindToClickhouseTypeMap[kind]; ok { return val, nil } else { diff --git a/flow/model/qvalue/timestamp.go b/flow/model/qvalue/timestamp.go deleted file mode 100644 index d7d7e6ad4a..0000000000 --- a/flow/model/qvalue/timestamp.go +++ /dev/null @@ -1,20 +0,0 @@ -package qvalue - -import ( - "time" - - "go.temporal.io/sdk/log" -) - -// Bigquery will not allow timestamp if it is less than 1AD and more than 9999AD -func DisallowedTimestamp(dwh QDWHType, t time.Time, logger log.Logger) bool { - if dwh == QDWHTypeBigQuery { - year := t.Year() - if year < 1 || year > 9999 { - logger.Warn("Nulling Timestamp value for BigQuery as it exceeds allowed range", - "timestamp", t.String()) - return true - } - } - return false -} From a0ad8a45a1e9d28f03714653359c0e723994bd44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Tue, 26 Mar 2024 19:16:31 +0000 Subject: [PATCH 18/48] Enable fieldalignment lint (#1542) fieldalignment lint includes a check for "pointer bytes", go does not reorder struct fields in memory, so to optimize layout one should list in order: 1. pointers (includes maps, channels, interfaces) 2. strings (has 1 integer after pointer) 3. slices (has 2 integers after pointer) 4. value types This allows the Go GC to ignore the ends of structs, reducing how many bytes it scans --- flow/.golangci.yml | 2 - flow/activities/flowable.go | 2 +- flow/activities/snapshot_activity.go | 8 +-- flow/alerting/alerting.go | 2 +- flow/alerting/email_alert_sender.go | 4 +- flow/cmd/api.go | 4 +- flow/cmd/handler.go | 2 +- flow/cmd/worker.go | 2 +- flow/concurrency/bound_selector.go | 2 +- flow/connectors/bigquery/bigquery.go | 4 +- .../bigquery/merge_stmt_generator.go | 8 +-- flow/connectors/bigquery/qrep_avro_sync.go | 2 +- flow/connectors/postgres/cdc.go | 10 +-- .../postgres/normalize_stmt_generator.go | 13 ++-- flow/connectors/postgres/postgres.go | 8 +-- .../postgres/qrep_query_executor.go | 4 +- flow/connectors/postgres/slot_signal.go | 2 +- flow/connectors/postgres/ssh_wrapped_pool.go | 2 +- flow/connectors/s3/s3.go | 6 +- .../snowflake/merge_stmt_generator.go | 13 ++-- flow/connectors/snowflake/snowflake.go | 2 +- flow/connectors/utils/avro/avro_writer.go | 6 +- .../utils/cdc_records/cdc_records_storage.go | 6 +- flow/connectors/utils/lua.go | 12 ++-- .../connectors/utils/monitoring/monitoring.go | 4 +- flow/e2e/bigquery/bigquery.go | 2 +- flow/e2e/bigquery/bigquery_helper.go | 4 +- flow/e2e/congen.go | 4 +- flow/e2e/snowflake/snowflake.go | 2 +- flow/model/cdc_record_stream.go | 4 +- flow/model/conversion_avro.go | 8 +-- flow/model/model.go | 70 +++++++++---------- flow/model/qrecord_batch.go | 6 +- flow/model/qrecord_stream.go | 4 +- flow/shared/telemetry/interface.go | 4 +- flow/workflows/cdc_flow.go | 6 +- flow/workflows/normalize_flow.go | 12 ++-- flow/workflows/setup_flow.go | 30 ++++---- flow/workflows/snapshot_flow.go | 4 +- 39 files changed, 145 insertions(+), 145 deletions(-) diff --git a/flow/.golangci.yml b/flow/.golangci.yml index 1b03b3c3a3..89c332defb 100644 --- a/flow/.golangci.yml +++ b/flow/.golangci.yml @@ -30,7 +30,6 @@ linters: - thelper - unconvert - unparam - - unparam - unused - wastedassign - whitespace @@ -60,7 +59,6 @@ linters-settings: govet: enable-all: true disable: - - fieldalignment - shadow stylecheck: checks: diff --git a/flow/activities/flowable.go b/flow/activities/flowable.go index 01c2789cdf..d501309294 100644 --- a/flow/activities/flowable.go +++ b/flow/activities/flowable.go @@ -38,8 +38,8 @@ type CheckConnectionResult struct { type FlowableActivity struct { CatalogPool *pgxpool.Pool Alerter *alerting.Alerter - CdcCacheRw sync.RWMutex CdcCache map[string]connectors.CDCPullConnector + CdcCacheRw sync.RWMutex } func (a *FlowableActivity) CheckConnection( diff --git a/flow/activities/snapshot_activity.go b/flow/activities/snapshot_activity.go index d5aeb50ed7..6faea50ee5 100644 --- a/flow/activities/snapshot_activity.go +++ b/flow/activities/snapshot_activity.go @@ -17,9 +17,9 @@ import ( ) type SlotSnapshotState struct { - snapshotName string - signal connpostgres.SlotSignal connector connectors.CDCPullConnector + signal connpostgres.SlotSignal + snapshotName string } type TxSnapshotState struct { @@ -28,10 +28,10 @@ type TxSnapshotState struct { } type SnapshotActivity struct { - SnapshotStatesMutex sync.Mutex + Alerter *alerting.Alerter SlotSnapshotStates map[string]SlotSnapshotState TxSnapshotStates map[string]TxSnapshotState - Alerter *alerting.Alerter + SnapshotStatesMutex sync.Mutex } // closes the slot signal diff --git a/flow/alerting/alerting.go b/flow/alerting/alerting.go index acdbe6c290..3d5f7bcbaf 100644 --- a/flow/alerting/alerting.go +++ b/flow/alerting/alerting.go @@ -26,8 +26,8 @@ type Alerter struct { } type AlertSenderConfig struct { - Id int64 Sender AlertSender + Id int64 } func (a *Alerter) registerSendersFromPool(ctx context.Context) ([]AlertSenderConfig, error) { diff --git a/flow/alerting/email_alert_sender.go b/flow/alerting/email_alert_sender.go index 2a534318c0..62d6022747 100644 --- a/flow/alerting/email_alert_sender.go +++ b/flow/alerting/email_alert_sender.go @@ -19,9 +19,9 @@ type EmailAlertSender struct { sourceEmail string configurationSetName string replyToAddresses []string + emailAddresses []string slotLagMBAlertThreshold uint32 openConnectionsAlertThreshold uint32 - emailAddresses []string } func (e *EmailAlertSender) getSlotLagMBAlertThreshold() uint32 { @@ -36,9 +36,9 @@ type EmailAlertSenderConfig struct { sourceEmail string configurationSetName string replyToAddresses []string + EmailAddresses []string `json:"email_addresses"` SlotLagMBAlertThreshold uint32 `json:"slot_lag_mb_alert_threshold"` OpenConnectionsAlertThreshold uint32 `json:"open_connections_alert_threshold"` - EmailAddresses []string `json:"email_addresses"` } func (e *EmailAlertSender) sendAlert(ctx context.Context, alertTitle string, alertMessage string) error { diff --git a/flow/cmd/api.go b/flow/cmd/api.go index cf4d84b678..f2e1873242 100644 --- a/flow/cmd/api.go +++ b/flow/cmd/api.go @@ -29,12 +29,12 @@ import ( ) type APIServerParams struct { - Port uint16 - GatewayPort uint16 TemporalHostPort string TemporalNamespace string TemporalCert string TemporalKey string + Port uint16 + GatewayPort uint16 } // setupGRPCGatewayServer sets up the grpc-gateway mux diff --git a/flow/cmd/handler.go b/flow/cmd/handler.go index 7c528d8333..7493fb150b 100644 --- a/flow/cmd/handler.go +++ b/flow/cmd/handler.go @@ -22,10 +22,10 @@ import ( // grpc server implementation type FlowRequestHandler struct { + protos.UnimplementedFlowServiceServer temporalClient client.Client pool *pgxpool.Pool peerflowTaskQueueID string - protos.UnimplementedFlowServiceServer } func NewFlowRequestHandler(temporalClient client.Client, pool *pgxpool.Pool, taskQueue string) *FlowRequestHandler { diff --git a/flow/cmd/worker.go b/flow/cmd/worker.go index c9e3ed14f1..b825a18d7b 100644 --- a/flow/cmd/worker.go +++ b/flow/cmd/worker.go @@ -24,13 +24,13 @@ import ( type WorkerOptions struct { TemporalHostPort string - EnableProfiling bool PyroscopeServer string TemporalNamespace string TemporalCert string TemporalKey string TemporalMaxConcurrentActivities int TemporalMaxConcurrentWorkflowTasks int + EnableProfiling bool } func setupPyroscope(opts *WorkerOptions) { diff --git a/flow/concurrency/bound_selector.go b/flow/concurrency/bound_selector.go index 922a422740..35ea84412d 100644 --- a/flow/concurrency/bound_selector.go +++ b/flow/concurrency/bound_selector.go @@ -7,9 +7,9 @@ import ( ) type BoundSelector struct { - limit int futures []workflow.Future ferrors []error + limit int } func NewBoundSelector(limit int) *BoundSelector { diff --git a/flow/connectors/bigquery/bigquery.go b/flow/connectors/bigquery/bigquery.go index e2f2f12659..8426ce6701 100644 --- a/flow/connectors/bigquery/bigquery.go +++ b/flow/connectors/bigquery/bigquery.go @@ -33,14 +33,14 @@ const ( ) type BigQueryConnector struct { + logger log.Logger bqConfig *protos.BigqueryConfig client *bigquery.Client storageClient *storage.Client pgMetadata *metadataStore.PostgresMetadataStore + catalogPool *pgxpool.Pool datasetID string projectID string - catalogPool *pgxpool.Pool - logger log.Logger } func NewBigQueryServiceAccount(bqConfig *protos.BigqueryConfig) (*utils.GcpServiceAccount, error) { diff --git a/flow/connectors/bigquery/merge_stmt_generator.go b/flow/connectors/bigquery/merge_stmt_generator.go index 989e8f7435..d81efb865e 100644 --- a/flow/connectors/bigquery/merge_stmt_generator.go +++ b/flow/connectors/bigquery/merge_stmt_generator.go @@ -12,18 +12,18 @@ import ( type mergeStmtGenerator struct { // dataset + raw table rawDatasetTable datasetTable - // destination table name, used to retrieve records from raw table - dstTableName string // dataset + destination table dstDatasetTable datasetTable - // batch id currently to be merged - mergeBatchId int64 // the schema of the table to merge into normalizedTableSchema *protos.TableSchema // _PEERDB_IS_DELETED and _SYNCED_AT columns peerdbCols *protos.PeerDBColumns // map for shorter columns shortColumn map[string]string + // destination table name, used to retrieve records from raw table + dstTableName string + // batch id currently to be merged + mergeBatchId int64 } // generateFlattenedCTE generates a flattened CTE. diff --git a/flow/connectors/bigquery/qrep_avro_sync.go b/flow/connectors/bigquery/qrep_avro_sync.go index 06c48391fd..82f0d7e687 100644 --- a/flow/connectors/bigquery/qrep_avro_sync.go +++ b/flow/connectors/bigquery/qrep_avro_sync.go @@ -232,8 +232,8 @@ func (s *QRepAvroSyncMethod) SyncQRepRecords( } type AvroField struct { - Name string `json:"name"` Type interface{} `json:"type"` + Name string `json:"name"` } type AvroSchema struct { diff --git a/flow/connectors/postgres/cdc.go b/flow/connectors/postgres/cdc.go index 056eafcccc..46aaab5d4e 100644 --- a/flow/connectors/postgres/cdc.go +++ b/flow/connectors/postgres/cdc.go @@ -46,21 +46,21 @@ type PostgresCDCSource struct { } type PostgresCDCConfig struct { - Slot string - Publication string + CatalogPool *pgxpool.Pool SrcTableIDNameMapping map[uint32]string TableNameMapping map[string]model.NameAndExclude TableNameSchemaMapping map[string]*protos.TableSchema ChildToParentRelIDMap map[uint32]uint32 - CatalogPool *pgxpool.Pool - FlowJobName string RelationMessageMapping model.RelationMessageMapping + FlowJobName string + Slot string + Publication string } type startReplicationOpts struct { conn *pgconn.PgConn - startLSN pglogrepl.LSN replicationOpts pglogrepl.StartReplicationOptions + startLSN pglogrepl.LSN } // Create a new PostgresCDCSource diff --git a/flow/connectors/postgres/normalize_stmt_generator.go b/flow/connectors/postgres/normalize_stmt_generator.go index f9ff1d5f07..d9acce4d96 100644 --- a/flow/connectors/postgres/normalize_stmt_generator.go +++ b/flow/connectors/postgres/normalize_stmt_generator.go @@ -15,21 +15,22 @@ import ( ) type normalizeStmtGenerator struct { + // to log fallback statement selection + logger log.Logger + // _PEERDB_RAW_... rawTableName string // destination table name, used to retrieve records from raw table dstTableName string // the schema of the table to merge into normalizedTableSchema *protos.TableSchema - // array of toast column combinations that are unchanged - unchangedToastColumns []string // _PEERDB_IS_DELETED and _SYNCED_AT columns peerdbCols *protos.PeerDBColumns - // Postgres version 15 introduced MERGE, fallback statements before that - supportsMerge bool // Postgres metadata schema metadataSchema string - // to log fallback statement selection - logger log.Logger + // array of toast column combinations that are unchanged + unchangedToastColumns []string + // Postgres version 15 introduced MERGE, fallback statements before that + supportsMerge bool } func (n *normalizeStmtGenerator) generateNormalizeStatements() []string { diff --git a/flow/connectors/postgres/postgres.go b/flow/connectors/postgres/postgres.go index 57cd7e9d86..f013468534 100644 --- a/flow/connectors/postgres/postgres.go +++ b/flow/connectors/postgres/postgres.go @@ -31,19 +31,19 @@ import ( ) type PostgresConnector struct { - connStr string + logger log.Logger config *protos.PostgresConfig ssh *SSHTunnel conn *pgx.Conn replConfig *pgx.ConnConfig replConn *pgx.Conn replState *ReplState - replLock sync.Mutex customTypesMapping map[uint32]string - metadataSchema string hushWarnOID map[uint32]struct{} - logger log.Logger relationMessageMapping model.RelationMessageMapping + connStr string + metadataSchema string + replLock sync.Mutex } type ReplState struct { diff --git a/flow/connectors/postgres/qrep_query_executor.go b/flow/connectors/postgres/qrep_query_executor.go index f7fb9accbd..ea21752720 100644 --- a/flow/connectors/postgres/qrep_query_executor.go +++ b/flow/connectors/postgres/qrep_query_executor.go @@ -21,11 +21,11 @@ import ( type QRepQueryExecutor struct { *PostgresConnector + logger log.Logger snapshot string - testEnv bool flowJobName string partitionID string - logger log.Logger + testEnv bool } func (c *PostgresConnector) NewQRepQueryExecutor(flowJobName string, partitionID string) *QRepQueryExecutor { diff --git a/flow/connectors/postgres/slot_signal.go b/flow/connectors/postgres/slot_signal.go index be6395917b..bd5bcbbd52 100644 --- a/flow/connectors/postgres/slot_signal.go +++ b/flow/connectors/postgres/slot_signal.go @@ -1,10 +1,10 @@ package connpostgres type SlotCreationResult struct { + Err error SlotName string SnapshotName string SupportsTIDScans bool - Err error } // This struct contains two signals. diff --git a/flow/connectors/postgres/ssh_wrapped_pool.go b/flow/connectors/postgres/ssh_wrapped_pool.go index ccfb6c6488..7c13e0be99 100644 --- a/flow/connectors/postgres/ssh_wrapped_pool.go +++ b/flow/connectors/postgres/ssh_wrapped_pool.go @@ -19,8 +19,8 @@ import ( type SSHTunnel struct { sshConfig *ssh.ClientConfig - sshServer string sshClient *ssh.Client + sshServer string } func NewSSHTunnel( diff --git a/flow/connectors/s3/s3.go b/flow/connectors/s3/s3.go index fddd69f78f..3003f5eb53 100644 --- a/flow/connectors/s3/s3.go +++ b/flow/connectors/s3/s3.go @@ -23,11 +23,11 @@ const ( ) type S3Connector struct { - url string + logger log.Logger pgMetadata *metadataStore.PostgresMetadataStore - client s3.Client creds utils.S3PeerCredentials - logger log.Logger + url string + client s3.Client } func NewS3Connector( diff --git a/flow/connectors/snowflake/merge_stmt_generator.go b/flow/connectors/snowflake/merge_stmt_generator.go index be5b244398..f384c8b4c0 100644 --- a/flow/connectors/snowflake/merge_stmt_generator.go +++ b/flow/connectors/snowflake/merge_stmt_generator.go @@ -12,17 +12,18 @@ import ( ) type mergeStmtGenerator struct { + // the schema of the table to merge into + normalizedTableSchema *protos.TableSchema + // _PEERDB_IS_DELETED and _SYNCED_AT columns + peerdbCols *protos.PeerDBColumns + // _PEERDB_RAW_... rawTableName string // destination table name, used to retrieve records from raw table dstTableName string - // Id of the currently merging batch - mergeBatchId int64 - // the schema of the table to merge into - normalizedTableSchema *protos.TableSchema // array of toast column combinations that are unchanged unchangedToastColumns []string - // _PEERDB_IS_DELETED and _SYNCED_AT columns - peerdbCols *protos.PeerDBColumns + // Id of the currently merging batch + mergeBatchId int64 } func (m *mergeStmtGenerator) generateMergeStmt() (string, error) { diff --git a/flow/connectors/snowflake/snowflake.go b/flow/connectors/snowflake/snowflake.go index 449c9d699f..743c18a691 100644 --- a/flow/connectors/snowflake/snowflake.go +++ b/flow/connectors/snowflake/snowflake.go @@ -81,8 +81,8 @@ const ( type SnowflakeConnector struct { database *sql.DB pgMetadata *metadataStore.PostgresMetadataStore - rawSchema string logger log.Logger + rawSchema string } // creating this to capture array results from snowflake. diff --git a/flow/connectors/utils/avro/avro_writer.go b/flow/connectors/utils/avro/avro_writer.go index 2fd05009e8..d9f72dc50a 100644 --- a/flow/connectors/utils/avro/avro_writer.go +++ b/flow/connectors/utils/avro/avro_writer.go @@ -46,15 +46,15 @@ const ( type peerDBOCFWriter struct { stream *model.QRecordStream avroSchema *model.QRecordAvroSchemaDefinition - avroCompressionCodec AvroCompressionCodec writer io.WriteCloser + avroCompressionCodec AvroCompressionCodec targetDWH protos.DBType } type AvroFile struct { - NumRecords int - StorageLocation AvroStorageLocation FilePath string + StorageLocation AvroStorageLocation + NumRecords int } func (l *AvroFile) Cleanup() { diff --git a/flow/connectors/utils/cdc_records/cdc_records_storage.go b/flow/connectors/utils/cdc_records/cdc_records_storage.go index 1de0a6d2cd..2b6dbce8b9 100644 --- a/flow/connectors/utils/cdc_records/cdc_records_storage.go +++ b/flow/connectors/utils/cdc_records/cdc_records_storage.go @@ -34,12 +34,12 @@ func encVal(val any) ([]byte, error) { type cdcRecordsStore struct { inMemoryRecords map[model.TableWithPkey]model.Record pebbleDB *pebble.DB - numRecords atomic.Int32 flowJobName string dbFolderName string - numRecordsSwitchThreshold int - memThresholdBytes uint64 thresholdReason string + memThresholdBytes uint64 + numRecords atomic.Int32 + numRecordsSwitchThreshold int memStats runtime.MemStats } diff --git a/flow/connectors/utils/lua.go b/flow/connectors/utils/lua.go index 2acd8821b9..ec4805e150 100644 --- a/flow/connectors/utils/lua.go +++ b/flow/connectors/utils/lua.go @@ -43,14 +43,14 @@ func LoadScript(ctx context.Context, script string, printfn lua.LGFunction) (*lu ls := lua.NewState(lua.Options{SkipOpenLibs: true}) ls.SetContext(ctx) for _, pair := range []struct { - n string f lua.LGFunction + n string }{ - {lua.LoadLibName, lua.OpenPackage}, // Must be first - {lua.BaseLibName, lua.OpenBase}, - {lua.TabLibName, lua.OpenTable}, - {lua.StringLibName, lua.OpenString}, - {lua.MathLibName, lua.OpenMath}, + {lua.OpenPackage, lua.LoadLibName}, // Must be first + {lua.OpenBase, lua.BaseLibName}, + {lua.OpenTable, lua.TabLibName}, + {lua.OpenString, lua.StringLibName}, + {lua.OpenMath, lua.MathLibName}, } { ls.Push(ls.NewFunction(pair.f)) ls.Push(lua.LString(pair.n)) diff --git a/flow/connectors/utils/monitoring/monitoring.go b/flow/connectors/utils/monitoring/monitoring.go index 472cc1efed..a402968544 100644 --- a/flow/connectors/utils/monitoring/monitoring.go +++ b/flow/connectors/utils/monitoring/monitoring.go @@ -19,10 +19,10 @@ import ( ) type CDCBatchInfo struct { + StartTime time.Time BatchID int64 - RowsInBatch uint32 BatchEndlSN int64 - StartTime time.Time + RowsInBatch uint32 } func InitializeCDCFlow(ctx context.Context, pool *pgxpool.Pool, flowJobName string) error { diff --git a/flow/e2e/bigquery/bigquery.go b/flow/e2e/bigquery/bigquery.go index 1e2a3842ee..ae57c0a449 100644 --- a/flow/e2e/bigquery/bigquery.go +++ b/flow/e2e/bigquery/bigquery.go @@ -19,9 +19,9 @@ import ( type PeerFlowE2ETestSuiteBQ struct { t *testing.T - bqSuffix string conn *connpostgres.PostgresConnector bqHelper *BigQueryTestHelper + bqSuffix string } func (s PeerFlowE2ETestSuiteBQ) T() *testing.T { diff --git a/flow/e2e/bigquery/bigquery_helper.go b/flow/e2e/bigquery/bigquery_helper.go index cb8558866a..25b7b94e41 100644 --- a/flow/e2e/bigquery/bigquery_helper.go +++ b/flow/e2e/bigquery/bigquery_helper.go @@ -24,14 +24,14 @@ import ( ) type BigQueryTestHelper struct { - // runID uniquely identifies the test run to namespace stateful schemas. - runID uint64 // config is the BigQuery config. Config *protos.BigqueryConfig // peer struct holder BigQuery Peer *protos.Peer // client to talk to BigQuery client *bigquery.Client + // runID uniquely identifies the test run to namespace stateful schemas. + runID uint64 } // NewBigQueryTestHelper creates a new BigQueryTestHelper. diff --git a/flow/e2e/congen.go b/flow/e2e/congen.go index 6d19b48d4e..cf89abcd05 100644 --- a/flow/e2e/congen.go +++ b/flow/e2e/congen.go @@ -162,10 +162,10 @@ func GeneratePostgresPeer() *protos.Peer { type FlowConnectionGenerationConfig struct { FlowJobName string - TableMappings []*protos.TableMapping TableNameMapping map[string]string Destination *protos.Peer CdcStagingPath string + TableMappings []*protos.TableMapping SoftDelete bool } @@ -214,9 +214,9 @@ type QRepFlowConnectionGenerationConfig struct { FlowJobName string WatermarkTable string DestinationTableIdentifier string - PostgresPort int Destination *protos.Peer StagingPath string + PostgresPort uint16 } // GenerateQRepConfig generates a qrep config for testing. diff --git a/flow/e2e/snowflake/snowflake.go b/flow/e2e/snowflake/snowflake.go index 06c46d1046..cf02014a25 100644 --- a/flow/e2e/snowflake/snowflake.go +++ b/flow/e2e/snowflake/snowflake.go @@ -22,10 +22,10 @@ import ( type PeerFlowE2ETestSuiteSF struct { t *testing.T - pgSuffix string conn *connpostgres.PostgresConnector sfHelper *SnowflakeTestHelper connector *connsnowflake.SnowflakeConnector + pgSuffix string } func (s PeerFlowE2ETestSuiteSF) T() *testing.T { diff --git a/flow/model/cdc_record_stream.go b/flow/model/cdc_record_stream.go index 0e2e633d4c..25f6aac9a5 100644 --- a/flow/model/cdc_record_stream.go +++ b/flow/model/cdc_record_stream.go @@ -8,6 +8,8 @@ import ( ) type CDCRecordStream struct { + // empty signal to indicate if the records are going to be empty or not. + emptySignal chan bool // Records are a list of json objects. records chan Record // Schema changes from the slot @@ -16,8 +18,6 @@ type CDCRecordStream struct { lastCheckpointSet bool // lastCheckpointID is the last ID of the commit that corresponds to this batch. lastCheckpointID atomic.Int64 - // empty signal to indicate if the records are going to be empty or not. - emptySignal chan bool } func NewCDCRecordStream() *CDCRecordStream { diff --git a/flow/model/conversion_avro.go b/flow/model/conversion_avro.go index d3b328c26c..1df765dde4 100644 --- a/flow/model/conversion_avro.go +++ b/flow/model/conversion_avro.go @@ -11,11 +11,11 @@ import ( ) type QRecordAvroConverter struct { + logger log.Logger QRecord []qvalue.QValue - TargetDWH protos.DBType NullableFields map[string]struct{} ColNames []string - logger log.Logger + TargetDWH protos.DBType } func NewQRecordAvroConverter( @@ -58,8 +58,8 @@ func (qac *QRecordAvroConverter) Convert() (map[string]interface{}, error) { } type QRecordAvroField struct { - Name string `json:"name"` Type interface{} `json:"type"` + Name string `json:"name"` } type QRecordAvroSchema struct { @@ -69,8 +69,8 @@ type QRecordAvroSchema struct { } type QRecordAvroSchemaDefinition struct { - Schema string NullableFields map[string]struct{} + Schema string } func GetAvroSchemaDefinition( diff --git a/flow/model/model.go b/flow/model/model.go index 0754db0c66..275e59f1f5 100644 --- a/flow/model/model.go +++ b/flow/model/model.go @@ -9,8 +9,8 @@ import ( ) type NameAndExclude struct { - Name string Exclude map[string]struct{} + Name string } func NewNameAndExclude(name string, exclude []string) NameAndExclude { @@ -25,14 +25,10 @@ func NewNameAndExclude(name string, exclude []string) NameAndExclude { } type PullRecordsRequest struct { + // record batch for pushing changes into + RecordStream *CDCRecordStream // FlowJobName is the name of the flow job. FlowJobName string - // LastOffset is the latest LSN that was synced. - LastOffset int64 - // MaxBatchSize is the max number of records to fetch. - MaxBatchSize uint32 - // IdleTimeout is the timeout to wait for new records. - IdleTimeout time.Duration // relId to name Mapping SrcTableIDNameMapping map[uint32]string // source to destination table name mapping @@ -43,8 +39,12 @@ type PullRecordsRequest struct { OverridePublicationName string // override replication slot name OverrideReplicationSlotName string - // record batch for pushing changes into - RecordStream *CDCRecordStream + // LastOffset is the latest LSN that was synced. + LastOffset int64 + // MaxBatchSize is the max number of records to fetch. + MaxBatchSize uint32 + // IdleTimeout is the timeout to wait for new records. + IdleTimeout time.Duration } type Record interface { @@ -92,15 +92,15 @@ func (r *BaseRecord) GetCommitTime() time.Time { } type InsertRecord struct { - BaseRecord + // Items is a map of column name to value. + Items *RecordItems // Name of the source table SourceTableName string // Name of the destination table DestinationTableName string // CommitID is the ID of the commit corresponding to this record. CommitID int64 - // Items is a map of column name to value. - Items *RecordItems + BaseRecord } func (r *InsertRecord) GetDestinationTableName() string { @@ -123,17 +123,17 @@ func (r *InsertRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts } type UpdateRecord struct { - BaseRecord - // Name of the source table - SourceTableName string - // Name of the destination table - DestinationTableName string // OldItems is a map of column name to value. OldItems *RecordItems // NewItems is a map of column name to value. NewItems *RecordItems // unchanged toast columns UnchangedToastColumns map[string]struct{} + // Name of the source table + SourceTableName string + // Name of the destination table + DestinationTableName string + BaseRecord } func (r *UpdateRecord) GetDestinationTableName() string { @@ -156,15 +156,15 @@ func (r *UpdateRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts } type DeleteRecord struct { - BaseRecord - // Name of the source table - SourceTableName string - // Name of the destination table - DestinationTableName string // Items is a map of column name to value. Items *RecordItems // unchanged toast columns, filled from latest UpdateRecord UnchangedToastColumns map[string]struct{} + // Name of the source table + SourceTableName string + // Name of the destination table + DestinationTableName string + BaseRecord } func (r *DeleteRecord) GetDestinationTableName() string { @@ -193,43 +193,43 @@ type TableWithPkey struct { } type SyncRecordsRequest struct { - SyncBatchID int64 - Records *CDCRecordStream + Records *CDCRecordStream // FlowJobName is the name of the flow job. FlowJobName string - // source:destination mappings - TableMappings []*protos.TableMapping // Staging path for AVRO files in CDC StagingPath string // Lua script Script string + // source:destination mappings + TableMappings []*protos.TableMapping + SyncBatchID int64 } type NormalizeRecordsRequest struct { + TableNameSchemaMapping map[string]*protos.TableSchema FlowJobName string - SyncBatchID int64 - SoftDelete bool SoftDeleteColName string SyncedAtColName string - TableNameSchemaMapping map[string]*protos.TableSchema + SyncBatchID int64 + SoftDelete bool } type SyncResponse struct { + // TableNameRowsMapping tells how many records need to be synced to each destination table. + TableNameRowsMapping map[string]*RecordTypeCounts + // to be carried to parent workflow + TableSchemaDeltas []*protos.TableSchemaDelta // LastSyncedCheckpointID is the last ID that was synced. LastSyncedCheckpointID int64 // NumRecordsSynced is the number of records that were synced. NumRecordsSynced int64 CurrentSyncBatchID int64 - // TableNameRowsMapping tells how many records need to be synced to each destination table. - TableNameRowsMapping map[string]*RecordTypeCounts - // to be carried to parent workflow - TableSchemaDeltas []*protos.TableSchemaDelta } type NormalizePayload struct { + TableNameSchemaMapping map[string]*protos.TableSchema Done bool SyncBatchID int64 - TableNameSchemaMapping map[string]*protos.TableSchema } type NormalizeResponse struct { @@ -241,8 +241,8 @@ type NormalizeResponse struct { // being clever and passing the delta back as a regular record instead of heavy CDC refactoring. type RelationRecord struct { - BaseRecord TableSchemaDelta *protos.TableSchemaDelta `json:"tableSchemaDelta"` + BaseRecord } func (r *RelationRecord) GetDestinationTableName() string { diff --git a/flow/model/qrecord_batch.go b/flow/model/qrecord_batch.go index eabd187ade..aaa13ea3e2 100644 --- a/flow/model/qrecord_batch.go +++ b/flow/model/qrecord_batch.go @@ -16,8 +16,8 @@ import ( // QRecordBatch holds a batch of []QValue slices type QRecordBatch struct { - Records [][]qvalue.QValue Schema *QRecordSchema + Records [][]qvalue.QValue } func (q *QRecordBatch) ToQRecordStream(buffer int) (*QRecordStream, error) { @@ -53,10 +53,10 @@ func constructArray[T any](qValue qvalue.QValue, typeName string) (*pgtype.Array } type QRecordBatchCopyFromSource struct { - numRecords int + err error stream *QRecordStream currentRecord QRecordOrError - err error + numRecords int } func NewQRecordBatchCopyFromSource( diff --git a/flow/model/qrecord_stream.go b/flow/model/qrecord_stream.go index 0feafe5502..b79ece015c 100644 --- a/flow/model/qrecord_stream.go +++ b/flow/model/qrecord_stream.go @@ -13,8 +13,8 @@ type RecordTypeCounts struct { } type QRecordOrError struct { - Record []qvalue.QValue Err error + Record []qvalue.QValue } type QRecordSchemaOrError struct { @@ -25,8 +25,8 @@ type QRecordSchemaOrError struct { type QRecordStream struct { schema chan QRecordSchemaOrError Records chan QRecordOrError - schemaSet bool schemaCache *QRecordSchema + schemaSet bool } type RecordsToStreamRequest struct { diff --git a/flow/shared/telemetry/interface.go b/flow/shared/telemetry/interface.go index 6ee7d6f391..4287a7661e 100644 --- a/flow/shared/telemetry/interface.go +++ b/flow/shared/telemetry/interface.go @@ -9,10 +9,10 @@ type Sender interface { } type Attributes struct { - Level Level DeploymentUID string - Tags []string Type string + Level Level + Tags []string } type Level string diff --git a/flow/workflows/cdc_flow.go b/flow/workflows/cdc_flow.go index d011acd690..8144085fd8 100644 --- a/flow/workflows/cdc_flow.go +++ b/flow/workflows/cdc_flow.go @@ -22,15 +22,15 @@ import ( ) type CDCFlowWorkflowState struct { - // Current signalled state of the peer flow. - ActiveSignal model.CDCFlowSignal // deprecated field RelationMessageMapping model.RelationMessageMapping - CurrentFlowStatus protos.FlowStatus // flow config update request, set to nil after processed FlowConfigUpdate *protos.CDCFlowConfigUpdate // options passed to all SyncFlows SyncFlowOptions *protos.SyncFlowOptions + // Current signalled state of the peer flow. + ActiveSignal model.CDCFlowSignal + CurrentFlowStatus protos.FlowStatus } // returns a new empty PeerFlowState diff --git a/flow/workflows/normalize_flow.go b/flow/workflows/normalize_flow.go index 6f6cbdb418..e4ed09e072 100644 --- a/flow/workflows/normalize_flow.go +++ b/flow/workflows/normalize_flow.go @@ -14,20 +14,20 @@ import ( ) type NormalizeState struct { - Wait bool - Stop bool + TableNameSchemaMapping map[string]*protos.TableSchema LastSyncBatchID int64 SyncBatchID int64 - TableNameSchemaMapping map[string]*protos.TableSchema + Wait bool + Stop bool } func NewNormalizeState() *NormalizeState { return &NormalizeState{ - Wait: true, - Stop: false, + TableNameSchemaMapping: nil, LastSyncBatchID: -1, SyncBatchID: -1, - TableNameSchemaMapping: nil, + Wait: true, + Stop: false, } } diff --git a/flow/workflows/setup_flow.go b/flow/workflows/setup_flow.go index 4355bd832c..2c2b0876d6 100644 --- a/flow/workflows/setup_flow.go +++ b/flow/workflows/setup_flow.go @@ -31,19 +31,19 @@ import ( // - creating the raw table on the destination peer // - creating the normalized table on the destination peer type SetupFlowExecution struct { + log.Logger tableNameMapping map[string]string cdcFlowName string executionID string - logger log.Logger } // NewSetupFlowExecution creates a new instance of SetupFlowExecution. func NewSetupFlowExecution(ctx workflow.Context, tableNameMapping map[string]string, cdcFlowName string) *SetupFlowExecution { return &SetupFlowExecution{ + Logger: log.With(workflow.GetLogger(ctx), slog.String(string(shared.FlowNameKey), cdcFlowName)), tableNameMapping: tableNameMapping, cdcFlowName: cdcFlowName, executionID: workflow.GetInfo(ctx).WorkflowExecution.ID, - logger: log.With(workflow.GetLogger(ctx), slog.String(string(shared.FlowNameKey), cdcFlowName)), } } @@ -53,7 +53,7 @@ func (s *SetupFlowExecution) checkConnectionsAndSetupMetadataTables( ctx workflow.Context, config *protos.FlowConnectionConfigs, ) error { - s.logger.Info("checking connections for CDC flow") + s.Info("checking connections for CDC flow") checkCtx := workflow.WithLocalActivityOptions(ctx, workflow.LocalActivityOptions{ StartToCloseTimeout: time.Minute, @@ -81,7 +81,7 @@ func (s *SetupFlowExecution) checkConnectionsAndSetupMetadataTables( return fmt.Errorf("failed to check destination peer connection: %w", err) } - s.logger.Info("ensuring metadata table exists") + s.Info("ensuring metadata table exists") // then setup the destination peer metadata tables if destConnStatus.NeedsSetupMetadataTables { @@ -93,7 +93,7 @@ func (s *SetupFlowExecution) checkConnectionsAndSetupMetadataTables( return fmt.Errorf("failed to setup destination peer metadata tables: %w", err) } } else { - s.logger.Info("destination peer metadata tables already exist") + s.Info("destination peer metadata tables already exist") } return nil @@ -105,7 +105,7 @@ func (s *SetupFlowExecution) ensurePullability( config *protos.FlowConnectionConfigs, checkConstraints bool, ) (map[uint32]string, error) { - s.logger.Info("ensuring pullability for peer flow") + s.Info("ensuring pullability for peer flow") ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 4 * time.Hour, @@ -126,7 +126,7 @@ func (s *SetupFlowExecution) ensurePullability( future := workflow.ExecuteActivity(ctx, flowable.EnsurePullability, ensurePullabilityInput) var ensurePullabilityOutput *protos.EnsurePullabilityBatchOutput if err := future.Get(ctx, &ensurePullabilityOutput); err != nil { - s.logger.Error("failed to ensure pullability for tables: ", err) + s.Error("failed to ensure pullability for tables: ", err) return nil, fmt.Errorf("failed to ensure pullability for tables: %w", err) } @@ -146,7 +146,7 @@ func (s *SetupFlowExecution) createRawTable( ctx workflow.Context, config *protos.FlowConnectionConfigs, ) error { - s.logger.Info("creating raw table on destination") + s.Info("creating raw table on destination") ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 5 * time.Minute, }) @@ -171,7 +171,7 @@ func (s *SetupFlowExecution) createRawTable( func (s *SetupFlowExecution) fetchTableSchemaAndSetupNormalizedTables( ctx workflow.Context, flowConnectionConfigs *protos.FlowConnectionConfigs, ) (map[string]*protos.TableSchema, error) { - s.logger.Info("fetching table schema for peer flow") + s.Info("fetching table schema for peer flow") ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ StartToCloseTimeout: 1 * time.Hour, @@ -191,7 +191,7 @@ func (s *SetupFlowExecution) fetchTableSchemaAndSetupNormalizedTables( var tblSchemaOutput *protos.GetTableSchemaBatchOutput if err := future.Get(ctx, &tblSchemaOutput); err != nil { - s.logger.Error("failed to fetch schema for source tables", slog.Any("error", err)) + s.Error("failed to fetch schema for source tables", slog.Any("error", err)) return nil, fmt.Errorf("failed to fetch schema for source table %s: %w", sourceTables, err) } @@ -199,9 +199,9 @@ func (s *SetupFlowExecution) fetchTableSchemaAndSetupNormalizedTables( sortedSourceTables := maps.Keys(tableNameSchemaMapping) sort.Strings(sortedSourceTables) - s.logger.Info("setting up normalized tables for peer flow") + s.Info("setting up normalized tables for peer flow") normalizedTableMapping := shared.BuildProcessedSchemaMapping(flowConnectionConfigs.TableMappings, - tableNameSchemaMapping, s.logger) + tableNameSchemaMapping, s.Logger) // now setup the normalized tables on the destination peer setupConfig := &protos.SetupNormalizedTableBatchInput{ @@ -214,11 +214,11 @@ func (s *SetupFlowExecution) fetchTableSchemaAndSetupNormalizedTables( future = workflow.ExecuteActivity(ctx, flowable.CreateNormalizedTable, setupConfig) if err := future.Get(ctx, nil); err != nil { - s.logger.Error("failed to create normalized tables: ", err) + s.Error("failed to create normalized tables: ", err) return nil, fmt.Errorf("failed to create normalized tables: %w", err) } - s.logger.Info("finished setting up normalized tables for peer flow") + s.Info("finished setting up normalized tables for peer flow") return normalizedTableMapping, nil } @@ -227,7 +227,7 @@ func (s *SetupFlowExecution) executeSetupFlow( ctx workflow.Context, config *protos.FlowConnectionConfigs, ) (*protos.SetupFlowOutput, error) { - s.logger.Info("executing setup flow") + s.Info("executing setup flow") // first check the connectionsAndSetupMetadataTables if err := s.checkConnectionsAndSetupMetadataTables(ctx, config); err != nil { diff --git a/flow/workflows/snapshot_flow.go b/flow/workflows/snapshot_flow.go index 3c966b4f3f..43105695c3 100644 --- a/flow/workflows/snapshot_flow.go +++ b/flow/workflows/snapshot_flow.go @@ -21,7 +21,7 @@ import ( "github.com/PeerDB-io/peer-flow/shared" ) -type snapshotType int +type snapshotType int8 const ( SNAPSHOT_TYPE_UNKNOWN snapshotType = iota @@ -36,9 +36,9 @@ type SnapshotFlowExecution struct { } type cloneTablesInput struct { - snapshotType snapshotType slotName string snapshotName string + snapshotType snapshotType supportsTIDScans bool maxParallelClones int } From c628a2ccd445acd70bb93f15433adb0c5f40ce71 Mon Sep 17 00:00:00 2001 From: Amogh Bharadwaj Date: Wed, 27 Mar 2024 01:44:48 +0530 Subject: [PATCH 19/48] Peerdb stats: add source and dest table info for qrep run (#1540) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Populates two columns in `qrep_runs` table: source (watermark) table and destination table. These columns are not relevant currently but this is just useful info in general and we can show it in UI too in a follow up PR without having to decode the config Co-authored-by: Kaushik Iska Co-authored-by: Philip Dubé --- flow/connectors/utils/monitoring/monitoring.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flow/connectors/utils/monitoring/monitoring.go b/flow/connectors/utils/monitoring/monitoring.go index a402968544..2adf240430 100644 --- a/flow/connectors/utils/monitoring/monitoring.go +++ b/flow/connectors/utils/monitoring/monitoring.go @@ -152,8 +152,8 @@ func InitializeQRepRun( ) error { flowJobName := config.GetFlowJobName() _, err := pool.Exec(ctx, - "INSERT INTO peerdb_stats.qrep_runs(flow_name,run_uuid) VALUES($1,$2) ON CONFLICT DO NOTHING", - flowJobName, runUUID) + "INSERT INTO peerdb_stats.qrep_runs(flow_name,run_uuid,source_table,destination_table) VALUES($1,$2,$3,$4) ON CONFLICT DO NOTHING", + flowJobName, runUUID, config.WatermarkTable, config.DestinationTableIdentifier) if err != nil { return fmt.Errorf("error while inserting qrep run in qrep_runs: %w", err) } From 5d0592fd0ecf2a4d8c211a6407631791eae261a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Wed, 27 Mar 2024 14:12:24 +0000 Subject: [PATCH 20/48] Lua: msgpack v1.0.0, also add some constructors/comparisons (#1545) Constructors parsing string: peerdb.UUID, peerdb.Decimal __eq for uuid __eq/__le/__lt for time, decimal, bigint Remove __len & integer indexing from bigint Serialize decimals as strings in msgpack --- flow/go.mod | 2 +- flow/go.sum | 4 +- flow/pua/peerdb.go | 140 +++++++++++++++++++++++++++++++++------- flow/pua/peerdb_test.go | 11 ++-- 4 files changed, 126 insertions(+), 31 deletions(-) diff --git a/flow/go.mod b/flow/go.mod index 11533a667f..74b203d22c 100644 --- a/flow/go.mod +++ b/flow/go.mod @@ -15,7 +15,7 @@ require ( github.com/PeerDB-io/gluabit32 v1.0.2 github.com/PeerDB-io/gluaflatbuffers v1.0.1 github.com/PeerDB-io/gluajson v1.0.1 - github.com/PeerDB-io/gluamsgpack v0.0.0-20240326021100-65fbc328e820 + github.com/PeerDB-io/gluamsgpack v1.0.0 github.com/aws/aws-sdk-go-v2 v1.26.0 github.com/aws/aws-sdk-go-v2/config v1.27.9 github.com/aws/aws-sdk-go-v2/credentials v1.17.9 diff --git a/flow/go.sum b/flow/go.sum index 4ad96ce804..f46a7b3d61 100644 --- a/flow/go.sum +++ b/flow/go.sum @@ -66,8 +66,8 @@ github.com/PeerDB-io/gluaflatbuffers v1.0.1 h1:Oxlv0VlMYoQ05Q5n/k4hXAsvtDnuVNC99 github.com/PeerDB-io/gluaflatbuffers v1.0.1/go.mod h1:unZOM4Mm2Sn+aAFuVjoJDZ2Dji7jlDWrt4Hvq79as2g= github.com/PeerDB-io/gluajson v1.0.1 h1:MBrTCRD2FVQBCZ7ruK1fZZG6jdL+zAprGAoTWE074Ss= github.com/PeerDB-io/gluajson v1.0.1/go.mod h1:arRzpblxlLiWfBAluxP9Xibf6J8UkUIfoY4FPHTsz4Q= -github.com/PeerDB-io/gluamsgpack v0.0.0-20240326021100-65fbc328e820 h1:bBcFQrZ+fdASDz/8XGRs8vfCz0aKaHF3zSGAUPfWdno= -github.com/PeerDB-io/gluamsgpack v0.0.0-20240326021100-65fbc328e820/go.mod h1:8hJ3nYdOKLQNAoDubZL2tdu0sNEGN7BM7NWeuZlBNb0= +github.com/PeerDB-io/gluamsgpack v1.0.0 h1:bpO5Fxprl7rD7uYP/xm5xp8ABAwrYmnp0YgC7j1nseE= +github.com/PeerDB-io/gluamsgpack v1.0.0/go.mod h1:1ufs5NK2DczzQS78Nhy0AkCA0dOVyt/KVEk39lbWzyU= github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= diff --git a/flow/pua/peerdb.go b/flow/pua/peerdb.go index bbfd461d5f..14b073d9ac 100644 --- a/flow/pua/peerdb.go +++ b/flow/pua/peerdb.go @@ -26,7 +26,7 @@ var ( LuaTime = glua64.UserDataType[time.Time]{Name: "peerdb_time"} LuaUuid = glua64.UserDataType[uuid.UUID]{Name: "peerdb_uuid"} LuaBigInt = glua64.UserDataType[*big.Int]{Name: "peerdb_bigint"} - LuaDecimal = glua64.UserDataType[decimal.Decimal]{Name: "peerdb_bigrat"} + LuaDecimal = glua64.UserDataType[decimal.Decimal]{Name: "peerdb_decimal"} ) func RegisterTypes(ls *lua.LState) { @@ -53,26 +53,37 @@ func RegisterTypes(ls *lua.LState) { mt = LuaUuid.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaUuidIndex)) mt.RawSetString("__tostring", ls.NewFunction(LuaUuidString)) + mt.RawSetString("__eq", ls.NewFunction(LuaUuidEq)) mt.RawSetString("__msgpack", ls.NewFunction(LuaUuidMsgpack)) mt = LuaTime.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaTimeIndex)) mt.RawSetString("__tostring", ls.NewFunction(LuaTimeString)) + mt.RawSetString("__eq", ls.NewFunction(LuaTimeEq)) + mt.RawSetString("__le", ls.NewFunction(LuaTimeLe)) + mt.RawSetString("__lt", ls.NewFunction(LuaTimeLt)) mt = LuaBigInt.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaBigIntIndex)) mt.RawSetString("__tostring", ls.NewFunction(LuaBigIntString)) - mt.RawSetString("__len", ls.NewFunction(LuaBigIntLen)) + mt.RawSetString("__eq", ls.NewFunction(LuaBigIntEq)) + mt.RawSetString("__le", ls.NewFunction(LuaBigIntLe)) + mt.RawSetString("__lt", ls.NewFunction(LuaBigIntLt)) mt = LuaDecimal.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaDecimalIndex)) mt.RawSetString("__tostring", ls.NewFunction(LuaDecimalString)) + mt.RawSetString("__eq", ls.NewFunction(LuaDecimalEq)) + mt.RawSetString("__le", ls.NewFunction(LuaDecimalLe)) + mt.RawSetString("__lt", ls.NewFunction(LuaDecimalLt)) + mt.RawSetString("__msgpack", ls.NewFunction(LuaDecimalString)) peerdb := ls.NewTable() peerdb.RawSetString("RowColumns", ls.NewFunction(LuaRowColumns)) peerdb.RawSetString("RowColumnKind", ls.NewFunction(LuaRowColumnKind)) peerdb.RawSetString("Now", ls.NewFunction(LuaNow)) peerdb.RawSetString("UUID", ls.NewFunction(LuaUUID)) + peerdb.RawSetString("Decimal", ls.NewFunction(LuaParseDecimal)) peerdb.RawSetString("type", ls.NewFunction(LuaType)) peerdb.RawSetString("tostring", ls.NewFunction(LuaToString)) ls.Env.RawSetString("peerdb", peerdb) @@ -122,13 +133,13 @@ func LuaRowIndex(ls *lua.LState) int { } func LuaRowLen(ls *lua.LState) int { - _, row := LuaRow.Check(ls, 1) + row := LuaRow.StartMethod(ls) ls.Push(lua.LNumber(len(row.Values))) return 1 } func LuaRowColumns(ls *lua.LState) int { - _, row := LuaRow.Check(ls, 1) + row := LuaRow.StartMethod(ls) tbl := ls.CreateTable(len(row.ColToValIdx), 0) for col, idx := range row.ColToValIdx { tbl.RawSetInt(idx+1, lua.LString(col)) @@ -298,6 +309,13 @@ func LuaUuidString(ls *lua.LState) int { return 1 } +func LuaUuidEq(ls *lua.LState) int { + val1 := LuaUuid.StartMethod(ls) + _, val2 := LuaUuid.Check(ls, 2) + ls.Push(lua.LBool(val1 == val2)) + return 1 +} + func LuaUuidMsgpack(ls *lua.LState) int { val := LuaUuid.StartMethod(ls) ls.Push(&lua.LUserData{ @@ -314,7 +332,29 @@ func LuaNow(ls *lua.LState) int { } func LuaUUID(ls *lua.LState) int { - ls.Push(LuaUuid.New(ls, uuid.New())) + if ls.GetTop() == 0 { + ls.Push(LuaUuid.New(ls, uuid.New())) + } else if v, ok := ls.Get(1).(lua.LString); ok { + ls.Push(LuaUuid.New(ls, uuid.MustParse(string(v)))) + } else { + ls.RaiseError("uuid must be created from string") + } + return 1 +} + +func LuaParseDecimal(ls *lua.LState) int { + switch v := ls.Get(1).(type) { + case lua.LNumber: + ls.Push(LuaDecimal.New(ls, decimal.NewFromFloat(float64(v)))) + case lua.LString: + d, err := decimal.NewFromString(string(v)) + if err != nil { + ls.RaiseError(err.Error()) + } + ls.Push(LuaDecimal.New(ls, d)) + default: + ls.RaiseError("cannot create decimal from " + v.Type().String()) + } return 1 } @@ -377,24 +417,40 @@ func LuaTimeString(ls *lua.LState) int { return 1 } +func LuaTimeEq(ls *lua.LState) int { + t1 := LuaTime.StartMethod(ls) + _, t2 := LuaTime.Check(ls, 2) + ls.Push(lua.LBool(t1.Compare(t2) == 0)) + return 1 +} + +func LuaTimeLe(ls *lua.LState) int { + t1 := LuaTime.StartMethod(ls) + _, t2 := LuaTime.Check(ls, 2) + ls.Push(lua.LBool(t1.Compare(t2) <= 0)) + return 1 +} + +func LuaTimeLt(ls *lua.LState) int { + t1 := LuaTime.StartMethod(ls) + _, t2 := LuaTime.Check(ls, 2) + ls.Push(lua.LBool(t1.Compare(t2) == -1)) + return 1 +} + func LuaBigIntIndex(ls *lua.LState) int { - _, bi := LuaBigInt.Check(ls, 1) - switch key := ls.Get(2).(type) { - case lua.LNumber: - ls.Push(lua.LNumber(bi.Bytes()[int(key)])) - case lua.LString: - switch string(key) { - case "sign": - ls.Push(lua.LNumber(bi.Sign())) - case "bytes": - ls.Push(lua.LString(bi.Bytes())) - case "int64": - ls.Push(glua64.I64.New(ls, bi.Int64())) - case "is64": - ls.Push(lua.LBool(bi.IsInt64())) - } + bi, key := LuaBigInt.StartIndex(ls) + switch key { + case "sign": + ls.Push(lua.LNumber(bi.Sign())) + case "bytes": + ls.Push(lua.LString(bi.Bytes())) + case "int64": + ls.Push(glua64.I64.New(ls, bi.Int64())) + case "is64": + ls.Push(lua.LBool(bi.IsInt64())) default: - ls.RaiseError("BigInt accessed with non number/string") + return 0 } return 1 } @@ -405,9 +461,24 @@ func LuaBigIntString(ls *lua.LState) int { return 1 } -func LuaBigIntLen(ls *lua.LState) int { - bi := LuaBigInt.StartMethod(ls) - ls.Push(lua.LNumber(len(bi.Bytes()))) +func LuaBigIntEq(ls *lua.LState) int { + t1 := LuaBigInt.StartMethod(ls) + _, t2 := LuaBigInt.Check(ls, 2) + ls.Push(lua.LBool(t1.Cmp(t2) == 0)) + return 1 +} + +func LuaBigIntLe(ls *lua.LState) int { + t1 := LuaBigInt.StartMethod(ls) + _, t2 := LuaBigInt.Check(ls, 2) + ls.Push(lua.LBool(t1.Cmp(t2) <= 0)) + return 1 +} + +func LuaBigIntLt(ls *lua.LState) int { + t1 := LuaBigInt.StartMethod(ls) + _, t2 := LuaBigInt.Check(ls, 2) + ls.Push(lua.LBool(t1.Cmp(t2) == -1)) return 1 } @@ -437,3 +508,24 @@ func LuaDecimalString(ls *lua.LState) int { ls.Push(lua.LString(num.String())) return 1 } + +func LuaDecimalEq(ls *lua.LState) int { + t1 := LuaDecimal.StartMethod(ls) + _, t2 := LuaDecimal.Check(ls, 2) + ls.Push(lua.LBool(t1.Cmp(t2) == 0)) + return 1 +} + +func LuaDecimalLe(ls *lua.LState) int { + t1 := LuaDecimal.StartMethod(ls) + _, t2 := LuaDecimal.Check(ls, 2) + ls.Push(lua.LBool(t1.Cmp(t2) <= 0)) + return 1 +} + +func LuaDecimalLt(ls *lua.LState) int { + t1 := LuaDecimal.StartMethod(ls) + _, t2 := LuaDecimal.Check(ls, 2) + ls.Push(lua.LBool(t1.Cmp(t2) == -1)) + return 1 +} diff --git a/flow/pua/peerdb_test.go b/flow/pua/peerdb_test.go index 63cb7c6743..ee9a7b084b 100644 --- a/flow/pua/peerdb_test.go +++ b/flow/pua/peerdb_test.go @@ -3,7 +3,6 @@ package pua import ( "testing" - "github.com/google/uuid" "github.com/yuin/gopher-lua" "github.com/PeerDB-io/peer-flow/model" @@ -29,14 +28,12 @@ func Test(t *testing.T) { row.AddColumn("a", qvalue.QValueInt64{Val: 5040}) ls.Env.RawSetString("row", LuaRow.New(ls, row)) - id := uuid.UUID([16]byte{2, 3, 5, 7, 11, 13, 17, 19, 127, 131, 137, 139, 149, 151, 241, 251}) - ls.Env.RawSetString("uuid", LuaUuid.New(ls, id)) - assert(t, ls, ` assert(require('bit32').band(173, 21) == 5) assert(dofile == nil) assert(loadfile == nil) +local uuid = peerdb.UUID("02030507-0b0d-1113-7f83-898b9597f1fb") assert(uuid[0] == 2) assert(uuid[1] == 3) assert(uuid[2] == 5) @@ -54,6 +51,12 @@ assert(uuid[13] == 151) assert(uuid[14] == 241) assert(uuid[15] == 251) +local dec102 = peerdb.Decimal("10.2") +local dec101 = peerdb.Decimal("10.1") +assert(tostring(dec102) == "10.2") +assert(dec101 < dec102) + + local msgpack = require "msgpack" assert(msgpack.encode(uuid) == string.char(0xc4, 16, 2, 3, 5, 7, 11, 13, 17, 19, 127, 131, 137, 139, 149, 151, 241, 251)) From f31b7e6f16d718e7cf20db7d46c5c5a5853edc90 Mon Sep 17 00:00:00 2001 From: Amogh Bharadwaj Date: Wed, 27 Mar 2024 20:49:39 +0530 Subject: [PATCH 21/48] UI: Scripts console and some refactoring (#1547) - Scripts UI: Viewing scripts, creating scripts, deleting scrips and editing scripts - Move toast notification function to global utils - NewButton component shared for buttons like New Peer, New Mirror etc - Increase width of Create Peer form https://github.com/PeerDB-io/peerdb/assets/65964360/366afcaf-7f4d-4e5a-bfa1-c542b2a730b4 Closes #1505 --- ui/app/alert-config/new.tsx | 9 +- ui/app/api/mirrors/alerts/route.ts | 38 ---- ui/app/api/scripts/route.ts | 64 ++++++ ui/app/dto/ScriptsDTO.ts | 6 + ui/app/mirrors/[mirrorId]/edit/page.tsx | 10 +- ui/app/mirrors/create/handlers.ts | 26 ++- ui/app/mirrors/create/page.tsx | 20 +- ui/app/mirrors/create/qrep/query.tsx | 26 --- .../mirrors/errors/[mirrorName]/ackbutton.tsx | 8 +- ui/app/mirrors/page.tsx | 17 +- ui/app/peers/create/[peerType]/page.tsx | 23 +-- ui/app/peers/page.tsx | 16 +- ui/app/scripts/handlers.ts | 68 +++++++ ui/app/scripts/layout.tsx | 11 + ui/app/scripts/list.tsx | 112 ++++++++++ ui/app/scripts/new/page.tsx | 192 ++++++++++++++++++ ui/app/scripts/page.tsx | 66 ++++++ ui/app/utils/notify.tsx | 13 ++ ui/components/DropDialog.tsx | 76 ++++--- ui/components/NewButton.tsx | 29 +++ ui/components/PeerDBEditor.tsx | 28 +++ ui/components/PeerForms/KafkaConfig.tsx | 2 +- ui/components/PeerForms/PostgresForm.tsx | 2 +- ui/components/SidebarComponent.tsx | 9 +- ui/lib/AppTheme/appThemeColors.ts | 2 +- ui/lib/Button/Button.styles.ts | 2 +- ui/public/svgs/lua.svg | 27 +++ 27 files changed, 708 insertions(+), 194 deletions(-) delete mode 100644 ui/app/api/mirrors/alerts/route.ts create mode 100644 ui/app/api/scripts/route.ts create mode 100644 ui/app/dto/ScriptsDTO.ts delete mode 100644 ui/app/mirrors/create/qrep/query.tsx create mode 100644 ui/app/scripts/handlers.ts create mode 100644 ui/app/scripts/layout.tsx create mode 100644 ui/app/scripts/list.tsx create mode 100644 ui/app/scripts/new/page.tsx create mode 100644 ui/app/scripts/page.tsx create mode 100644 ui/app/utils/notify.tsx create mode 100644 ui/components/NewButton.tsx create mode 100644 ui/components/PeerDBEditor.tsx create mode 100644 ui/public/svgs/lua.svg diff --git a/ui/app/alert-config/new.tsx b/ui/app/alert-config/new.tsx index 12dfbc9cf5..7ea738af93 100644 --- a/ui/app/alert-config/new.tsx +++ b/ui/app/alert-config/new.tsx @@ -4,9 +4,10 @@ import Image from 'next/image'; import { Dispatch, SetStateAction, useState } from 'react'; import ReactSelect from 'react-select'; import { PulseLoader } from 'react-spinners'; -import { ToastContainer, toast } from 'react-toastify'; +import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import SelectTheme from '../styles/select'; +import { notifyErr } from '../utils/notify'; import { alertConfigReqSchema, alertConfigType, @@ -25,12 +26,6 @@ export interface AlertConfigProps { forEdit?: boolean; } -const notifyErr = (errMsg: string) => { - toast.error(errMsg, { - position: 'bottom-center', - }); -}; - function ConfigLabel(data: { label: string; value: string }) { return (
diff --git a/ui/app/api/mirrors/alerts/route.ts b/ui/app/api/mirrors/alerts/route.ts deleted file mode 100644 index 3596c4a294..0000000000 --- a/ui/app/api/mirrors/alerts/route.ts +++ /dev/null @@ -1,38 +0,0 @@ -import prisma from '@/app/utils/prisma'; - -export async function POST(request: Request) { - const { flowName } = await request.json(); - const errCount = await prisma.flow_errors.count({ - where: { - flow_name: flowName, - error_type: 'error', - ack: false, - }, - }); - let mirrorStatus: 'healthy' | 'failed'; - if (errCount > 0) { - mirrorStatus = 'failed'; - } else { - mirrorStatus = 'healthy'; - } - return new Response(JSON.stringify(mirrorStatus)); -} - -// We accept a list here in preparation for a Select All feature in UI -export async function PUT(request: Request) { - const { mirrorIDStringList } = await request.json(); - const mirrorIDList: bigint[] = mirrorIDStringList.map((id: string) => - BigInt(id) - ); - const success = await prisma.flow_errors.updateMany({ - where: { - id: { - in: mirrorIDList, - }, - }, - data: { - ack: true, - }, - }); - return new Response(JSON.stringify(success.count)); -} diff --git a/ui/app/api/scripts/route.ts b/ui/app/api/scripts/route.ts new file mode 100644 index 0000000000..640d930a75 --- /dev/null +++ b/ui/app/api/scripts/route.ts @@ -0,0 +1,64 @@ +import { ScriptsType } from '@/app/dto/ScriptsDTO'; +import prisma from '@/app/utils/prisma'; + +export async function POST(request: Request) { + const scriptReq: ScriptsType = await request.json(); + let createStatus: 'success' | string = 'error'; + try { + const createRes = await prisma.scripts.create({ + data: { + lang: scriptReq.lang, + name: scriptReq.name, + source: Buffer.from(scriptReq.source, 'utf-8'), + }, + }); + if (createRes.id) createStatus = 'success'; + } catch (err) { + createStatus = 'error'; + } + + return new Response(createStatus); +} + +export async function DELETE(request: Request) { + const scriptDeleteId = await request.json(); + let deleteStatus: 'success' | 'error' = 'error'; + try { + const deleteRes = await prisma.scripts.delete({ + where: { + id: scriptDeleteId, + }, + }); + if (deleteRes.id) { + deleteStatus = 'success'; + } + } catch (err) { + deleteStatus = 'error'; + } + + return new Response(deleteStatus); +} + +export async function PUT(request: Request) { + const scriptReq: ScriptsType = await request.json(); + let editStatus: 'success' | 'error' = 'error'; + try { + const editRes = await prisma.scripts.update({ + data: { + lang: scriptReq.lang, + name: scriptReq.name, + source: Buffer.from(scriptReq.source, 'utf-8'), + }, + where: { + id: scriptReq.id, + }, + }); + if (editRes.id) { + editStatus = 'success'; + } + } catch (err) { + editStatus = 'error'; + } + + return new Response(editStatus); +} diff --git a/ui/app/dto/ScriptsDTO.ts b/ui/app/dto/ScriptsDTO.ts new file mode 100644 index 0000000000..b863804cdb --- /dev/null +++ b/ui/app/dto/ScriptsDTO.ts @@ -0,0 +1,6 @@ +export type ScriptsType = { + id: number; + lang: 'lua'; + name: string; + source: string; +}; diff --git a/ui/app/mirrors/[mirrorId]/edit/page.tsx b/ui/app/mirrors/[mirrorId]/edit/page.tsx index 3b0240a0c6..9f65a72d8b 100644 --- a/ui/app/mirrors/[mirrorId]/edit/page.tsx +++ b/ui/app/mirrors/[mirrorId]/edit/page.tsx @@ -1,6 +1,7 @@ 'use client'; import { TableMapRow } from '@/app/dto/MirrorsDTO'; +import { notifyErr } from '@/app/utils/notify'; import { CDCFlowConfigUpdate, FlowStatus } from '@/grpc_generated/flow'; import { FlowStateChangeRequest, @@ -14,22 +15,17 @@ import { TextField } from '@/lib/TextField'; import { Callout } from '@tremor/react'; import { useRouter } from 'next/navigation'; import { useCallback, useEffect, useMemo, useState } from 'react'; -import { ToastContainer, toast } from 'react-toastify'; +import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import TableMapping from '../../create/cdc/tablemapping'; import { reformattedTableMapping } from '../../create/handlers'; import { blankCDCSetting } from '../../create/helpers/common'; import * as styles from '../../create/styles'; + type EditMirrorProps = { params: { mirrorId: string }; }; -const notifyErr = (errMsg: string) => { - toast.error(errMsg, { - position: 'bottom-center', - }); -}; - const EditMirror = ({ params: { mirrorId } }: EditMirrorProps) => { const defaultBatchSize = blankCDCSetting.maxBatchSize; const defaultIdleTimeout = blankCDCSetting.idleTimeoutSeconds; diff --git a/ui/app/mirrors/create/handlers.ts b/ui/app/mirrors/create/handlers.ts index 282fe70a34..c53731402d 100644 --- a/ui/app/mirrors/create/handlers.ts +++ b/ui/app/mirrors/create/handlers.ts @@ -6,6 +6,7 @@ import { UTablesAllResponse, UTablesResponse, } from '@/app/dto/PeersDTO'; +import { notifyErr } from '@/app/utils/notify'; import { FlowConnectionConfigs, QRepConfig, @@ -137,13 +138,12 @@ export const handleCreateCDC = async ( flowJobName: string, rows: TableMapRow[], config: CDCConfig, - notify: (msg: string, ok?: boolean) => void, setLoading: Dispatch>, route: RouteCallback ) => { const err = CDCCheck(flowJobName, rows, config); if (err != '') { - notify(err); + notifyErr(err); return; } @@ -155,11 +155,11 @@ export const handleCreateCDC = async ( }), }).then((res) => res.json()); if (!statusMessage.created) { - notify(statusMessage.message || 'Unable to create mirror.'); + notifyErr(statusMessage.message || 'Unable to create mirror.'); setLoading(false); return; } - notify('CDC Mirror created successfully', true); + notifyErr('CDC Mirror created successfully', true); route(); setLoading(false); }; @@ -177,7 +177,6 @@ export const handleCreateQRep = async ( flowJobName: string, query: string, config: QRepConfig, - notify: (msg: string) => void, setLoading: Dispatch>, route: RouteCallback, xmin?: boolean @@ -185,7 +184,7 @@ export const handleCreateQRep = async ( const flowNameValid = flowNameSchema.safeParse(flowJobName); if (!flowNameValid.success) { const flowNameErr = flowNameValid.error.issues[0].message; - notify(flowNameErr); + notifyErr(flowNameErr); return; } @@ -203,12 +202,12 @@ export const handleCreateQRep = async ( (!config.writeMode?.upsertKeyColumns || config.writeMode?.upsertKeyColumns.length == 0) ) { - notify('For upsert mode, unique key columns cannot be empty.'); + notifyErr('For upsert mode, unique key columns cannot be empty.'); return; } const fieldErr = validateQRepFields(query, config); if (fieldErr) { - notify(fieldErr); + notifyErr(fieldErr); return; } config.flowJobName = flowJobName; @@ -225,11 +224,11 @@ export const handleCreateQRep = async ( } ).then((res) => res.json()); if (!statusMessage.created) { - notify('unable to create mirror.'); + notifyErr('unable to create mirror.'); setLoading(false); return; } - notify('Query Replication Mirror created successfully'); + notifyErr('Query Replication Mirror created successfully'); route(); setLoading(false); }; @@ -343,13 +342,12 @@ export const handleValidateCDC = async ( flowJobName: string, rows: TableMapRow[], config: CDCConfig, - notify: (msg: string, ok?: boolean) => void, setLoading: Dispatch> ) => { setLoading(true); const err = CDCCheck(flowJobName, rows, config); if (err != '') { - notify(err); + notifyErr(err); setLoading(false); return; } @@ -362,11 +360,11 @@ export const handleValidateCDC = async ( .then((res) => res.json()) .catch((e) => console.log(e)); if (!status.ok) { - notify(status.message || 'Mirror is invalid'); + notifyErr(status.message || 'Mirror is invalid'); setLoading(false); return; } - notify('CDC Mirror is valid', true); + notifyErr('CDC Mirror is valid', true); setLoading(false); }; diff --git a/ui/app/mirrors/create/page.tsx b/ui/app/mirrors/create/page.tsx index 4d79fea628..c19bc3b995 100644 --- a/ui/app/mirrors/create/page.tsx +++ b/ui/app/mirrors/create/page.tsx @@ -16,9 +16,10 @@ import Image from 'next/image'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import ReactSelect from 'react-select'; -import { ToastContainer, toast } from 'react-toastify'; +import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import { InfoPopover } from '../../../components/InfoPopover'; +import PeerDBCodeEditor from '../../../components/PeerDBEditor'; import { CDCConfig, TableMapRow } from '../../dto/MirrorsDTO'; import CDCConfigForm from './cdc/cdc'; import { @@ -32,7 +33,6 @@ import { blankCDCSetting } from './helpers/common'; import { qrepSettings } from './helpers/qrep'; import MirrorCards from './mirrorcards'; import QRepConfigForm from './qrep/qrep'; -import QRepQuery from './qrep/query'; import * as styles from './styles'; function getPeerValue(peer: Peer) { @@ -56,17 +56,6 @@ function getPeerLabel(peer: Peer) { ); } -const notifyErr = (msg: string, ok?: boolean) => { - if (ok) { - toast.success(msg, { - position: 'bottom-center', - }); - } else { - toast.error(msg, { - position: 'bottom-center', - }); - } -}; export default function CreateMirrors() { const router = useRouter(); const [mirrorName, setMirrorName] = useState(''); @@ -199,7 +188,7 @@ export default function CreateMirrors() { {mirrorType === 'Query Replication' && ( - + )} {mirrorType && ( @@ -244,7 +233,6 @@ export default function CreateMirrors() { mirrorName, rows, config as CDCConfig, - notifyErr, setValidating ) } @@ -268,7 +256,6 @@ export default function CreateMirrors() { mirrorName, rows, config as CDCConfig, - notifyErr, setCreating, listMirrorsPage ) @@ -276,7 +263,6 @@ export default function CreateMirrors() { mirrorName, qrepQuery, config as QRepConfig, - notifyErr, setCreating, listMirrorsPage, mirrorType === 'XMIN' // for handling xmin specific diff --git a/ui/app/mirrors/create/qrep/query.tsx b/ui/app/mirrors/create/qrep/query.tsx deleted file mode 100644 index 64d0f893ac..0000000000 --- a/ui/app/mirrors/create/qrep/query.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import Editor from '@monaco-editor/react'; -import { Dispatch, SetStateAction } from 'react'; -const options = { - readOnly: false, - minimap: { enabled: false }, - fontSize: 14, -}; - -interface QueryProps { - setter: Dispatch>; - query: string; -} -const QRepQuery = (props: QueryProps) => { - return ( - props.setter(value as string)} - /> - ); -}; - -export default QRepQuery; diff --git a/ui/app/mirrors/errors/[mirrorName]/ackbutton.tsx b/ui/app/mirrors/errors/[mirrorName]/ackbutton.tsx index c6b23a6e72..88c2f9e12a 100644 --- a/ui/app/mirrors/errors/[mirrorName]/ackbutton.tsx +++ b/ui/app/mirrors/errors/[mirrorName]/ackbutton.tsx @@ -1,15 +1,9 @@ 'use client'; +import { notifyErr } from '@/app/utils/notify'; import { Button } from '@/lib/Button'; import { Label } from '@/lib/Label'; import { ProgressCircle } from '@/lib/ProgressCircle'; import { useState } from 'react'; -import { toast } from 'react-toastify'; - -const notifyErr = (errMsg: string) => { - toast.error(errMsg, { - position: 'bottom-center', - }); -}; const AckButton = ({ ack, id }: { ack: boolean; id: number | bigint }) => { const [loading, setLoading] = useState(false); diff --git a/ui/app/mirrors/page.tsx b/ui/app/mirrors/page.tsx index 0a8c51f6c1..f22b522d19 100644 --- a/ui/app/mirrors/page.tsx +++ b/ui/app/mirrors/page.tsx @@ -1,14 +1,11 @@ 'use client'; +import NewButton from '@/components/NewButton'; import { QRepConfig } from '@/grpc_generated/flow'; -import { Button } from '@/lib/Button'; import { Header } from '@/lib/Header'; -import { Icon } from '@/lib/Icon'; -import { Label } from '@/lib/Label'; import { LayoutMain } from '@/lib/Layout'; import { Panel } from '@/lib/Panel'; import { ProgressCircle } from '@/lib/ProgressCircle'; -import Link from 'next/link'; import useSWR from 'swr'; import { fetcher } from '../utils/swr'; import { CDCFlows, QRepFlows } from './tables'; @@ -50,17 +47,7 @@ export default function Mirrors() {
-
- -
- + } > Mirrors diff --git a/ui/app/peers/create/[peerType]/page.tsx b/ui/app/peers/create/[peerType]/page.tsx index ffb4495db4..7f8b5cbf9c 100644 --- a/ui/app/peers/create/[peerType]/page.tsx +++ b/ui/app/peers/create/[peerType]/page.tsx @@ -9,6 +9,7 @@ import PubSubForm from '@/components/PeerForms/PubSubConfig'; import S3Form from '@/components/PeerForms/S3Form'; import SnowflakeForm from '@/components/PeerForms/SnowflakeForm'; +import { notifyErr } from '@/app/utils/notify'; import TitleCase from '@/app/utils/titlecase'; import { Button } from '@/lib/Button'; import { ButtonGroup } from '@/lib/ButtonGroup'; @@ -20,7 +21,7 @@ import { Tooltip } from '@/lib/Tooltip'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; -import { ToastContainer, toast } from 'react-toastify'; +import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import { handleCreate, handleValidate } from './handlers'; import { clickhouseSetting } from './helpers/ch'; @@ -32,19 +33,6 @@ type CreateConfigProps = { params: { peerType: string }; }; -const notify = (msg: string, success?: boolean) => { - if (success) { - toast.success(msg, { - position: 'bottom-center', - autoClose: 1000, - }); - } else { - toast.error(msg, { - position: 'bottom-center', - }); - } -}; - export default function CreateConfig({ params: { peerType }, }: CreateConfigProps) { @@ -143,7 +131,8 @@ export default function CreateConfig({ - {configComponentMap(peerType)} + +
{configComponentMap(peerType)}
- } + slot={} > Peers
diff --git a/ui/app/scripts/handlers.ts b/ui/app/scripts/handlers.ts new file mode 100644 index 0000000000..fb501bac2f --- /dev/null +++ b/ui/app/scripts/handlers.ts @@ -0,0 +1,68 @@ +import { ScriptsType } from '../dto/ScriptsDTO'; +import { notifyErr } from '../utils/notify'; + +export const AddScript = async (script: ScriptsType) => { + try { + const addScriptRes = await fetch('/api/scripts', { + method: 'POST', + body: JSON.stringify(script), + }); + const addScriptStatus = await addScriptRes.text(); + if (addScriptStatus === 'error') { + notifyErr( + 'Something went wrong when adding the script. Please try again' + ); + return false; + } + } catch (err) { + notifyErr('Something went wrong when adding the script. Please try again'); + return false; + } + + notifyErr('Successfully added script', true); + return true; +}; + +export const HandleEditScript = async (script: ScriptsType) => { + try { + const editScriptRes = await fetch('/api/scripts', { + method: 'PUT', + body: JSON.stringify(script), + }); + const addScriptStatus = await editScriptRes.text(); + if (addScriptStatus === 'error') { + notifyErr( + 'Something went wrong when editing the script. Please try again' + ); + return false; + } + } catch (err) { + notifyErr('Something went wrong when editing the script. Please try again'); + return false; + } + notifyErr('Successfully edited script', true); + return true; +}; + +export const DeleteScript = async (scriptId: number) => { + try { + const deleteScriptRes = await fetch('/api/scripts', { + method: 'DELETE', + body: JSON.stringify(scriptId), + }); + const addScriptStatus = await deleteScriptRes.text(); + if (addScriptStatus === 'error') { + notifyErr( + 'Something went wrong when deleting the script. Please try again' + ); + return false; + } + } catch (err) { + notifyErr( + 'Something went wrong when deleting the script. Please try again' + ); + return false; + } + notifyErr('Successfully deleted script', true); + return true; +}; diff --git a/ui/app/scripts/layout.tsx b/ui/app/scripts/layout.tsx new file mode 100644 index 0000000000..3968fee83d --- /dev/null +++ b/ui/app/scripts/layout.tsx @@ -0,0 +1,11 @@ +import SidebarComponent from '@/components/SidebarComponent'; +import { Layout } from '@/lib/Layout'; +import { PropsWithChildren, Suspense } from 'react'; + +export default function PageLayout({ children }: PropsWithChildren) { + return ( + }> + {children} + + ); +} diff --git a/ui/app/scripts/list.tsx b/ui/app/scripts/list.tsx new file mode 100644 index 0000000000..68c5bbd98c --- /dev/null +++ b/ui/app/scripts/list.tsx @@ -0,0 +1,112 @@ +'use client'; +import { DropDialog } from '@/components/DropDialog'; +import { Button } from '@/lib/Button/Button'; +import { Label } from '@/lib/Label/Label'; +import { SearchField } from '@/lib/SearchField'; +import { TableCell } from '@/lib/Table'; +import { Table } from '@/lib/Table/Table'; +import { TableRow } from '@tremor/react'; +import Image from 'next/image'; +import Link from 'next/link'; +import { useRouter } from 'next/navigation'; +import { useEffect, useMemo, useState } from 'react'; +import { ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; +import { ScriptsType } from '../dto/ScriptsDTO'; + +const LanguageIcon = (language: string) => { + switch (language.toLowerCase()) { + case 'lua': + return '/svgs/lua.svg'; + default: + return '/svgs/lua.svg'; + } +}; + +const ScriptsTable = ({ scripts }: { scripts: ScriptsType[] }) => { + const router = useRouter(); + const [searchQuery, setSearchQuery] = useState(''); + const displayedScripts = useMemo(() => { + return scripts.filter((script) => script.name.includes(searchQuery)); + }, [scripts, searchQuery]); + + // This is a hack to ensure this table + // shows updated data when landing from /scripts/new + // after adding a script + // router.push/replace does not seem to invalidate cache for /scripts + // https://github.com/vercel/next.js/discussions/54075 + useEffect(() => { + router.refresh(); + }, [router]); + return ( + <> + ) => + setSearchQuery(e.target.value) + } + /> + ), + }} + header={ + + {['Name', 'Language'].map((heading) => { + return ( + + {heading} + + ); + })} + + } + > + {displayedScripts.map((script) => { + return ( + + {script.name} + +
+ + +
+
+ + + + + + +
+ ); + })} +
+ + + ); +}; + +export default ScriptsTable; diff --git a/ui/app/scripts/new/page.tsx b/ui/app/scripts/new/page.tsx new file mode 100644 index 0000000000..9553e8eb3f --- /dev/null +++ b/ui/app/scripts/new/page.tsx @@ -0,0 +1,192 @@ +'use client'; +import { ScriptsType } from '@/app/dto/ScriptsDTO'; +import { notifyErr } from '@/app/utils/notify'; +import PeerDBCodeEditor from '@/components/PeerDBEditor'; +import { Button } from '@/lib/Button'; +import { Icon } from '@/lib/Icon'; +import { Label } from '@/lib/Label/Label'; +import { ProgressCircle } from '@/lib/ProgressCircle'; +import { TextField } from '@/lib/TextField'; +import Link from 'next/link'; +import { useRouter, useSearchParams } from 'next/navigation'; +import { useState } from 'react'; +import { ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; +import { AddScript, HandleEditScript } from '../handlers'; + +const EditScript = () => { + const params = useSearchParams(); + const router = useRouter(); + const scriptStringBase64 = params.get('script'); + let script: ScriptsType = { + id: 1, + name: '', + lang: 'lua', + source: ` +-- This is a sample script +-- Fill in the onRecord function to transform the incoming record +local json = require "json" + +function onRecord(r) + return json.encode(r.row) +end + `, + }; + let inEditMode: boolean = false; + if (scriptStringBase64) { + const scriptString = Buffer.from(scriptStringBase64, 'base64').toString( + 'utf-8' + ); + script = JSON.parse(scriptString); + inEditMode = true; + } + + const [newScript, setNewScript] = useState(script); + const [loading, setLoading] = useState(false); + const handleAdd = (script?: ScriptsType) => { + if (!script || !script.source) { + notifyErr('Empty scripts not allowed'); + return; + } + if (!script?.name) { + notifyErr('Please enter a script name'); + return; + } + setLoading(true); + AddScript(script).then((success) => { + setLoading(false); + if (success) { + router.replace('/scripts'); + } + }); + }; + + const handleEdit = (script?: ScriptsType) => { + if (!script || !script.source) { + notifyErr('Empty scripts not allowed'); + return; + } + if (!script?.name) { + notifyErr('Please enter a script name'); + return; + } + setLoading(true); + HandleEditScript(script).then((success) => { + setLoading(false); + if (success) { + router.replace('/scripts'); + } + }); + }; + + return ( +
+ + + +
+
+ + + +
+
+ + + setNewScript((prev) => ({ ...prev, name: e.target.value })) + } + variant='simple' + defaultValue={newScript?.name} + style={{ height: '2rem', width: '30%' }} + /> +
+ +
+ + + setNewScript((prev) => ({ ...prev, source: newQuery })) + } + code={newScript?.source} + height={'30vh'} + language='lua' + /> +
+
+ + +
+ ); +}; + +export default EditScript; diff --git a/ui/app/scripts/page.tsx b/ui/app/scripts/page.tsx new file mode 100644 index 0000000000..dc828fa908 --- /dev/null +++ b/ui/app/scripts/page.tsx @@ -0,0 +1,66 @@ +import NewButton from '@/components/NewButton'; +import { Label } from '@/lib/Label/Label'; +import Link from 'next/link'; +import { ScriptsType } from '../dto/ScriptsDTO'; +import prisma from '../utils/prisma'; +import ScriptsTable from './list'; +export const dynamic = 'force-dynamic'; +export const revalidate = 5; + +const ScriptsPage = async () => { + const existingScripts = await prisma.scripts.findMany(); + const scripts: ScriptsType[] = existingScripts.map((script) => ({ + ...script, + source: script.source.toString(), + })); + return ( +
+
+
+ + +
+
+
+ + + +
+ +
+ ); +}; + +export default ScriptsPage; diff --git a/ui/app/utils/notify.tsx b/ui/app/utils/notify.tsx new file mode 100644 index 0000000000..7306a24609 --- /dev/null +++ b/ui/app/utils/notify.tsx @@ -0,0 +1,13 @@ +import { toast } from 'react-toastify'; + +export const notifyErr = (msg: string, ok?: boolean) => { + if (ok) { + toast.success(msg, { + position: 'bottom-center', + }); + } else { + toast.error(msg, { + position: 'bottom-center', + }); + } +}; diff --git a/ui/components/DropDialog.tsx b/ui/components/DropDialog.tsx index 63acb3ef2b..14680900e3 100644 --- a/ui/components/DropDialog.tsx +++ b/ui/components/DropDialog.tsx @@ -1,6 +1,7 @@ 'use client'; import { UDropMirrorResponse } from '@/app/dto/MirrorsDTO'; import { UDropPeerResponse } from '@/app/dto/PeersDTO'; +import { DeleteScript } from '@/app/scripts/handlers'; import { Peer } from '@/grpc_generated/peers'; import { Button } from '@/lib/Button'; import { Dialog, DialogClose } from '@/lib/Dialog'; @@ -26,6 +27,10 @@ interface deleteAlertArgs { id: number | bigint; } +interface deleteScriptArgs { + scriptId: number; +} + export const handleDropMirror = async ( dropArgs: dropMirrorArgs, setLoading: Dispatch>, @@ -62,8 +67,8 @@ export const DropDialog = ({ mode, dropArgs, }: { - mode: 'PEER' | 'MIRROR' | 'ALERT'; - dropArgs: dropMirrorArgs | dropPeerArgs | deleteAlertArgs; + mode: 'PEER' | 'MIRROR' | 'ALERT' | 'SCRIPT'; + dropArgs: dropMirrorArgs | dropPeerArgs | deleteAlertArgs | deleteScriptArgs; }) => { const [loading, setLoading] = useState(false); const [msg, setMsg] = useState(''); @@ -108,6 +113,45 @@ export const DropDialog = ({ } }; + const handleDeleteScript = (dropArgs: deleteScriptArgs) => { + setLoading(true); + DeleteScript(dropArgs.scriptId).then((success) => { + setLoading(false); + if (success) window.location.reload(); + }); + }; + + const getDeleteText = () => { + let deletePart = 'Are you sure you want to delete '; + let objectSpecificDeleteText = ''; + switch (mode) { + case 'MIRROR': + objectSpecificDeleteText = `mirror ${(dropArgs as dropMirrorArgs).flowJobName}`; + case 'PEER': + objectSpecificDeleteText = `peer ${(dropArgs as dropPeerArgs).peerName}`; + case 'ALERT': + objectSpecificDeleteText = 'this alert'; + case 'SCRIPT': + objectSpecificDeleteText = 'this script'; + } + return ( + deletePart + objectSpecificDeleteText + '? This action cannot be reverted' + ); + }; + + const handleDelete = () => { + switch (mode) { + case 'MIRROR': + handleDropMirror(dropArgs as dropMirrorArgs, setLoading, setMsg); + case 'PEER': + handleDropPeer(dropArgs as dropPeerArgs); + case 'ALERT': + handleDeleteAlert(dropArgs as deleteAlertArgs); + case 'SCRIPT': + handleDeleteScript(dropArgs as deleteScriptArgs); + } + }; + return (
@@ -151,17 +183,7 @@ export const DropDialog = ({ + ); +}; + +export default NewButton; diff --git a/ui/components/PeerDBEditor.tsx b/ui/components/PeerDBEditor.tsx new file mode 100644 index 0000000000..94d2cfc52a --- /dev/null +++ b/ui/components/PeerDBEditor.tsx @@ -0,0 +1,28 @@ +import Editor from '@monaco-editor/react'; + +const defaultOptions = { + readOnly: false, + minimap: { enabled: false }, + fontSize: 14, +}; + +interface CodeEditorProps { + setter: (value: string) => void; + code?: string; + language?: string; + height?: string; + options?: Object; +} +const PeerDBCodeEditor = (props: CodeEditorProps) => { + return ( + props.setter(value as string)} + /> + ); +}; + +export default PeerDBCodeEditor; diff --git a/ui/components/PeerForms/KafkaConfig.tsx b/ui/components/PeerForms/KafkaConfig.tsx index 65df972ba5..752ad7470c 100644 --- a/ui/components/PeerForms/KafkaConfig.tsx +++ b/ui/components/PeerForms/KafkaConfig.tsx @@ -15,7 +15,7 @@ interface KafkaProps { const KafkaForm = ({ setter }: KafkaProps) => { return ( -
+
{kaSetting.map((setting, index) => { return setting.type === 'switch' ? ( diff --git a/ui/components/SidebarComponent.tsx b/ui/components/SidebarComponent.tsx index 750648ef51..3985c7dcaa 100644 --- a/ui/components/SidebarComponent.tsx +++ b/ui/components/SidebarComponent.tsx @@ -141,7 +141,14 @@ export default function SidebarComponent() { href={'/alert-config'} leadingIcon={} > - {sidebarState === 'open' && 'Alert Configuration'} + {sidebarState === 'open' && 'Alerts'} + + } + > + {sidebarState === 'open' && 'Scripts'} diff --git a/ui/lib/AppTheme/appThemeColors.ts b/ui/lib/AppTheme/appThemeColors.ts index 17c4ccf7d1..7b850f40c2 100644 --- a/ui/lib/AppTheme/appThemeColors.ts +++ b/ui/lib/AppTheme/appThemeColors.ts @@ -54,7 +54,7 @@ export const appThemeColors = { }, surface: { normal: '#FFF0EE', - hovered: '#FFE6E2', + hovered: '#f79383', selected: '#FDD8D3', }, border: { diff --git a/ui/lib/Button/Button.styles.ts b/ui/lib/Button/Button.styles.ts index d74e612afb..7bbc6671f6 100644 --- a/ui/lib/Button/Button.styles.ts +++ b/ui/lib/Button/Button.styles.ts @@ -58,7 +58,7 @@ const dropStyle = css` --focus-border-color: ${({ theme }) => theme.colors.accent.border.normal}; --text-color: ${({ theme }) => theme.colors.base.text.highContrast}; --background-color-default: ${({ theme, $loading }) => - $loading ? theme.colors.base.surface.selected : 'transparent'}; + $loading ? theme.colors.base.surface.selected : '#FFE6E2'}; --background-color-hover: ${({ theme }) => theme.colors.destructive.surface.hovered}; --background-color-focus: transparent; diff --git a/ui/public/svgs/lua.svg b/ui/public/svgs/lua.svg new file mode 100644 index 0000000000..6788797549 --- /dev/null +++ b/ui/public/svgs/lua.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + From 6d98796e10cbcb379da56d0e484ed05b1f329f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Wed, 27 Mar 2024 16:17:38 +0000 Subject: [PATCH 22/48] cdc records storage: replace runtime.MemStats with runtime/metrics (#1546) runtime.MemStats has 2 flaws: 1. it's 5kb 2. ReadMemStats calls stopTheWorld --- flow/connectors/utils/cdc_records/cdc_records_storage.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/flow/connectors/utils/cdc_records/cdc_records_storage.go b/flow/connectors/utils/cdc_records/cdc_records_storage.go index 2b6dbce8b9..0608aa14fd 100644 --- a/flow/connectors/utils/cdc_records/cdc_records_storage.go +++ b/flow/connectors/utils/cdc_records/cdc_records_storage.go @@ -7,7 +7,7 @@ import ( "fmt" "log/slog" "os" - "runtime" + "runtime/metrics" "sync/atomic" "time" @@ -37,10 +37,10 @@ type cdcRecordsStore struct { flowJobName string dbFolderName string thresholdReason string + memStats []metrics.Sample memThresholdBytes uint64 numRecords atomic.Int32 numRecordsSwitchThreshold int - memStats runtime.MemStats } func NewCDCRecordsStore(flowJobName string) *cdcRecordsStore { @@ -60,6 +60,7 @@ func NewCDCRecordsStore(flowJobName string) *cdcRecordsStore { return 0 }(), thresholdReason: "", + memStats: []metrics.Sample{{Name: "/gc/heap/allocs:bytes"}}, } } @@ -134,9 +135,9 @@ func (c *cdcRecordsStore) diskSpillThresholdsExceeded() bool { return true } if c.memThresholdBytes > 0 { - runtime.ReadMemStats(&c.memStats) + metrics.Read(c.memStats) - if c.memStats.Alloc >= c.memThresholdBytes { + if c.memStats[0].Value.Uint64() >= c.memThresholdBytes { c.thresholdReason = fmt.Sprintf("memalloc greater than %d bytes, spilling to disk", c.memThresholdBytes) return true From 857bc5dbf01a3172f916da50f95bddbe8e4d3bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Wed, 27 Mar 2024 20:17:10 +0000 Subject: [PATCH 23/48] lua: utf8 (#1548) https://github.com/PeerDB-io/gluautf8 --- flow/go.mod | 1 + flow/go.sum | 2 ++ flow/pua/peerdb.go | 2 ++ 3 files changed, 5 insertions(+) diff --git a/flow/go.mod b/flow/go.mod index 74b203d22c..2c1c8cd7c5 100644 --- a/flow/go.mod +++ b/flow/go.mod @@ -16,6 +16,7 @@ require ( github.com/PeerDB-io/gluaflatbuffers v1.0.1 github.com/PeerDB-io/gluajson v1.0.1 github.com/PeerDB-io/gluamsgpack v1.0.0 + github.com/PeerDB-io/gluautf8 v1.0.0 github.com/aws/aws-sdk-go-v2 v1.26.0 github.com/aws/aws-sdk-go-v2/config v1.27.9 github.com/aws/aws-sdk-go-v2/credentials v1.17.9 diff --git a/flow/go.sum b/flow/go.sum index f46a7b3d61..307c581dcd 100644 --- a/flow/go.sum +++ b/flow/go.sum @@ -68,6 +68,8 @@ github.com/PeerDB-io/gluajson v1.0.1 h1:MBrTCRD2FVQBCZ7ruK1fZZG6jdL+zAprGAoTWE07 github.com/PeerDB-io/gluajson v1.0.1/go.mod h1:arRzpblxlLiWfBAluxP9Xibf6J8UkUIfoY4FPHTsz4Q= github.com/PeerDB-io/gluamsgpack v1.0.0 h1:bpO5Fxprl7rD7uYP/xm5xp8ABAwrYmnp0YgC7j1nseE= github.com/PeerDB-io/gluamsgpack v1.0.0/go.mod h1:1ufs5NK2DczzQS78Nhy0AkCA0dOVyt/KVEk39lbWzyU= +github.com/PeerDB-io/gluautf8 v1.0.0 h1:Ubhy6FVnrED5jrosdUOxzAkf3YdcgebYJzX2YBdGedE= +github.com/PeerDB-io/gluautf8 v1.0.0/go.mod h1:+4RQlCVFCMikYFmiKUA9ADZftgGAZseMmdErxfE1EZQ= github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= diff --git a/flow/pua/peerdb.go b/flow/pua/peerdb.go index 14b073d9ac..2f54a5f772 100644 --- a/flow/pua/peerdb.go +++ b/flow/pua/peerdb.go @@ -15,6 +15,7 @@ import ( "github.com/PeerDB-io/gluabit32" "github.com/PeerDB-io/gluajson" "github.com/PeerDB-io/gluamsgpack" + "github.com/PeerDB-io/gluautf8" "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/peerdbenv" @@ -42,6 +43,7 @@ func RegisterTypes(ls *lua.LState) { ls.PreloadModule("bit32", gluabit32.Loader) ls.PreloadModule("json", gluajson.Loader) ls.PreloadModule("msgpack", gluamsgpack.Loader) + ls.PreloadModule("utf8", gluautf8.Loader) mt := LuaRecord.NewMetatable(ls) mt.RawSetString("__index", ls.NewFunction(LuaRecordIndex)) From 00ac0c21199c0e693fcd785b97789d56b6de298c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Wed, 27 Mar 2024 22:06:25 +0000 Subject: [PATCH 24/48] Close replication connection faster (#1549) Kevin noticed MaintainPull was outliving parent workflow for some time, temporal contexts only detect cancelation with RecordHeartbeat, in order to reduce shutdown latency implement UnmaintainPull --- flow/activities/flowable.go | 29 +++++++++++++++++++++++++---- flow/cmd/worker.go | 3 +-- flow/workflows/sync_flow.go | 22 +++++++++++++++++++++- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/flow/activities/flowable.go b/flow/activities/flowable.go index d501309294..16d290d0e8 100644 --- a/flow/activities/flowable.go +++ b/flow/activities/flowable.go @@ -35,10 +35,15 @@ type CheckConnectionResult struct { NeedsSetupMetadataTables bool } +type CdcCacheEntry struct { + connector connectors.CDCPullConnector + done chan struct{} +} + type FlowableActivity struct { CatalogPool *pgxpool.Pool Alerter *alerting.Alerter - CdcCache map[string]connectors.CDCPullConnector + CdcCache map[string]CdcCacheEntry CdcCacheRw sync.RWMutex } @@ -217,8 +222,12 @@ func (a *FlowableActivity) MaintainPull( return err } + done := make(chan struct{}) a.CdcCacheRw.Lock() - a.CdcCache[sessionID] = srcConn + a.CdcCache[sessionID] = CdcCacheEntry{ + connector: srcConn, + done: done, + } a.CdcCacheRw.Unlock() ticker := time.NewTicker(15 * time.Second) @@ -234,6 +243,8 @@ func (a *FlowableActivity) MaintainPull( a.CdcCacheRw.Unlock() return temporal.NewNonRetryableApplicationError("connection to source down", "disconnect", err) } + case <-done: + return nil case <-ctx.Done(): a.CdcCacheRw.Lock() delete(a.CdcCache, sessionID) @@ -243,15 +254,25 @@ func (a *FlowableActivity) MaintainPull( } } +func (a *FlowableActivity) UnmaintainPull(ctx context.Context, sessionID string) error { + a.CdcCacheRw.Lock() + if entry, ok := a.CdcCache[sessionID]; ok { + close(entry.done) + delete(a.CdcCache, sessionID) + } + a.CdcCacheRw.Unlock() + return nil +} + func (a *FlowableActivity) waitForCdcCache(ctx context.Context, sessionID string) (connectors.CDCPullConnector, error) { logger := activity.GetLogger(ctx) attempt := 0 for { a.CdcCacheRw.RLock() - conn, ok := a.CdcCache[sessionID] + entry, ok := a.CdcCache[sessionID] a.CdcCacheRw.RUnlock() if ok { - return conn, nil + return entry.connector, nil } activity.RecordHeartbeat(ctx, "wait another second for source connector") attempt += 1 diff --git a/flow/cmd/worker.go b/flow/cmd/worker.go index b825a18d7b..654cfad163 100644 --- a/flow/cmd/worker.go +++ b/flow/cmd/worker.go @@ -15,7 +15,6 @@ import ( "github.com/PeerDB-io/peer-flow/activities" "github.com/PeerDB-io/peer-flow/alerting" - "github.com/PeerDB-io/peer-flow/connectors" "github.com/PeerDB-io/peer-flow/logger" "github.com/PeerDB-io/peer-flow/peerdbenv" "github.com/PeerDB-io/peer-flow/shared" @@ -132,7 +131,7 @@ func WorkerMain(opts *WorkerOptions) (client.Client, worker.Worker, error) { w.RegisterActivity(&activities.FlowableActivity{ CatalogPool: conn, Alerter: alerting.NewAlerter(context.Background(), conn), - CdcCache: make(map[string]connectors.CDCPullConnector), + CdcCache: make(map[string]activities.CdcCacheEntry), }) return c, w, nil diff --git a/flow/workflows/sync_flow.go b/flow/workflows/sync_flow.go index 890da2e0fa..61fc94753d 100644 --- a/flow/workflows/sync_flow.go +++ b/flow/workflows/sync_flow.go @@ -5,6 +5,7 @@ import ( "time" "go.temporal.io/sdk/log" + "go.temporal.io/sdk/temporal" "go.temporal.io/sdk/workflow" "golang.org/x/exp/maps" @@ -212,10 +213,29 @@ func SyncFlowWorkflow( break } } + if err := ctx.Err(); err != nil { logger.Info("sync canceled", slog.Any("error", err)) return err - } else if stop { + } + + if fMaintain != nil { + unmaintainCtx := workflow.WithActivityOptions(syncSessionCtx, workflow.ActivityOptions{ + RetryPolicy: &temporal.RetryPolicy{MaximumAttempts: 1}, + StartToCloseTimeout: time.Minute, + HeartbeatTimeout: time.Minute, + WaitForCancellation: true, + }) + if err := workflow.ExecuteActivity( + unmaintainCtx, + flowable.UnmaintainPull, + sessionID, + ).Get(unmaintainCtx, nil); err != nil { + logger.Warn("UnmaintainPull failed", slog.Any("error", err)) + } + } + + if stop { return nil } return workflow.NewContinueAsNewError(ctx, SyncFlowWorkflow, config, options) From 1faf6a5c23274f339f0553fce21c278fafd39a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 28 Mar 2024 07:42:43 +0000 Subject: [PATCH 25/48] Remove storybook (#1551) It isn't be used & it makes it annoying to grep code --- ui/.eslintrc.json | 2 +- ui/.storybook/decorators.tsx | 8 - ui/.storybook/main.ts | 57 - ui/.storybook/preview.ts | 17 - ui/.storybook/public/.gitignore | 4 - ui/README.md | 12 - ui/lib/Action/Action.stories.tsx | 18 - ui/lib/Avatar/Avatar.stories.tsx | 43 - ui/lib/Badge/Badge.stories.tsx | 34 - ui/lib/Button/Button.stories.tsx | 76 - ui/lib/ButtonGroup/ButtonGroup.stories.tsx | 38 - ui/lib/Chart/TrackerChart.stories.tsx | 43 - ui/lib/Checkbox/Checkbox.stories.tsx | 35 - ui/lib/CodeSnippet/CodeSnippet.stories.tsx | 30 - ui/lib/Color/Color.stories.tsx | 18 - ui/lib/Dialog/Dialog.stories.tsx | 29 - ui/lib/Dialog/DialogContent.stories.tsx | 54 - ui/lib/Header/Header.stories.tsx | 65 - ui/lib/Icon/Icon.stories.tsx | 21 - ui/lib/Label/Label.stories.tsx | 66 - ui/lib/Layout/ColumnWithTextField.stories.tsx | 29 - ui/lib/Layout/Layout.stories.tsx | 50 - ui/lib/Layout/Row.stories.tsx | 51 - ui/lib/Layout/RowWIthCheckbox.stories.tsx | 18 - ui/lib/Layout/RowWithButton.stories.tsx | 18 - ui/lib/Layout/RowWithProgressBar.stories.tsx | 31 - ui/lib/Layout/RowWithRadioButton.stories.tsx | 23 - ui/lib/Layout/RowWithSelect.stories.tsx | 19 - ui/lib/Layout/RowWithSwitch.stories.tsx | 18 - ui/lib/Layout/RowWithTextField.stories.tsx | 24 - ui/lib/Layout/RowWithToggleGroup.stories.tsx | 30 - ui/lib/Media/Media.stories.tsx | 85 - ui/lib/ProgressBar/ProgressBar.stories.tsx | 14 - .../ProgressCircle/ProgressCircle.stories.tsx | 21 - .../RadioButtonGroup.stories.tsx | 21 - ui/lib/SearchField/SearchField.stories.tsx | 20 - ui/lib/Separator/Separator.stories.tsx | 48 - ui/lib/Sidebar/Sidebar.stories.tsx | 41 - ui/lib/Sidebar/SidebarItem.stories.tsx | 35 - ui/lib/Slot/Slot.stories.tsx | 15 - ui/lib/Switch/Switch.stories.tsx | 26 - ui/lib/Table/Table.stories.tsx | 154 - ui/lib/Table/TableCell.stories.tsx | 39 - ui/lib/Table/TableRow.stories.tsx | 48 - ui/lib/TextField/TextField.stories.tsx | 26 - ui/lib/Thumbnail/Thumbnail.stories.tsx | 37 - ui/lib/Toast/Toast.stories.tsx | 31 - .../ToggleButton/ToggleButton.stories.tsx | 54 - .../ToggleGroup/ToggleGroup.stories.tsx | 35 - ui/lib/Tooltip/Tooltip.stories.tsx | 18 - ui/package-lock.json | 22181 ++++------------ ui/package.json | 28 +- 52 files changed, 4641 insertions(+), 19317 deletions(-) delete mode 100644 ui/.storybook/decorators.tsx delete mode 100644 ui/.storybook/main.ts delete mode 100644 ui/.storybook/preview.ts delete mode 100644 ui/.storybook/public/.gitignore delete mode 100644 ui/lib/Action/Action.stories.tsx delete mode 100644 ui/lib/Avatar/Avatar.stories.tsx delete mode 100644 ui/lib/Badge/Badge.stories.tsx delete mode 100644 ui/lib/Button/Button.stories.tsx delete mode 100644 ui/lib/ButtonGroup/ButtonGroup.stories.tsx delete mode 100644 ui/lib/Chart/TrackerChart.stories.tsx delete mode 100644 ui/lib/Checkbox/Checkbox.stories.tsx delete mode 100644 ui/lib/CodeSnippet/CodeSnippet.stories.tsx delete mode 100644 ui/lib/Color/Color.stories.tsx delete mode 100644 ui/lib/Dialog/Dialog.stories.tsx delete mode 100644 ui/lib/Dialog/DialogContent.stories.tsx delete mode 100644 ui/lib/Header/Header.stories.tsx delete mode 100644 ui/lib/Icon/Icon.stories.tsx delete mode 100644 ui/lib/Label/Label.stories.tsx delete mode 100644 ui/lib/Layout/ColumnWithTextField.stories.tsx delete mode 100644 ui/lib/Layout/Layout.stories.tsx delete mode 100644 ui/lib/Layout/Row.stories.tsx delete mode 100644 ui/lib/Layout/RowWIthCheckbox.stories.tsx delete mode 100644 ui/lib/Layout/RowWithButton.stories.tsx delete mode 100644 ui/lib/Layout/RowWithProgressBar.stories.tsx delete mode 100644 ui/lib/Layout/RowWithRadioButton.stories.tsx delete mode 100644 ui/lib/Layout/RowWithSelect.stories.tsx delete mode 100644 ui/lib/Layout/RowWithSwitch.stories.tsx delete mode 100644 ui/lib/Layout/RowWithTextField.stories.tsx delete mode 100644 ui/lib/Layout/RowWithToggleGroup.stories.tsx delete mode 100644 ui/lib/Media/Media.stories.tsx delete mode 100644 ui/lib/ProgressBar/ProgressBar.stories.tsx delete mode 100644 ui/lib/ProgressCircle/ProgressCircle.stories.tsx delete mode 100644 ui/lib/RadioButtonGroup/RadioButtonGroup.stories.tsx delete mode 100644 ui/lib/SearchField/SearchField.stories.tsx delete mode 100644 ui/lib/Separator/Separator.stories.tsx delete mode 100644 ui/lib/Sidebar/Sidebar.stories.tsx delete mode 100644 ui/lib/Sidebar/SidebarItem.stories.tsx delete mode 100644 ui/lib/Slot/Slot.stories.tsx delete mode 100644 ui/lib/Switch/Switch.stories.tsx delete mode 100644 ui/lib/Table/Table.stories.tsx delete mode 100644 ui/lib/Table/TableCell.stories.tsx delete mode 100644 ui/lib/Table/TableRow.stories.tsx delete mode 100644 ui/lib/TextField/TextField.stories.tsx delete mode 100644 ui/lib/Thumbnail/Thumbnail.stories.tsx delete mode 100644 ui/lib/Toast/Toast.stories.tsx delete mode 100644 ui/lib/Toggle/ToggleButton/ToggleButton.stories.tsx delete mode 100644 ui/lib/Toggle/ToggleGroup/ToggleGroup.stories.tsx delete mode 100644 ui/lib/Tooltip/Tooltip.stories.tsx diff --git a/ui/.eslintrc.json b/ui/.eslintrc.json index 1aa3f3c57b..c5d43a6eba 100644 --- a/ui/.eslintrc.json +++ b/ui/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": ["next", "plugin:storybook/recommended", "prettier"] + "extends": ["next", "prettier"] } diff --git a/ui/.storybook/decorators.tsx b/ui/.storybook/decorators.tsx deleted file mode 100644 index 311112c6aa..0000000000 --- a/ui/.storybook/decorators.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { Decorator } from '@storybook/react'; -import { AppThemeProvider } from '../lib/AppTheme'; - -export const withTheme: Decorator = (Story) => ( - - - -); diff --git a/ui/.storybook/main.ts b/ui/.storybook/main.ts deleted file mode 100644 index ec0111c96d..0000000000 --- a/ui/.storybook/main.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { StorybookConfig } from '@storybook/nextjs'; -import CopyPlugin from 'copy-webpack-plugin'; -import path from 'path'; - -const MATERIAL_ICONS_FONT_NODE_MODULE_PATH = - 'node_modules/material-symbols/material-symbols-sharp.woff2'; - -const config: StorybookConfig = { - stories: ['../lib/**/*.mdx', '../lib/**/*.stories.@(js|jsx|mjs|ts|tsx)'], - addons: [ - '@storybook/addon-links', - '@storybook/addon-essentials', - '@storybook/addon-interactions', - { - name: '@storybook/addon-styling', - options: { - postCss: { - implementation: require.resolve('postcss'), - }, - }, - }, - ], - framework: { - name: '@storybook/nextjs', - options: {}, - }, - docs: { - autodocs: 'tag', - }, - staticDirs: ['./public'], - webpackFinal(config) { - const iconsPath = path.resolve( - __dirname, - '..', - MATERIAL_ICONS_FONT_NODE_MODULE_PATH - ); - - const toPath = path.resolve( - __dirname, - 'public', - MATERIAL_ICONS_FONT_NODE_MODULE_PATH - ); - - config.plugins?.push( - new CopyPlugin({ - patterns: [ - { - from: iconsPath, - to: toPath, - }, - ], - }) - ); - return config; - }, -}; -export default config; diff --git a/ui/.storybook/preview.ts b/ui/.storybook/preview.ts deleted file mode 100644 index cfa5ad0e34..0000000000 --- a/ui/.storybook/preview.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { Preview } from '@storybook/react'; -import { withTheme } from './decorators'; - -const preview: Preview = { - parameters: { - actions: { argTypesRegex: '^on[A-Z].*' }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, - }, - }, - }, - decorators: [withTheme], -}; - -export default preview; diff --git a/ui/.storybook/public/.gitignore b/ui/.storybook/public/.gitignore deleted file mode 100644 index 86d0cb2726..0000000000 --- a/ui/.storybook/public/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore \ No newline at end of file diff --git a/ui/README.md b/ui/README.md index 6947d3f03d..e36ccbc937 100644 --- a/ui/README.md +++ b/ui/README.md @@ -21,15 +21,3 @@ npm run dev Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. The example project files resides inside the `app` folder. - -### Start the Storybook - -Every UI component has a [Storybook](https://storybook.js.org/) story attached to it. To run and view the Storybook for the project run the following - -```bash -npm run storybook -``` - -Open [http://localhost:6000](http://localhost:6000) with your browser to see the result. - -The stories and their corresponding components resides inside the `lib` folder. diff --git a/ui/lib/Action/Action.stories.tsx b/ui/lib/Action/Action.stories.tsx deleted file mode 100644 index ab074625ea..0000000000 --- a/ui/lib/Action/Action.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from '../Icon'; -import { Action } from './Action'; - -export default { - title: 'Components / Action', - component: Action, - tags: ['autodocs'], - args: { - disabled: false, - children: 'Label', - icon: , - href: '/', - }, -} as Meta; - -type Story = StoryObj; -export const Default: Story = {}; diff --git a/ui/lib/Avatar/Avatar.stories.tsx b/ui/lib/Avatar/Avatar.stories.tsx deleted file mode 100644 index 27dc6590ba..0000000000 --- a/ui/lib/Avatar/Avatar.stories.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Avatar } from './Avatar'; -import checkerImage from './checker.png'; - -export default { - title: 'Components / Avatar', - component: Avatar, - tags: ['autodocs'], - args: { - size: 'small', - }, - argTypes: { - variant: { - description: 'The variant of the Avatar', - }, - size: { - description: 'The size of the Avatar', - }, - }, -} satisfies Meta; - -type Story = StoryObj; -export const Image: Story = { - args: { - variant: 'image', - src: checkerImage.src, - alt: 'Checker Image Avatar', - }, -}; - -export const Text: Story = { - args: { - variant: 'text', - text: 'MP', - }, -}; - -export const Icon: Story = { - args: { - variant: 'icon', - name: 'square', - }, -}; diff --git a/ui/lib/Badge/Badge.stories.tsx b/ui/lib/Badge/Badge.stories.tsx deleted file mode 100644 index 58b1836884..0000000000 --- a/ui/lib/Badge/Badge.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from '../Icon'; -import { Badge } from './Badge'; - -export default { - title: 'Components / Badge', - component: Badge, - tags: ['autodocs'], - args: { - variant: 'normal', - }, -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = { - args: { - variant: 'normal', - type: 'default', - }, - render: (props) => ( - - - Label - - ), -}; - -export const SingleDigit: Story = { - args: { - variant: 'normal', - type: 'singleDigit', - }, - render: (props) => 3, -}; diff --git a/ui/lib/Button/Button.stories.tsx b/ui/lib/Button/Button.stories.tsx deleted file mode 100644 index e21b1acff5..0000000000 --- a/ui/lib/Button/Button.stories.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from '../Icon'; -import { Button } from './Button'; - -export default { - title: 'Components / Button', - component: Button, - tags: ['autodocs'], - args: { - children: 'Action', - loading: false, - }, - argTypes: { - onClick: { - action: 'Clicked', - }, - }, -} satisfies Meta; - -type Story = StoryObj; -export const Normal: Story = { - args: { - variant: 'normal', - }, -}; - -export const Destructive: Story = { - args: { - variant: 'destructive', - }, -}; - -export const NormalSolid: Story = { - args: { - variant: 'normalSolid', - }, -}; - -export const DestructiveSolid: Story = { - args: { - variant: 'destructiveSolid', - }, -}; - -export const NormalBorderless: Story = { - args: { - variant: 'normalBorderless', - }, -}; - -export const DestructiveBorderless: Story = { - args: { - variant: 'destructiveBorderless', - }, -}; - -export const WithIcon: Story = { - args: { - variant: 'normal', - children: , - }, -}; - -export const Disabled: Story = { - args: { - variant: 'normal', - disabled: true, - }, -}; - -export const Loading: Story = { - args: { - variant: 'normal', - loading: true, - }, -}; diff --git a/ui/lib/ButtonGroup/ButtonGroup.stories.tsx b/ui/lib/ButtonGroup/ButtonGroup.stories.tsx deleted file mode 100644 index ec5c6b737c..0000000000 --- a/ui/lib/ButtonGroup/ButtonGroup.stories.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Button } from '../Button'; -import { ButtonGroup } from './ButtonGroup'; - -export default { - title: 'Components / ButtonGroup', - component: ButtonGroup, - tags: ['autodocs'], -} satisfies Meta; - -type Story = StoryObj; - -export const OneButton: Story = { - render: () => ( - - - - ), -}; - -export const TwoButtons: Story = { - render: () => ( - - - - - ), -}; - -export const ThreeButtons: Story = { - render: () => ( - - - - - - ), -}; diff --git a/ui/lib/Chart/TrackerChart.stories.tsx b/ui/lib/Chart/TrackerChart.stories.tsx deleted file mode 100644 index b2a71e98e7..0000000000 --- a/ui/lib/Chart/TrackerChart.stories.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Color } from '@tremor/react'; -import { Label } from '../Label'; -import { RowWithToggleGroup } from '../Layout'; -import { ToggleGroup, ToggleGroupItem } from '../Toggle'; -import { TrackerChart } from './TrackerChart'; - -const weekdays = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']; - -interface Tracker { - color: Color; - tooltip: string; -} - -const weekData = weekdays.map((weekDay) => ({ - tooltip: weekDay, - color: Math.random() > 0.5 ? 'blue' : 'gray', -})); - -export default { - title: 'Components / Tracker', - component: TrackerChart, - tags: ['autodocs'], - args: { - data: weekData, - top: ( - Sync history} - action={ - - Month - Week - Day - - } - /> - ), - }, -} as Meta; - -type Story = StoryObj; - -export const Default: Story = {}; diff --git a/ui/lib/Checkbox/Checkbox.stories.tsx b/ui/lib/Checkbox/Checkbox.stories.tsx deleted file mode 100644 index 1708b52c96..0000000000 --- a/ui/lib/Checkbox/Checkbox.stories.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Checkbox } from './Checkbox'; - -export default { - title: 'Components / Input / Checkbox', - component: Checkbox, - tags: ['autodocs'], - args: { - name: 'story', - disabled: false, - defaultChecked: false, - }, -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; - -export const Mixed: Story = { - args: { - checked: true, - variant: 'mixed', - }, -}; - -export const Disabled: Story = { - args: { - disabled: true, - }, -}; - -export const Checked: Story = { - args: { - checked: true, - }, -}; diff --git a/ui/lib/CodeSnippet/CodeSnippet.stories.tsx b/ui/lib/CodeSnippet/CodeSnippet.stories.tsx deleted file mode 100644 index 78339e534e..0000000000 --- a/ui/lib/CodeSnippet/CodeSnippet.stories.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { CodeSnippet } from './CodeSnippet'; - -export default { - title: 'Components / Input / CodeSnippet', - component: CodeSnippet, - tags: ['autodocs'], - args: { - defaultValue: `apiVersion: apps/v1 - kind: DaemonSet - metadata: - name: kernel-optimization - namespace: kube-system - labels: - tier: management - app: kernel-optimization - spec: - selector:`, - disabled: false, - }, -} satisfies Meta; - -type Story = StoryObj; - -export const Default: Story = {}; -export const Disabled: Story = { - args: { - disabled: true, - }, -}; diff --git a/ui/lib/Color/Color.stories.tsx b/ui/lib/Color/Color.stories.tsx deleted file mode 100644 index 8f0218e9df..0000000000 --- a/ui/lib/Color/Color.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { Color } from './Color'; - -export default { - title: 'Utils / Color', - component: Color, - tags: ['autodocs'], -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = { - render: () => ( - - - - ), -}; diff --git a/ui/lib/Dialog/Dialog.stories.tsx b/ui/lib/Dialog/Dialog.stories.tsx deleted file mode 100644 index 625c3be20d..0000000000 --- a/ui/lib/Dialog/Dialog.stories.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Button } from '../Button'; -import { Label } from '../Label'; -import { Dialog, DialogClose } from './Dialog'; - -export default { - title: 'Components / Dialog', - component: Dialog, - tags: ['autodocs'], - args: { - triggerButton: , - size: 'xxSmall', - }, - render: (props) => ( - - - - - - - ), -} as Meta; - -type Story = StoryObj; -export const Default: Story = { - args: { - size: 'xxSmall', - }, -}; diff --git a/ui/lib/Dialog/DialogContent.stories.tsx b/ui/lib/Dialog/DialogContent.stories.tsx deleted file mode 100644 index 8843fadd83..0000000000 --- a/ui/lib/Dialog/DialogContent.stories.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import * as RadixDialog from '@radix-ui/react-dialog'; -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { DialogContent } from './DialogContent'; - -export default { - title: 'Components / Dialog / DialogContent', - component: DialogContent, - tags: ['autodocs'], - render: (props) => ( - - - - - - ), -} satisfies Meta; - -type Story = StoryObj; -export const XXSmall: Story = { - args: { - size: 'xxSmall', - }, -}; - -export const XSmall: Story = { - args: { - size: 'xSmall', - }, -}; - -export const Small: Story = { - args: { - size: 'small', - }, -}; - -export const Medium: Story = { - args: { - size: 'medium', - }, -}; - -export const Large: Story = { - args: { - size: 'large', - }, -}; - -export const XLarge: Story = { - args: { - size: 'xLarge', - }, -}; diff --git a/ui/lib/Header/Header.stories.tsx b/ui/lib/Header/Header.stories.tsx deleted file mode 100644 index 3cc3da4d37..0000000000 --- a/ui/lib/Header/Header.stories.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Header } from './Header'; - -export default { - title: 'Components / Header', - component: Header, - tags: ['autodocs'], - args: { - variant: 'body', - }, -} satisfies Meta; - -type Story = StoryObj; -export const Body: Story = { - args: { - variant: 'body', - children: 'Body', - }, -}; - -export const Subheadline: Story = { - args: { - variant: 'subheadline', - children: 'Subheadline', - }, -}; - -export const Headline: Story = { - args: { - variant: 'headline', - children: 'Headline', - }, -}; - -export const Title3: Story = { - args: { - variant: 'title3', - children: 'Title 3', - as: 'h3', - }, -}; - -export const Title2: Story = { - args: { - variant: 'title2', - children: 'Title 2', - as: 'h2', - }, -}; - -export const Title1: Story = { - args: { - variant: 'title1', - children: 'Title 1', - as: 'h1', - }, -}; - -export const LargeTitle: Story = { - args: { - variant: 'largeTitle', - children: 'Large Title', - as: 'h3', - }, -}; diff --git a/ui/lib/Icon/Icon.stories.tsx b/ui/lib/Icon/Icon.stories.tsx deleted file mode 100644 index 4bc69aa5ab..0000000000 --- a/ui/lib/Icon/Icon.stories.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from './Icon'; - -export default { - title: 'Components / Icon', - component: Icon, - tags: ['autodocs'], - args: { - name: 'square', - fill: false, - }, -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; - -export const Filled: Story = { - args: { - fill: true, - }, -}; diff --git a/ui/lib/Label/Label.stories.tsx b/ui/lib/Label/Label.stories.tsx deleted file mode 100644 index 1f05291a54..0000000000 --- a/ui/lib/Label/Label.stories.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from './Label'; - -export default { - title: 'Components / Label', - component: Label, - tags: ['autodocs'], - args: { - children: 'Label', - }, -} as Meta; - -type Story = StoryObj; -export const Body: Story = { - args: { - variant: 'body', - }, -}; - -export const Action: Story = { - args: { - variant: 'action', - }, -}; - -export const Footnote: Story = { - args: { - variant: 'footnote', - }, -}; - -export const Subheadline: Story = { - args: { - variant: 'subheadline', - }, -}; - -export const Headline: Story = { - args: { - variant: 'headline', - }, -}; - -export const Title3: Story = { - args: { - variant: 'title3', - }, -}; - -export const Title2: Story = { - args: { - variant: 'title2', - }, -}; - -export const Title1: Story = { - args: { - variant: 'title1', - }, -}; - -export const LargeTitle: Story = { - args: { - variant: 'largeTitle', - }, -}; diff --git a/ui/lib/Layout/ColumnWithTextField.stories.tsx b/ui/lib/Layout/ColumnWithTextField.stories.tsx deleted file mode 100644 index 3e9d6b6ebb..0000000000 --- a/ui/lib/Layout/ColumnWithTextField.stories.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { TextField } from '../TextField'; -import { ColumnWithTextField } from './Layout'; - -export default { - title: 'Components / Layout / ColumnWithTextField', - component: ColumnWithTextField, - args: { - label: , - action: , - description: , - }, -} satisfies Meta; - -export const Default: StoryObj = {}; - -export const WithInstruction: StoryObj = { - args: { - instruction: , - }, -}; - -export const WithSuffix: StoryObj = { - args: { - instruction: , - suffix: , - }, -}; diff --git a/ui/lib/Layout/Layout.stories.tsx b/ui/lib/Layout/Layout.stories.tsx deleted file mode 100644 index 2d5e625eef..0000000000 --- a/ui/lib/Layout/Layout.stories.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Button } from '../Button'; -import { Header } from '../Header'; -import { Icon } from '../Icon'; -import { Label } from '../Label'; -import { Sidebar, SidebarItem } from '../Sidebar'; -import { Layout } from './Layout'; - -export default { - title: 'Components / Layout', - component: Layout, - tags: ['autodocs'], - args: {}, -} satisfies Meta; - -type Story = StoryObj; -export const Overview: Story = { - render: () => ( - PeerDB} - bottomRow={ - <> - - - - } - bottomLabel={} - > - }> - Dashboard - - }> - Connectors - - }> - Mirrors - - }>Cloud - }> - Settings - - - } - > -
Dashboard
-
- ), -}; diff --git a/ui/lib/Layout/Row.stories.tsx b/ui/lib/Layout/Row.stories.tsx deleted file mode 100644 index 7eedd36025..0000000000 --- a/ui/lib/Layout/Row.stories.tsx +++ /dev/null @@ -1,51 +0,0 @@ -'use client'; - -import { Meta, StoryObj } from '@storybook/react'; -import { Color } from '../Color'; -import { Icon } from '../Icon'; -import { Thumbnail } from '../Thumbnail'; -import { Row } from './Row'; -import checkerImage from './checker.png'; - -export default { - title: 'Components / Layout / Row', - component: Row, - tags: ['autodocs'], - args: { - leadingIcon: , - thumbnail: , - trailingIcon: , - preTitle: 'Pre-title', - title: ( - <> - - Green - - Title - - ), - description: 'Description', - titleSuffix: 'Suffix', - descriptionSuffix: 'Suffix', - footnote: 'Footnote', - }, -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; - -export const Focused: Story = { - args: { - variant: 'focused', - }, -}; - -export const Disabled: Story = { - args: { - variant: 'disabled', - }, -}; diff --git a/ui/lib/Layout/RowWIthCheckbox.stories.tsx b/ui/lib/Layout/RowWIthCheckbox.stories.tsx deleted file mode 100644 index e999904b4a..0000000000 --- a/ui/lib/Layout/RowWIthCheckbox.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -'use client'; - -import { Meta, StoryObj } from '@storybook/react'; -import { Checkbox } from '../Checkbox'; -import { Label } from '../Label'; -import { RowWithCheckbox } from './Layout'; - -export default { - title: 'Components / Layout / RowWithCheckbox', - component: RowWithCheckbox, - args: { - label: , - action: , - description: , - }, -} satisfies Meta; - -export const Default: StoryObj = {}; diff --git a/ui/lib/Layout/RowWithButton.stories.tsx b/ui/lib/Layout/RowWithButton.stories.tsx deleted file mode 100644 index 41d7f77854..0000000000 --- a/ui/lib/Layout/RowWithButton.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -'use client'; - -import { Meta, StoryObj } from '@storybook/react'; -import { Button } from '../Button'; -import { Label } from '../Label'; -import { RowWithButton } from './Layout'; - -export default { - title: 'Components / Layout / RowWithButton', - component: RowWithButton, - args: { - label: , - action: , - description: , - }, -} satisfies Meta; - -export const Default: StoryObj = {}; diff --git a/ui/lib/Layout/RowWithProgressBar.stories.tsx b/ui/lib/Layout/RowWithProgressBar.stories.tsx deleted file mode 100644 index 42e99c1fc9..0000000000 --- a/ui/lib/Layout/RowWithProgressBar.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -'use client'; - -import { Meta, StoryObj } from '@storybook/react'; -import { Button } from '../Button'; -import { Icon } from '../Icon'; -import { Label } from '../Label'; -import { ProgressBar } from '../ProgressBar'; -import { RowWithProgressBar } from './Layout'; - -export default { - title: 'Components / Layout / RowWithProgressBar', - component: RowWithProgressBar, - args: { - label: , - action: , - description: , - }, -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; - -export const WithSlot: Story = { - args: { - actionSlot: ( - - ), - }, -}; diff --git a/ui/lib/Layout/RowWithRadioButton.stories.tsx b/ui/lib/Layout/RowWithRadioButton.stories.tsx deleted file mode 100644 index 2458703e16..0000000000 --- a/ui/lib/Layout/RowWithRadioButton.stories.tsx +++ /dev/null @@ -1,23 +0,0 @@ -'use client'; - -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { RadioButton, RadioButtonGroup } from '../RadioButtonGroup'; -import { RowWithRadiobutton } from './Layout'; - -export default { - title: 'Components / Layout / RowWithRadioButton', - component: RowWithRadiobutton, - args: { - label: , - action: , - description: , - }, - render: (props) => ( - - - - ), -} satisfies Meta; - -export const Default: StoryObj = {}; diff --git a/ui/lib/Layout/RowWithSelect.stories.tsx b/ui/lib/Layout/RowWithSelect.stories.tsx deleted file mode 100644 index 3af3dfaafa..0000000000 --- a/ui/lib/Layout/RowWithSelect.stories.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { RowWithSelect } from './Layout'; - -export default { - title: 'Components / Layout / RowWithSelect', - component: RowWithSelect, - args: { - label: ( - - ), - action:
select
, - description: , - }, -} satisfies Meta; - -export const Default: StoryObj = {}; diff --git a/ui/lib/Layout/RowWithSwitch.stories.tsx b/ui/lib/Layout/RowWithSwitch.stories.tsx deleted file mode 100644 index ffd537aeb9..0000000000 --- a/ui/lib/Layout/RowWithSwitch.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -'use client'; - -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { Switch } from '../Switch'; -import { RowWithSwitch } from './Layout'; - -export default { - title: 'Components / Layout / RowWithSwitch', - component: RowWithSwitch, - args: { - label: , - action: , - description: , - }, -} satisfies Meta; - -export const Default: StoryObj = {}; diff --git a/ui/lib/Layout/RowWithTextField.stories.tsx b/ui/lib/Layout/RowWithTextField.stories.tsx deleted file mode 100644 index f51040b76d..0000000000 --- a/ui/lib/Layout/RowWithTextField.stories.tsx +++ /dev/null @@ -1,24 +0,0 @@ -'use client'; - -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { TextField } from '../TextField'; -import { RowWithTextField } from './Layout'; - -export default { - title: 'Components / Layout / RowWithTextField', - component: RowWithTextField, - args: { - label: , - action: , - description: , - }, -} satisfies Meta; - -export const Default: StoryObj = {}; - -export const WithInstruction: StoryObj = { - args: { - instruction: , - }, -}; diff --git a/ui/lib/Layout/RowWithToggleGroup.stories.tsx b/ui/lib/Layout/RowWithToggleGroup.stories.tsx deleted file mode 100644 index 8848a000d7..0000000000 --- a/ui/lib/Layout/RowWithToggleGroup.stories.tsx +++ /dev/null @@ -1,30 +0,0 @@ -'use client'; - -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from '../Icon'; -import { Label } from '../Label'; -import { ToggleGroup, ToggleGroupItem } from '../Toggle'; -import { RowWithToggleGroup } from './Layout'; - -export default { - title: 'Components / Layout / RowWithToggleGroup', - component: RowWithToggleGroup, - args: { - label: , - action: ( - - - - - - - - - - - - ), - }, -} satisfies Meta; - -export const Default: StoryObj = {}; diff --git a/ui/lib/Media/Media.stories.tsx b/ui/lib/Media/Media.stories.tsx deleted file mode 100644 index cc056b1603..0000000000 --- a/ui/lib/Media/Media.stories.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Media } from './Media'; -import checkerImage from './checker.png'; - -export default { - title: 'Components / Media', - component: Media, - tags: ['autodocs'], - args: { - src: checkerImage.src, - }, -} as Meta; - -type Story = StoryObj; -export const AspectRatio1x1: Story = { - args: { - ratio: '1 / 1', - }, -}; - -export const AspectRatio2x1: Story = { - args: { - ratio: '2 / 1', - }, -}; - -export const AspectRatio2x3: Story = { - args: { - ratio: '2 / 3', - }, -}; - -export const AspectRatio3x2: Story = { - args: { - ratio: '3 / 2', - }, -}; - -export const AspectRatio3x4: Story = { - args: { - ratio: '3 / 4', - }, -}; - -export const AspectRatio4x3: Story = { - args: { - ratio: '4 / 3', - }, -}; - -export const AspectRatio4x5: Story = { - args: { - ratio: '4 / 5', - }, -}; - -export const AspectRatio5x4: Story = { - args: { - ratio: '5 / 4', - }, -}; - -export const AspectRatio9x16: Story = { - args: { - ratio: '9 / 16', - }, -}; - -export const AspectRatio16x9: Story = { - args: { - ratio: '16 / 9', - }, -}; - -export const AspectRatio21x9: Story = { - args: { - ratio: '21 / 9', - }, -}; - -export const AspectRatioGolden: Story = { - args: { - ratio: 'golden', - }, -}; diff --git a/ui/lib/ProgressBar/ProgressBar.stories.tsx b/ui/lib/ProgressBar/ProgressBar.stories.tsx deleted file mode 100644 index bc3c059eb0..0000000000 --- a/ui/lib/ProgressBar/ProgressBar.stories.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { ProgressBar } from './ProgressBar'; - -export default { - title: 'Components / ProgressBar', - component: ProgressBar, - tags: ['autodocs'], - args: { - progress: 50, - }, -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; diff --git a/ui/lib/ProgressCircle/ProgressCircle.stories.tsx b/ui/lib/ProgressCircle/ProgressCircle.stories.tsx deleted file mode 100644 index 895f29a6ad..0000000000 --- a/ui/lib/ProgressCircle/ProgressCircle.stories.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { ProgressCircle } from './ProgressCircle'; - -export default { - title: 'Components / ProgressCircle', - component: ProgressCircle, - tags: ['autodocs'], -} satisfies Meta; - -type Story = StoryObj; -export const DeterminateProgressCircle: Story = { - args: { - variant: 'determinate_progress_circle', - }, -}; - -export const IndeterminateProgressCircle: Story = { - args: { - variant: 'intermediate_progress_circle', - }, -}; diff --git a/ui/lib/RadioButtonGroup/RadioButtonGroup.stories.tsx b/ui/lib/RadioButtonGroup/RadioButtonGroup.stories.tsx deleted file mode 100644 index 66576a34c7..0000000000 --- a/ui/lib/RadioButtonGroup/RadioButtonGroup.stories.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { RadioButton, RadioButtonGroup } from './RadioButtonGroup'; - -export default { - title: 'Components / Input / RadioButtonGroup', - component: RadioButtonGroup, - tags: ['autodocs'], - args: { - children: , - disabled: false, - }, -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; - -export const Disabled: Story = { - args: { - disabled: true, - }, -}; diff --git a/ui/lib/SearchField/SearchField.stories.tsx b/ui/lib/SearchField/SearchField.stories.tsx deleted file mode 100644 index f717d61506..0000000000 --- a/ui/lib/SearchField/SearchField.stories.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { SearchField } from './SearchField'; - -export default { - title: 'Components / SearchField', - component: SearchField, - tags: ['autodocs'], - args: { - placeholder: 'Placeholder', - }, -} as Meta; - -type Story = StoryObj; -export const Default: Story = {}; - -export const Disabled: Story = { - args: { - disabled: true, - }, -}; diff --git a/ui/lib/Separator/Separator.stories.tsx b/ui/lib/Separator/Separator.stories.tsx deleted file mode 100644 index 5cf441785e..0000000000 --- a/ui/lib/Separator/Separator.stories.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Separator } from './Separator'; - -export default { - title: 'Components / Separator', - component: Separator, - tags: ['autodocs'], - args: { - height: 'tall', - variant: 'normal', - }, -} as Meta; - -type Story = StoryObj; -export const Normal: Story = { - args: { - variant: 'normal', - height: 'tall', - }, -}; - -export const Indent: Story = { - args: { - variant: 'indent', - height: 'tall', - }, -}; - -export const Thick: Story = { - args: { - variant: 'thick', - height: 'tall', - }, -}; - -export const Centered: Story = { - args: { - variant: 'centered', - height: 'tall', - }, -}; - -export const Empty: Story = { - args: { - variant: 'empty', - height: 'tall', - }, -}; diff --git a/ui/lib/Sidebar/Sidebar.stories.tsx b/ui/lib/Sidebar/Sidebar.stories.tsx deleted file mode 100644 index 94cc07fe99..0000000000 --- a/ui/lib/Sidebar/Sidebar.stories.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Color } from '../Color'; -import { Icon } from '../Icon'; -import { Label } from '../Label'; -import { Separator } from '../Separator'; -import { Sidebar } from './Sidebar'; -import { SidebarItem } from './SidebarItem'; - -export default { - title: 'Components / Sidebar', - component: Sidebar, - tags: ['autodocs'], - args: {}, -} as Meta; - -type Story = StoryObj; -export const Default: Story = { - render: (props) => ( - - - - - }>Recents - } selected> - Desktop - - }>Documents - }> - Downloads - - - - - - }> - Macintosh HD - - }>Network - - ), -}; diff --git a/ui/lib/Sidebar/SidebarItem.stories.tsx b/ui/lib/Sidebar/SidebarItem.stories.tsx deleted file mode 100644 index 046646e78d..0000000000 --- a/ui/lib/Sidebar/SidebarItem.stories.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from '../Icon'; -import { SidebarItem } from './SidebarItem'; - -export default { - title: 'Components / Sidebar / SidebarItem', - component: SidebarItem, - tags: ['autodocs'], - args: { - selected: false, - disabled: false, - leadingIcon: , - trailingIcon: , - suffix: 'Suffix', - }, -} as Meta; - -type Story = StoryObj; -export const Default: Story = { - render: (props) => Label, -}; - -export const Selected: Story = { - args: { - selected: true, - }, - render: (props) => Label, -}; - -export const Disabled: Story = { - args: { - disabled: true, - }, - render: (props) => Label, -}; diff --git a/ui/lib/Slot/Slot.stories.tsx b/ui/lib/Slot/Slot.stories.tsx deleted file mode 100644 index 0b93e695ca..0000000000 --- a/ui/lib/Slot/Slot.stories.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { Slot } from './Slot'; - -export default { - title: 'Components / Slot', - component: Slot, - tags: ['autodocs'], - args: { - children: , - }, -} as Meta; - -type Story = StoryObj; -export const Default: Story = {}; diff --git a/ui/lib/Switch/Switch.stories.tsx b/ui/lib/Switch/Switch.stories.tsx deleted file mode 100644 index e6ba7c4112..0000000000 --- a/ui/lib/Switch/Switch.stories.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Switch } from './Switch'; - -export default { - title: 'Components / Input / Switch', - component: Switch, - tags: ['autodocs'], - args: { - name: 'story', - }, -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; - -export const Disabled: Story = { - args: { - disabled: true, - }, -}; - -export const Checked: Story = { - args: { - checked: true, - }, -}; diff --git a/ui/lib/Table/Table.stories.tsx b/ui/lib/Table/Table.stories.tsx deleted file mode 100644 index 9bf333d213..0000000000 --- a/ui/lib/Table/Table.stories.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Badge } from '../Badge'; -import { Button } from '../Button'; -import { Checkbox } from '../Checkbox'; -import { Icon } from '../Icon'; -import { Label } from '../Label'; -import { SearchField } from '../SearchField'; -import { Table } from './Table'; -import { TableCell } from './TableCell'; -import { TableRow } from './TableRow'; - -export default { - title: 'Components / Table', - component: Table, - tags: ['autodocs'], - render: (props) => ( - Table title} - toolbar={{ - left: ( - <> - - - - - - - ), - right: ( - <> - - - - ), - }} - header={ - - - - - - - - - } - > - - - - - - - - - - - - - - - - - - - - - Active - - - - - - - - - - - - - - - - - - - - - - - - - - Active - - - - - - - - - - - - - - - - - - - - - - - - - - Active - - - - - -
- ), -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; diff --git a/ui/lib/Table/TableCell.stories.tsx b/ui/lib/Table/TableCell.stories.tsx deleted file mode 100644 index 43a8a52225..0000000000 --- a/ui/lib/Table/TableCell.stories.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Checkbox } from '../Checkbox'; -import { Label } from '../Label'; -import { TableCell } from './TableCell'; - -export default { - title: 'Components / Table / TableCell', - component: TableCell, -} satisfies Meta; - -type Story = StoryObj; -export const ButtonCell: Story = { - args: { - variant: 'button', - }, - render: (props) => ( - - - - ), -}; - -export const NormalCell: Story = { - args: { - variant: 'normal', - }, - render: (props) => , -}; - -export const ExtendedCell: Story = { - args: { - variant: 'extended', - }, - render: (props) => ( - - - - ), -}; diff --git a/ui/lib/Table/TableRow.stories.tsx b/ui/lib/Table/TableRow.stories.tsx deleted file mode 100644 index e849e5c00f..0000000000 --- a/ui/lib/Table/TableRow.stories.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Badge } from '../Badge'; -import { Button } from '../Button'; -import { Checkbox } from '../Checkbox'; -import { Icon } from '../Icon'; -import { Label } from '../Label'; -import { TableCell } from './TableCell'; -import { TableRow } from './TableRow'; - -export default { - title: 'Components / Table / TableRow', - component: TableRow, - render: () => ( - - - - - - - - - - - - - - - - - - - - - Active - - - - - - -
- ), -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = {}; diff --git a/ui/lib/TextField/TextField.stories.tsx b/ui/lib/TextField/TextField.stories.tsx deleted file mode 100644 index 4f0d4335bc..0000000000 --- a/ui/lib/TextField/TextField.stories.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { TextField } from './TextField'; - -export default { - title: 'Components / Input / TextField', - component: TextField, - tags: ['autodocs'], - args: { - placeholder: 'Placeholder', - disabled: false, - }, -} satisfies Meta; - -type Story = StoryObj; - -export const SimpleField: Story = { - args: { - variant: 'simple', - }, -}; - -export const TextAreaField: Story = { - args: { - variant: 'text-area', - }, -}; diff --git a/ui/lib/Thumbnail/Thumbnail.stories.tsx b/ui/lib/Thumbnail/Thumbnail.stories.tsx deleted file mode 100644 index 1e77b8e248..0000000000 --- a/ui/lib/Thumbnail/Thumbnail.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Thumbnail } from '.'; -import checkerImage from './checker.png'; - -export default { - title: 'Components / Thumbnail', - component: Thumbnail, - tags: ['autodocs'], - args: { - src: checkerImage.src, - }, -} as Meta; - -type Story = StoryObj; -export const Small: Story = { - args: { - size: 'small', - }, -}; - -export const Medium: Story = { - args: { - size: 'medium', - }, -}; - -export const Large: Story = { - args: { - size: 'large', - }, -}; - -export const XLarge: Story = { - args: { - size: 'xLarge', - }, -}; diff --git a/ui/lib/Toast/Toast.stories.tsx b/ui/lib/Toast/Toast.stories.tsx deleted file mode 100644 index d27f42b193..0000000000 --- a/ui/lib/Toast/Toast.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from '../Icon'; -import { ProgressCircle } from '../ProgressCircle'; -import { Toast } from './Toast'; - -export default { - title: 'Components / Toast', - component: Toast, - tags: ['autodocs'], - args: { - message: 'Message', - actionText: 'Action', - icon: , - open: true, - }, -} satisfies Meta; - -type Story = StoryObj; -export const DefaultInteractive: Story = {}; - -export const DefaultNonInteractive: Story = { - args: { - actionText: undefined, - }, -}; - -export const DefaultTimed: Story = { - args: { - icon: , - }, -}; diff --git a/ui/lib/Toggle/ToggleButton/ToggleButton.stories.tsx b/ui/lib/Toggle/ToggleButton/ToggleButton.stories.tsx deleted file mode 100644 index 98cce3d948..0000000000 --- a/ui/lib/Toggle/ToggleButton/ToggleButton.stories.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from '../../Icon'; -import { ToggleButton } from './ToggleButton'; - -export default { - title: 'Components / Toggle / ToggleButton', - component: ToggleButton, - tags: ['autodocs'], - args: { - disabled: false, - pressed: false, - }, -} satisfies Meta; - -type Story = StoryObj; -export const DefaultIcon: Story = { - args: { - children: , - }, -}; - -export const DefaultLabel: Story = { - args: { - children: 'Toggle', - }, -}; - -export const SelectedIcon: Story = { - args: { - pressed: true, - children: , - }, -}; - -export const SelectedLabel: Story = { - args: { - pressed: true, - children: 'Toggle', - }, -}; - -export const DisabledIcon: Story = { - args: { - disabled: true, - children: , - }, -}; - -export const DisabledLabel: Story = { - args: { - disabled: true, - children: 'Toggle', - }, -}; diff --git a/ui/lib/Toggle/ToggleGroup/ToggleGroup.stories.tsx b/ui/lib/Toggle/ToggleGroup/ToggleGroup.stories.tsx deleted file mode 100644 index 28ae43e410..0000000000 --- a/ui/lib/Toggle/ToggleGroup/ToggleGroup.stories.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Icon } from '../../Icon'; -import { ToggleGroup } from './ToggleGroup'; -import { ToggleGroupItem } from './ToggleGroup.styles'; - -export default { - title: 'Components / Toggle / ToggleGroup', - component: ToggleGroup, - tags: ['autodocs'], - args: { - disabled: false, - }, - render: (props) => ( - - - - - - - - - - - - ), -} as Meta; - -type Story = StoryObj; -export const Default: Story = {}; - -export const Disabled: Story = { - args: { - disabled: true, - }, -}; diff --git a/ui/lib/Tooltip/Tooltip.stories.tsx b/ui/lib/Tooltip/Tooltip.stories.tsx deleted file mode 100644 index 98a4826e35..0000000000 --- a/ui/lib/Tooltip/Tooltip.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; -import { Label } from '../Label'; -import { Tooltip } from './Tooltip'; - -export default { - title: 'Components / Tooltip', - component: Tooltip, - tags: ['autodocs'], -} satisfies Meta; - -type Story = StoryObj; -export const Default: Story = { - render: () => ( - - - - ), -}; diff --git a/ui/package-lock.json b/ui/package-lock.json index 99e98ec366..12ce907ffd 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -8,7 +8,7 @@ "name": "peerdb-ui", "version": "0.1.0", "dependencies": { - "@grpc/grpc-js": "^1.10.3", + "@grpc/grpc-js": "^1.10.4", "@monaco-editor/react": "^4.6.0", "@prisma/client": "^5.11.0", "@radix-ui/react-checkbox": "^1.0.4", @@ -26,13 +26,13 @@ "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-toggle-group": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", - "@tremor/react": "^3.14.1", + "@tremor/react": "^3.15.0", "@types/node": "^20.11.30", - "@types/react": "^18.2.70", + "@types/react": "^18.2.73", "@types/react-dom": "^18.2.22", "classnames": "^2.5.1", "long": "^5.2.3", - "lucide-react": "^0.354.0", + "lucide-react": "^0.363.0", "material-symbols": "^0.17.1", "moment": "^2.30.1", "moment-timezone": "^0.5.45", @@ -47,33 +47,23 @@ "react-toastify": "^10.0.5", "styled-components": "^6.1.8", "swr": "^2.2.5", - "usehooks-ts": "^2.16.0", + "usehooks-ts": "^3.0.2", "zod": "^3.22.4" }, "devDependencies": { - "@storybook/addon-essentials": "^8.0.4", - "@storybook/addon-interactions": "^8.0.4", - "@storybook/addon-links": "^8.0.4", - "@storybook/addon-styling": "^1.3.7", - "@storybook/blocks": "^8.0.0", - "@storybook/nextjs": "^8.0.4", - "@storybook/react": "^8.0.0", - "@storybook/testing-library": "^0.2.2", "autoprefixer": "^10.4.19", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", "eslint-config-next": "^14.1.4", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-storybook": "^0.8.0", "gh-pages": "^6.1.1", "less": "^4.2.0", "postcss": "^8.4.38", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", "prisma": "^5.11.0", - "storybook": "^8.0.4", "string-width": "^7.1.0", - "tailwindcss": "^3.4.1", + "tailwindcss": "^3.4.3", "tailwindcss-animate": "^1.0.7", "typescript": "^5.4.3", "webpack": "^5.91.0" @@ -88,12 +78,6 @@ "node": ">=0.10.0" } }, - "node_modules/@adobe/css-tools": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", - "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==", - "dev": true - }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -105,31 +89,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@aw-web-design/x-default-browser": { - "version": "1.4.126", - "resolved": "https://registry.npmjs.org/@aw-web-design/x-default-browser/-/x-default-browser-1.4.126.tgz", - "integrity": "sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug==", - "dev": true, - "dependencies": { - "default-browser-id": "3.0.0" - }, - "bin": { - "x-default-browser": "bin/x-default-browser.js" - } - }, "node_modules/@babel/code-frame": { "version": "7.24.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", @@ -142,13241 +101,3030 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", - "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { + "node_modules/@babel/helper-module-imports": { "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", - "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.1", - "@babel/parser": "^7.24.1", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "dependencies": { + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/generator": { + "node_modules/@babel/helper-string-parser": { "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", - "dev": true, + "node_modules/@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dev": true, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", - "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", - "dev": true, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=4" } }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", - "dev": true, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "color-name": "1.1.3" } }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { - "node": ">=6.9.0" + "node": ">=0.8.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { - "@babel/types": "^7.22.5" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", - "dev": true, + "node_modules/@babel/runtime": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", "dependencies": { - "@babel/types": "^7.23.0" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dependencies": { - "@babel/types": "^7.24.0" + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "engines": { - "node": ">=6.9.0" + "node": ">=0.10.0" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", - "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", - "dev": true, - "engines": { - "node": ">=6.9.0" + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" } }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", - "dev": true, + "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==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "@emotion/memoize": "^0.8.1" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", - "dev": true, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" + "react": ">=16.8.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dev": true, + "node_modules/@emotion/serialize": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" - }, - "engines": { - "node": ">=6.9.0" - } + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, - "node_modules/@babel/helpers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", - "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" }, - "node_modules/@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", - "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", - "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.24.1" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", - "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@floating-ui/utils": "^0.2.1" } }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, + "node_modules/@floating-ui/react": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", + "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@floating-ui/react-dom": "^1.3.0", + "aria-hidden": "^1.1.3", + "tabbable": "^6.0.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" + "@floating-ui/dom": "^1.6.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, + "node_modules/@floating-ui/react/node_modules/@floating-ui/react-dom": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", + "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@floating-ui/dom": "^1.2.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.1.tgz", - "integrity": "sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==", - "dev": true, + "node_modules/@grpc/grpc-js": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.4.tgz", + "integrity": "sha512-MqBisuxTkYvPFnEiu+dag3xG/NBUDzSbAFAWlzfkGnQkjVZ6by3h4atbBc+Ikqup1z5BfB4BN18gKWR1YyppNw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@grpc/proto-loader": "^0.7.10", + "@js-sdsl/ordered-map": "^4.4.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=12.10.0" } }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", - "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", - "dev": true, + "node_modules/@grpc/proto-loader": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.11.tgz", + "integrity": "sha512-amjhSfJ+xYnTP+hncJMmkchoRtjIdi+uO3FaymGSCr07yu5xfpXFEnhZkTU1mj2lPJB3oVToau7j9YkqB+YNdg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" }, - "engines": { - "node": ">=6.9.0" + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6" } }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", - "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", - "dev": true, + "node_modules/@headlessui/react": { + "version": "1.7.18", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.18.tgz", + "integrity": "sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@tanstack/react-virtual": "^3.0.0-beta.60", + "client-only": "^0.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=10" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "node_modules/@headlessui/tailwindcss": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@headlessui/tailwindcss/-/tailwindcss-0.2.0.tgz", + "integrity": "sha512-fpL830Fln1SykOCboExsWr3JIVeQKieLJ3XytLe/tt1A0XzqUthOftDmjcCYLW62w7mQI7wXcoPXr3tZ9QfGxw==", + "engines": { + "node": ">=10" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "tailwindcss": "^3.0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=10.10.0" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", - "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, "engines": { - "node": ">=6.9.0" + "node": ">=12.22" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=12" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=12" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=12" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", - "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", - "dev": true, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", - "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", - "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", - "dev": true, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", - "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz", - "integrity": "sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==", - "dev": true, + "node_modules/@monaco-editor/loader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", + "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "state-local": "^1.0.6" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "monaco-editor": ">= 0.21.0 < 1" } }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", - "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", - "dev": true, + "node_modules/@monaco-editor/react": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", + "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@monaco-editor/loader": "^1.4.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz", - "integrity": "sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==", + "node_modules/@next/env": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.4.tgz", + "integrity": "sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ==" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.4.tgz", + "integrity": "sha512-n4zYNLSyCo0Ln5b7qxqQeQ34OZKXwgbdcx6kmkQbywr+0k6M3Vinft0T72R6CDAcDrne2IAgSud4uWCzFgc5HA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" + "glob": "10.3.10" } }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", - "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" - }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.4.tgz", + "integrity": "sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", - "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/template": "^7.24.0" - }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.4.tgz", + "integrity": "sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", - "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.4.tgz", + "integrity": "sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", - "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.4.tgz", + "integrity": "sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", - "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.4.tgz", + "integrity": "sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", - "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.4.tgz", + "integrity": "sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", - "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.4.tgz", + "integrity": "sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", - "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.4.tgz", + "integrity": "sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.1.tgz", - "integrity": "sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-flow": "^7.24.1" - }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.4.tgz", + "integrity": "sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 10" } }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", - "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", - "dev": true, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 8" } }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", - "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0" - }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 8" } }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", - "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", - "dev": true, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 8" } }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", - "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/@panva/hkdf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz", + "integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==", + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", - "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=14" } }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", - "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, + "node_modules/@prisma/client": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.11.0.tgz", + "integrity": "sha512-SWshvS5FDXvgJKM/a0y9nDC1rqd7KG0Q6ZVzd+U7ZXK5soe73DJxJJgbNBt2GNXOa+ysWB4suTpdK5zfFPhwiw==", + "hasInstallScript": true, "engines": { - "node": ">=6.9.0" + "node": ">=16.13" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", - "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "prisma": "*" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "prisma": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "node_modules/@prisma/debug": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.11.0.tgz", + "integrity": "sha512-N6yYr3AbQqaiUg+OgjkdPp3KPW1vMTAgtKX6+BiB/qB2i1TjLYCrweKcUjzOoRM5BriA4idrkTej9A9QqTfl3A==", + "devOptional": true }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", - "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", - "dev": true, + "node_modules/@prisma/engines": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.11.0.tgz", + "integrity": "sha512-gbrpQoBTYWXDRqD+iTYMirDlF9MMlQdxskQXbhARhG6A/uFQjB7DZMYocMQLoiZXO/IskfDOZpPoZE8TBQKtEw==", + "devOptional": true, + "hasInstallScript": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@prisma/debug": "5.11.0", + "@prisma/engines-version": "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102", + "@prisma/fetch-engine": "5.11.0", + "@prisma/get-platform": "5.11.0" } }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", - "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "node_modules/@prisma/engines-version": { + "version": "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102.tgz", + "integrity": "sha512-WXCuyoymvrS4zLz4wQagSsc3/nE6CHy8znyiMv8RKazKymOMd5o9FP5RGwGHAtgoxd+aB/BWqxuP/Ckfu7/3MA==", + "devOptional": true }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "dev": true, + "node_modules/@prisma/fetch-engine": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.11.0.tgz", + "integrity": "sha512-994viazmHTJ1ymzvWugXod7dZ42T2ROeFuH6zHPcUfp/69+6cl5r9u3NFb6bW8lLdNjwLYEVPeu3hWzxpZeC0w==", + "devOptional": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "@prisma/debug": "5.11.0", + "@prisma/engines-version": "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102", + "@prisma/get-platform": "5.11.0" } }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", - "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", - "dev": true, + "node_modules/@prisma/get-platform": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.11.0.tgz", + "integrity": "sha512-rxtHpMLxNTHxqWuGOLzR2QOyQi79rK1u1XYAVLZxDGTLz/A+uoDnjz9veBFlicrpWjwuieM4N6jcnjj/DDoidw==", + "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@prisma/debug": "5.11.0" } }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", - "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", - "dev": true, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" } }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", - "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", - "dev": true, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/runtime": "^7.13.10" } }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", - "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", - "dev": true, + "node_modules/@radix-ui/react-arrow": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz", + "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==", "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", - "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", - "dev": true, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz", + "integrity": "sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", - "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", - "dev": true, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz", + "integrity": "sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", - "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", - "dev": true, + "node_modules/@radix-ui/react-collection": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz", + "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", - "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", - "dev": true, + "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/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", - "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", - "dev": true, + "node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", - "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", - "dev": true, + "node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", - "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", - "dev": true, + "node_modules/@radix-ui/react-direction": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz", + "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz", - "integrity": "sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", - "dev": true, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/types": "^7.23.4" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", - "dev": true, - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz", - "integrity": "sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==", - "dev": true, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz", + "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-menu": "2.0.6", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", - "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", - "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", - "dev": true, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz", - "integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-plugin-utils": "^7.24.0", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", - "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", - "dev": true, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", + "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", - "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", - "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", - "dev": true, + "node_modules/@radix-ui/react-form": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.0.3.tgz", + "integrity": "sha512-kgE+Z/haV6fxE5WqIXj05KkaXa3OkZASoTDy25yX2EIp/x0c54rOH/vFr5nOZTg7n7T1z8bSyXmiVIFP9bbhPQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-label": "2.0.2", + "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", - "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", - "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, + "node_modules/@radix-ui/react-icons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", + "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==", "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": "^16.x || ^17.x || ^18.x" } }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.1.tgz", - "integrity": "sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w==", - "dev": true, + "node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-typescript": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", - "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", - "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", - "dev": true, + "node_modules/@radix-ui/react-label": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.0.2.tgz", + "integrity": "sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", - "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", - "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", - "dev": true, + "node_modules/@radix-ui/react-menu": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz", + "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" }, "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.3.tgz", - "integrity": "sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.1", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.1", - "@babel/plugin-transform-classes": "^7.24.1", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.1", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.1", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.1", - "@babel/plugin-transform-parameters": "^7.24.1", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.1", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.1", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/preset-flow": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.1.tgz", - "integrity": "sha512-sWCV2G9pcqZf+JHyv/RyqEIpFypxdCSxWIxQjpdaQxenNog7cN1pr76hg8u0Fz8Qgg0H4ETkGcJnXL8d4j0PPA==", - "dev": true, + "node_modules/@radix-ui/react-popover": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz", + "integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-transform-flow-strip-types": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dev": true, + "node_modules/@radix-ui/react-popper": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz", + "integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==", "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-rect": "1.0.1", + "@radix-ui/react-use-size": "1.0.1", + "@radix-ui/rect": "1.0.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/preset-react": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.1.tgz", - "integrity": "sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==", - "dev": true, + "node_modules/@radix-ui/react-portal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", + "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-transform-react-display-name": "^7.24.1", - "@babel/plugin-transform-react-jsx": "^7.23.4", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/preset-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz", - "integrity": "sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==", - "dev": true, + "node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-syntax-jsx": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-typescript": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/register": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.23.7.tgz", - "integrity": "sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==", - "dev": true, + "node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", "dependencies": { - "clone-deep": "^4.0.1", - "find-cache-dir": "^2.0.0", - "make-dir": "^2.1.0", - "pirates": "^4.0.6", - "source-map-support": "^0.5.16" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/register/node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "engines": { - "node": ">=6" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/register/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, + "node_modules/@radix-ui/react-progress": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.0.3.tgz", + "integrity": "sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag==", "dependencies": { - "locate-path": "^3.0.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3" }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/register/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "engines": { - "node": ">=6" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/register/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz", + "integrity": "sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==", "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/register/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@babel/register/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/register/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/register/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/register/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", + "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", "dependencies": { - "find-up": "^3.0.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1" }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/register/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, - "node_modules/@babel/runtime": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", - "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", - "dependencies": { - "regenerator-runtime": "^0.14.0" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", - "dev": true, + "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==", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", - "debug": "^4.3.1", - "globals": "^11.1.0" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "node_modules/@radix-ui/react-switch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.0.3.tgz", + "integrity": "sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@base2/pretty-print-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz", - "integrity": "sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==", - "dev": true - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@emotion/babel-plugin": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", - "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/serialize": "^1.1.2", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", - "dependencies": { - "@emotion/memoize": "^0.8.1", - "@emotion/sheet": "^1.2.2", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "stylis": "4.2.0" - } - }, - "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==" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", - "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", - "dependencies": { - "@emotion/memoize": "^0.8.1" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" - }, - "node_modules/@emotion/react": { - "version": "11.11.4", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", - "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "node_modules/@radix-ui/react-tabs": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz", + "integrity": "sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==", "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.3", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "hoist-non-react-statics": "^3.3.1" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1" }, "peerDependencies": { - "react": ">=16.8.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@emotion/serialize": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", - "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", - "dependencies": { - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/unitless": "^0.8.1", - "@emotion/utils": "^1.2.1", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" - }, - "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@fal-works/esbuild-plugin-global-externals": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz", - "integrity": "sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==", - "dev": true - }, - "node_modules/@floating-ui/core": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", - "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", - "dependencies": { - "@floating-ui/utils": "^0.2.1" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", - "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", - "dependencies": { - "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.0" - } - }, - "node_modules/@floating-ui/react": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", - "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", - "dependencies": { - "@floating-ui/react-dom": "^1.3.0", - "aria-hidden": "^1.1.3", - "tabbable": "^6.0.1" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", - "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", - "dependencies": { - "@floating-ui/dom": "^1.6.1" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/react/node_modules/@floating-ui/react-dom": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", - "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", - "dependencies": { - "@floating-ui/dom": "^1.2.1" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", - "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" - }, - "node_modules/@grpc/grpc-js": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.3.tgz", - "integrity": "sha512-qiO9MNgYnwbvZ8MK0YLWbnGrNX3zTcj6/Ef7UHu5ZofER3e2nF3Y35GaPo9qNJJ/UJQKa4KL+z/F4Q8Q+uCdUQ==", - "dependencies": { - "@grpc/proto-loader": "^0.7.10", - "@js-sdsl/ordered-map": "^4.4.2" - }, - "engines": { - "node": ">=12.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", - "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.4", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@headlessui/react": { - "version": "1.7.18", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.18.tgz", - "integrity": "sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ==", - "dependencies": { - "@tanstack/react-virtual": "^3.0.0-beta.60", - "client-only": "^0.0.1" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": "^16 || ^17 || ^18", - "react-dom": "^16 || ^17 || ^18" - } - }, - "node_modules/@headlessui/tailwindcss": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@headlessui/tailwindcss/-/tailwindcss-0.2.0.tgz", - "integrity": "sha512-fpL830Fln1SykOCboExsWr3JIVeQKieLJ3XytLe/tt1A0XzqUthOftDmjcCYLW62w7mQI7wXcoPXr3tZ9QfGxw==", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "tailwindcss": "^3.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/@juggle/resize-observer": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", - "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==", - "dev": true - }, - "node_modules/@mdx-js/react": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", - "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", - "dev": true, - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "node_modules/@monaco-editor/loader": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", - "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", - "dependencies": { - "state-local": "^1.0.6" - }, - "peerDependencies": { - "monaco-editor": ">= 0.21.0 < 1" - } - }, - "node_modules/@monaco-editor/react": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", - "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", - "dependencies": { - "@monaco-editor/loader": "^1.4.0" - }, - "peerDependencies": { - "monaco-editor": ">= 0.25.0 < 1", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@ndelangen/get-tarball": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@ndelangen/get-tarball/-/get-tarball-3.0.9.tgz", - "integrity": "sha512-9JKTEik4vq+yGosHYhZ1tiH/3WpUS0Nh0kej4Agndhox8pAdWhEx5knFVRcb/ya9knCRCs1rPxNrSXTDdfVqpA==", - "dev": true, - "dependencies": { - "gunzip-maybe": "^1.4.2", - "pump": "^3.0.0", - "tar-fs": "^2.1.1" - } - }, - "node_modules/@ndelangen/get-tarball/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/@ndelangen/get-tarball/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@ndelangen/get-tarball/node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/@ndelangen/get-tarball/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@next/env": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.4.tgz", - "integrity": "sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ==" - }, - "node_modules/@next/eslint-plugin-next": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.4.tgz", - "integrity": "sha512-n4zYNLSyCo0Ln5b7qxqQeQ34OZKXwgbdcx6kmkQbywr+0k6M3Vinft0T72R6CDAcDrne2IAgSud4uWCzFgc5HA==", - "dev": true, - "dependencies": { - "glob": "10.3.10" - } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.4.tgz", - "integrity": "sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.4.tgz", - "integrity": "sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.4.tgz", - "integrity": "sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.4.tgz", - "integrity": "sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.4.tgz", - "integrity": "sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.4.tgz", - "integrity": "sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.4.tgz", - "integrity": "sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.4.tgz", - "integrity": "sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.4.tgz", - "integrity": "sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@panva/hkdf": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz", - "integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz", - "integrity": "sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==", - "dev": true, - "dependencies": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.23.3", - "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.4", - "schema-utils": "^3.0.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">= 10.13" - }, - "peerDependencies": { - "@types/webpack": "4.x || 5.x", - "react-refresh": ">=0.10.0 <1.0.0", - "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <5.0.0", - "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "0.x || 1.x" - }, - "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { - "optional": true - } - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/@prisma/client": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.11.0.tgz", - "integrity": "sha512-SWshvS5FDXvgJKM/a0y9nDC1rqd7KG0Q6ZVzd+U7ZXK5soe73DJxJJgbNBt2GNXOa+ysWB4suTpdK5zfFPhwiw==", - "hasInstallScript": true, - "engines": { - "node": ">=16.13" - }, - "peerDependencies": { - "prisma": "*" - }, - "peerDependenciesMeta": { - "prisma": { - "optional": true - } - } - }, - "node_modules/@prisma/debug": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.11.0.tgz", - "integrity": "sha512-N6yYr3AbQqaiUg+OgjkdPp3KPW1vMTAgtKX6+BiB/qB2i1TjLYCrweKcUjzOoRM5BriA4idrkTej9A9QqTfl3A==", - "devOptional": true - }, - "node_modules/@prisma/engines": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.11.0.tgz", - "integrity": "sha512-gbrpQoBTYWXDRqD+iTYMirDlF9MMlQdxskQXbhARhG6A/uFQjB7DZMYocMQLoiZXO/IskfDOZpPoZE8TBQKtEw==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "@prisma/debug": "5.11.0", - "@prisma/engines-version": "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102", - "@prisma/fetch-engine": "5.11.0", - "@prisma/get-platform": "5.11.0" - } - }, - "node_modules/@prisma/engines-version": { - "version": "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102.tgz", - "integrity": "sha512-WXCuyoymvrS4zLz4wQagSsc3/nE6CHy8znyiMv8RKazKymOMd5o9FP5RGwGHAtgoxd+aB/BWqxuP/Ckfu7/3MA==", - "devOptional": true - }, - "node_modules/@prisma/fetch-engine": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.11.0.tgz", - "integrity": "sha512-994viazmHTJ1ymzvWugXod7dZ42T2ROeFuH6zHPcUfp/69+6cl5r9u3NFb6bW8lLdNjwLYEVPeu3hWzxpZeC0w==", - "devOptional": true, - "dependencies": { - "@prisma/debug": "5.11.0", - "@prisma/engines-version": "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102", - "@prisma/get-platform": "5.11.0" - } - }, - "node_modules/@prisma/get-platform": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.11.0.tgz", - "integrity": "sha512-rxtHpMLxNTHxqWuGOLzR2QOyQi79rK1u1XYAVLZxDGTLz/A+uoDnjz9veBFlicrpWjwuieM4N6jcnjj/DDoidw==", - "devOptional": true, - "dependencies": { - "@prisma/debug": "5.11.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@radix-ui/number": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", - "integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@radix-ui/primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", - "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz", - "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-checkbox": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz", - "integrity": "sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-previous": "1.0.1", - "@radix-ui/react-use-size": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collapsible": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz", - "integrity": "sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collection": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz", - "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "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" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-context": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", - "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", - "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.4", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-controllable-state": "1.0.1", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz", - "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", - "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-escape-keydown": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz", - "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-menu": "2.0.6", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", - "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", - "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-form": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.0.3.tgz", - "integrity": "sha512-kgE+Z/haV6fxE5WqIXj05KkaXa3OkZASoTDy25yX2EIp/x0c54rOH/vFr5nOZTg7n7T1z8bSyXmiVIFP9bbhPQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-label": "2.0.2", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-icons": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", - "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==", - "peerDependencies": { - "react": "^16.x || ^17.x || ^18.x" - } - }, - "node_modules/@radix-ui/react-id": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", - "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-label": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.0.2.tgz", - "integrity": "sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz", - "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.4", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.3", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-callback-ref": "1.0.1", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz", - "integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.4", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.3", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-controllable-state": "1.0.1", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popper": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz", - "integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-use-rect": "1.0.1", - "@radix-ui/react-use-size": "1.0.1", - "@radix-ui/rect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-portal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", - "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-presence": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", - "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", - "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-progress": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.0.3.tgz", - "integrity": "sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-radio-group": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz", - "integrity": "sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-previous": "1.0.1", - "@radix-ui/react-use-size": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", - "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-select": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-1.2.2.tgz", - "integrity": "sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/number": "1.0.1", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.4", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.3", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.2", - "@radix-ui/react-portal": "1.0.3", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-use-previous": "1.0.1", - "@radix-ui/react-visually-hidden": "1.0.3", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz", - "integrity": "sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-escape-keydown": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-scope": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.3.tgz", - "integrity": "sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-popper": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.2.tgz", - "integrity": "sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.10", - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-use-rect": "1.0.1", - "@radix-ui/react-use-size": "1.0.1", - "@radix-ui/rect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-portal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.3.tgz", - "integrity": "sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-separator": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.0.3.tgz", - "integrity": "sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "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==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-switch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.0.3.tgz", - "integrity": "sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-previous": "1.0.1", - "@radix-ui/react-use-size": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz", - "integrity": "sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toast": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.1.5.tgz", - "integrity": "sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-visually-hidden": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz", - "integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle-group": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz", - "integrity": "sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-toggle": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toolbar": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.0.4.tgz", - "integrity": "sha512-tBgmM/O7a07xbaEkYJWYTXkIdU/1pW4/KZORR43toC/4XWyBCURK0ei9kMUdp+gTPPKBgYLxXmRSH1EVcIDp8Q==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-separator": "1.0.3", - "@radix-ui/react-toggle-group": "1.0.4" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", - "integrity": "sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.3", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-visually-hidden": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", - "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", - "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", - "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", - "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-previous": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", - "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-rect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", - "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/rect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-size": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz", - "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz", - "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/rect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", - "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.8.0.tgz", - "integrity": "sha512-0HejFckBN2W+ucM6cUOlwsByTKt9/+0tWhqUffNIcHqCXkthY/mZ7AuYPK/2IIaGWhdl0h+tICDO0ssLMd6XMQ==", - "dev": true - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@storybook/addon-actions": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.0.4.tgz", - "integrity": "sha512-EyCWo+8T11/TJGYNL/AXtW4yaB+q1v2E9mixbumryCLxpTl2NtaeGZ4e0dlwfIMuw/7RWgHk2uIypcIPR/UANQ==", - "dev": true, - "dependencies": { - "@storybook/core-events": "8.0.4", - "@storybook/global": "^5.0.0", - "@types/uuid": "^9.0.1", - "dequal": "^2.0.2", - "polished": "^4.2.2", - "uuid": "^9.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-backgrounds": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.0.4.tgz", - "integrity": "sha512-fef0KD2GhJx2zpicOf8iL7k2LiIsNzEbGaQpIIjoy4DMqM1hIfNCt3DGTLH7LN5O8G+NVCLS1xmQg7RLvIVSCA==", - "dev": true, - "dependencies": { - "@storybook/global": "^5.0.0", - "memoizerific": "^1.11.3", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-controls": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.0.4.tgz", - "integrity": "sha512-K5EYBTsUOTJlvIdA7p6Xj31wnV+RbZAkk56UKQvA7nJD7oDuLOq3E9u46F/uZD1vxddd9zFhf2iONfMe3KTTwQ==", - "dev": true, - "dependencies": { - "@storybook/blocks": "8.0.4", - "lodash": "^4.17.21", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-docs": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.0.4.tgz", - "integrity": "sha512-m0Y7qGAMnNPLEOEgzW/SBm8GX0xabJBaRN+aYijO6UKTln7F6oXXVve+xPC0Y4s6Gc9HZFdJY8WXZr1YSGEUVA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.0.4", - "@storybook/client-logger": "8.0.4", - "@storybook/components": "8.0.4", - "@storybook/csf-plugin": "8.0.4", - "@storybook/csf-tools": "8.0.4", - "@storybook/global": "^5.0.0", - "@storybook/node-logger": "8.0.4", - "@storybook/preview-api": "8.0.4", - "@storybook/react-dom-shim": "8.0.4", - "@storybook/theming": "8.0.4", - "@storybook/types": "8.0.4", - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "fs-extra": "^11.1.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "rehype-external-links": "^3.0.0", - "rehype-slug": "^6.0.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-essentials": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.0.4.tgz", - "integrity": "sha512-mUIqhAkSz6Qv7nRqAAyCqMLiXBWVsY/8qN7HEIoaMQgdFq38KW3rYwNdzd2JLeXNWP1bBXwfvfcFe7/eqhYJFA==", - "dev": true, - "dependencies": { - "@storybook/addon-actions": "8.0.4", - "@storybook/addon-backgrounds": "8.0.4", - "@storybook/addon-controls": "8.0.4", - "@storybook/addon-docs": "8.0.4", - "@storybook/addon-highlight": "8.0.4", - "@storybook/addon-measure": "8.0.4", - "@storybook/addon-outline": "8.0.4", - "@storybook/addon-toolbars": "8.0.4", - "@storybook/addon-viewport": "8.0.4", - "@storybook/core-common": "8.0.4", - "@storybook/manager-api": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/preview-api": "8.0.4", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-highlight": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.0.4.tgz", - "integrity": "sha512-tnEiVaJlXL07v8JBox+QtRPVruoy0YovOTAOWY7fKDiKzF1I9wLaJjQF3wOsvwspHTHu00OZw2gsazgXiH4wLQ==", - "dev": true, - "dependencies": { - "@storybook/global": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-interactions": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.0.4.tgz", - "integrity": "sha512-wTEOnVUbF1lNJxxocr5IKmpgnmwyO8YsQf6Baw3tTWCHAa/MaWWQYq1OA6CfFfmVGGRjv/w2GTuf1Vyq99O7mg==", - "dev": true, - "dependencies": { - "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.0.4", - "@storybook/test": "8.0.4", - "@storybook/types": "8.0.4", - "polished": "^4.2.2", - "ts-dedent": "^2.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-links": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.0.4.tgz", - "integrity": "sha512-SzE+JPZ4mxjprZqbLHf8Hx7UA2fXfMajFjeY9c3JREKQrDoOF1e4r28nAoVsZYF+frWxQB51U4+hOqjlx06wEA==", - "dev": true, - "dependencies": { - "@storybook/csf": "^0.1.2", - "@storybook/global": "^5.0.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-measure": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.0.4.tgz", - "integrity": "sha512-GZYKo2ss5Br+dfHinoK3bgTaS90z3oKKDkhv6lrFfjjU1mDYzzMJpxajQhd3apCYxHLr3MbUqMQibWu2T/q2DQ==", - "dev": true, - "dependencies": { - "@storybook/global": "^5.0.0", - "tiny-invariant": "^1.3.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-outline": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.0.4.tgz", - "integrity": "sha512-6J9ezNDUxdA3rMCh8sUEQbUwAgkrr+M9QdiFr1t+gKrk5FKP5gwubw1sr3sF1IRB9+s/AjljcOtJAVulSfq05w==", - "dev": true, - "dependencies": { - "@storybook/global": "^5.0.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-styling/-/addon-styling-1.3.7.tgz", - "integrity": "sha512-JSBZMOrSw/3rlq5YoEI7Qyq703KSNP0Jd+gxTWu3/tP6245mpjn2dXnR8FvqVxCi+FG4lt2kQyPzgsuwEw1SSA==", - "deprecated": "This package has been split into @storybook/addon-styling-webpack and @storybook/addon-themes. More info: https://github.com/storybookjs/addon-styling", - "dev": true, - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.5", - "@storybook/api": "^7.0.12", - "@storybook/components": "^7.0.12", - "@storybook/core-common": "^7.0.12", - "@storybook/core-events": "^7.0.12", - "@storybook/manager-api": "^7.0.12", - "@storybook/node-logger": "^7.0.12", - "@storybook/preview-api": "^7.0.12", - "@storybook/theming": "^7.0.12", - "@storybook/types": "^7.0.12", - "css-loader": "^6.7.3", - "less-loader": "^11.1.0", - "postcss-loader": "^7.2.4", - "prettier": "^2.8.0", - "resolve-url-loader": "^5.0.0", - "sass-loader": "^13.2.2", - "style-loader": "^3.3.2" - }, - "bin": { - "addon-styling-setup": "postinstall.js" - }, - "peerDependencies": { - "less": "^3.5.0 || ^4.0.0", - "postcss": "^7.0.0 || ^8.0.1", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "less": { - "optional": true - }, - "postcss": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/channels": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", - "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "7.6.17", - "@storybook/core-events": "7.6.17", - "@storybook/global": "^5.0.0", - "qs": "^6.10.0", - "telejson": "^7.2.0", - "tiny-invariant": "^1.3.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/client-logger": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", - "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", - "dev": true, - "dependencies": { - "@storybook/global": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/components": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.6.17.tgz", - "integrity": "sha512-lbh7GynMidA+CZcJnstVku6Nhs+YkqjYaZ+mKPugvlVhGVWv0DaaeQFVuZ8cJtUGJ/5FFU4Y+n+gylYUHkGBMA==", - "dev": true, - "dependencies": { - "@radix-ui/react-select": "^1.2.2", - "@radix-ui/react-toolbar": "^1.0.4", - "@storybook/client-logger": "7.6.17", - "@storybook/csf": "^0.1.2", - "@storybook/global": "^5.0.0", - "@storybook/theming": "7.6.17", - "@storybook/types": "7.6.17", - "memoizerific": "^1.11.3", - "use-resize-observer": "^9.1.0", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/core-common": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.17.tgz", - "integrity": "sha512-me2TP3Q9/qzqCLoDHUSsUF+VS1MHxfHbTVF6vAz0D/COTxzsxLpu9TxTbzJoBCxse6XRb6wWI1RgF1mIcjic7g==", - "dev": true, - "dependencies": { - "@storybook/core-events": "7.6.17", - "@storybook/node-logger": "7.6.17", - "@storybook/types": "7.6.17", - "@types/find-cache-dir": "^3.2.1", - "@types/node": "^18.0.0", - "@types/node-fetch": "^2.6.4", - "@types/pretty-hrtime": "^1.0.0", - "chalk": "^4.1.0", - "esbuild": "^0.18.0", - "esbuild-register": "^3.5.0", - "file-system-cache": "2.3.0", - "find-cache-dir": "^3.0.0", - "find-up": "^5.0.0", - "fs-extra": "^11.1.0", - "glob": "^10.0.0", - "handlebars": "^4.7.7", - "lazy-universal-dotenv": "^4.0.0", - "node-fetch": "^2.0.0", - "picomatch": "^2.3.0", - "pkg-dir": "^5.0.0", - "pretty-hrtime": "^1.0.3", - "resolve-from": "^5.0.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/core-events": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", - "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", - "dev": true, - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/manager-api": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.6.17.tgz", - "integrity": "sha512-IJIV1Yc6yw1dhCY4tReHCfBnUKDqEBnMyHp3mbXpsaHxnxJZrXO45WjRAZIKlQKhl/Ge1CrnznmHRCmYgqmrWg==", - "dev": true, - "dependencies": { - "@storybook/channels": "7.6.17", - "@storybook/client-logger": "7.6.17", - "@storybook/core-events": "7.6.17", - "@storybook/csf": "^0.1.2", - "@storybook/global": "^5.0.0", - "@storybook/router": "7.6.17", - "@storybook/theming": "7.6.17", - "@storybook/types": "7.6.17", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "store2": "^2.14.2", - "telejson": "^7.2.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/node-logger": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.17.tgz", - "integrity": "sha512-w59MQuXhhUNrUVmVkXhMwIg2nvFWjdDczLTwYLorhfsE36CWeUOY5QCZWQy0Qf/h+jz8Uo7Evy64qn18v9C4wA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/preview-api": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.17.tgz", - "integrity": "sha512-wLfDdI9RWo1f2zzFe54yRhg+2YWyxLZvqdZnSQ45mTs4/7xXV5Wfbv3QNTtcdw8tT3U5KRTrN1mTfTCiRJc0Kw==", - "dev": true, - "dependencies": { - "@storybook/channels": "7.6.17", - "@storybook/client-logger": "7.6.17", - "@storybook/core-events": "7.6.17", - "@storybook/csf": "^0.1.2", - "@storybook/global": "^5.0.0", - "@storybook/types": "7.6.17", - "@types/qs": "^6.9.5", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "qs": "^6.10.0", - "synchronous-promise": "^2.0.15", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/router": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.6.17.tgz", - "integrity": "sha512-GnyC0j6Wi5hT4qRhSyT8NPtJfGmf82uZw97LQRWeyYu5gWEshUdM7aj40XlNiScd5cZDp0owO1idduVF2k2l2A==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "7.6.17", - "memoizerific": "^1.11.3", - "qs": "^6.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/theming": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.17.tgz", - "integrity": "sha512-ZbaBt3KAbmBtfjNqgMY7wPMBshhSJlhodyMNQypv+95xLD/R+Az6aBYbpVAOygLaUQaQk4ar7H/Ww6lFIoiFbA==", - "dev": true, - "dependencies": { - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.6.17", - "@storybook/global": "^5.0.0", - "memoizerific": "^1.11.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@storybook/types": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", - "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", - "dev": true, - "dependencies": { - "@storybook/channels": "7.6.17", - "@types/babel__core": "^7.0.0", - "@types/express": "^4.7.0", - "file-system-cache": "2.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-styling/node_modules/@types/node": { - "version": "18.19.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", - "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@storybook/addon-styling/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@storybook/addon-styling/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@storybook/addon-styling/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, - "node_modules/@storybook/addon-styling/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/addon-styling/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/@storybook/addon-styling/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/addon-toolbars": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.0.4.tgz", - "integrity": "sha512-yodRXDYog/90cNEy84kg6s7L+nxQ+egBjHBTsav1L4cJmQI/uAX8yISHHiX4I5ppNc120Jz3UdHdRxXRlo345g==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-viewport": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.0.4.tgz", - "integrity": "sha512-E5IKOsxKcOtlOYc0cWgzVJohQB+dVBWwaJcg5FlslToknfVB9M0kfQ/SQcp3KB0C9/cOmJK1Jm388InW+EjrBQ==", - "dev": true, - "dependencies": { - "memoizerific": "^1.11.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-7.6.17.tgz", - "integrity": "sha512-l92PI+5XL4zB/o4IBWFCKQWTXvPg9hR45DCJqlPHrLZStiR6Xj1mbrtOjUlgIOH+nYb/SZFZqO53hhrs7X4Nvg==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "7.6.17", - "@storybook/manager-api": "7.6.17" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/channels": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.17.tgz", - "integrity": "sha512-GFG40pzaSxk1hUr/J/TMqW5AFDDPUSu+HkeE/oqSWJbOodBOLJzHN6CReJS6y1DjYSZLNFt1jftPWZZInG/XUA==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "7.6.17", - "@storybook/core-events": "7.6.17", - "@storybook/global": "^5.0.0", - "qs": "^6.10.0", - "telejson": "^7.2.0", - "tiny-invariant": "^1.3.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/client-logger": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.17.tgz", - "integrity": "sha512-6WBYqixAXNAXlSaBWwgljWpAu10tPRBJrcFvx2gPUne58EeMM20Gi/iHYBz2kMCY+JLAgeIH7ZxInqwO8vDwiQ==", - "dev": true, - "dependencies": { - "@storybook/global": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/core-events": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.17.tgz", - "integrity": "sha512-AriWMCm/k1cxlv10f+jZ1wavThTRpLaN3kY019kHWbYT9XgaSuLU67G7GPr3cGnJ6HuA6uhbzu8qtqVCd6OfXA==", - "dev": true, - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/manager-api": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.6.17.tgz", - "integrity": "sha512-IJIV1Yc6yw1dhCY4tReHCfBnUKDqEBnMyHp3mbXpsaHxnxJZrXO45WjRAZIKlQKhl/Ge1CrnznmHRCmYgqmrWg==", - "dev": true, - "dependencies": { - "@storybook/channels": "7.6.17", - "@storybook/client-logger": "7.6.17", - "@storybook/core-events": "7.6.17", - "@storybook/csf": "^0.1.2", - "@storybook/global": "^5.0.0", - "@storybook/router": "7.6.17", - "@storybook/theming": "7.6.17", - "@storybook/types": "7.6.17", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "store2": "^2.14.2", - "telejson": "^7.2.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/router": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.6.17.tgz", - "integrity": "sha512-GnyC0j6Wi5hT4qRhSyT8NPtJfGmf82uZw97LQRWeyYu5gWEshUdM7aj40XlNiScd5cZDp0owO1idduVF2k2l2A==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "7.6.17", - "memoizerific": "^1.11.3", - "qs": "^6.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/theming": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.6.17.tgz", - "integrity": "sha512-ZbaBt3KAbmBtfjNqgMY7wPMBshhSJlhodyMNQypv+95xLD/R+Az6aBYbpVAOygLaUQaQk4ar7H/Ww6lFIoiFbA==", - "dev": true, - "dependencies": { - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.6.17", - "@storybook/global": "^5.0.0", - "memoizerific": "^1.11.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/types": { - "version": "7.6.17", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.17.tgz", - "integrity": "sha512-GRY0xEJQ0PrL7DY2qCNUdIfUOE0Gsue6N+GBJw9ku1IUDFLJRDOF+4Dx2BvYcVCPI5XPqdWKlEyZdMdKjiQN7Q==", - "dev": true, - "dependencies": { - "@storybook/channels": "7.6.17", - "@types/babel__core": "^7.0.0", - "@types/express": "^4.7.0", - "file-system-cache": "2.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/blocks": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.0.4.tgz", - "integrity": "sha512-9dRXk9zLJVPOmEWsSXm10XUmIfvS/tVgeBgFXNbusFQZXPpexIPNdRgB004pDGg9RvlY78ykpnd3yP143zaXMg==", - "dev": true, - "dependencies": { - "@storybook/channels": "8.0.4", - "@storybook/client-logger": "8.0.4", - "@storybook/components": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/csf": "^0.1.2", - "@storybook/docs-tools": "8.0.4", - "@storybook/global": "^5.0.0", - "@storybook/icons": "^1.2.5", - "@storybook/manager-api": "8.0.4", - "@storybook/preview-api": "8.0.4", - "@storybook/theming": "8.0.4", - "@storybook/types": "8.0.4", - "@types/lodash": "^4.14.167", - "color-convert": "^2.0.1", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "markdown-to-jsx": "7.3.2", - "memoizerific": "^1.11.3", - "polished": "^4.2.2", - "react-colorful": "^5.1.2", - "telejson": "^7.2.0", - "tocbot": "^4.20.1", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@storybook/builder-manager": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-8.0.4.tgz", - "integrity": "sha512-BafYVxq77uuTmXdjYo5by42OyOrb6qcpWYKva3ntWK2ZhTaLJlwwqAOdahT1DVzi4VeUP6465YvsTCzIE8fuIw==", - "dev": true, - "dependencies": { - "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@storybook/core-common": "8.0.4", - "@storybook/manager": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@types/ejs": "^3.1.1", - "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", - "browser-assert": "^1.2.1", - "ejs": "^3.1.8", - "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0", - "esbuild-plugin-alias": "^0.2.1", - "express": "^4.17.3", - "fs-extra": "^11.1.0", - "process": "^0.11.10", - "util": "^0.12.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/builder-webpack5": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.0.4.tgz", - "integrity": "sha512-FKXIGfDjZJ7KCq6w8e3NEp2+KATsh4U24UV/K8cFjCrRIU++jDpO274D9ozdpzEmhvHOfxK/QlgalqS4G599Aw==", - "dev": true, - "dependencies": { - "@storybook/channels": "8.0.4", - "@storybook/client-logger": "8.0.4", - "@storybook/core-common": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/core-webpack": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/preview": "8.0.4", - "@storybook/preview-api": "8.0.4", - "@types/node": "^18.0.0", - "@types/semver": "^7.3.4", - "browser-assert": "^1.2.1", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "cjs-module-lexer": "^1.2.3", - "constants-browserify": "^1.0.0", - "css-loader": "^6.7.1", - "es-module-lexer": "^1.4.1", - "express": "^4.17.3", - "fork-ts-checker-webpack-plugin": "^8.0.0", - "fs-extra": "^11.1.0", - "html-webpack-plugin": "^5.5.0", - "magic-string": "^0.30.5", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "semver": "^7.3.7", - "style-loader": "^3.3.1", - "terser-webpack-plugin": "^5.3.1", - "ts-dedent": "^2.0.0", - "url": "^0.11.0", - "util": "^0.12.4", - "util-deprecate": "^1.0.2", - "webpack": "5", - "webpack-dev-middleware": "^6.1.1", - "webpack-hot-middleware": "^2.25.1", - "webpack-virtual-modules": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { - "version": "18.19.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", - "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@storybook/channels": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-8.0.4.tgz", - "integrity": "sha512-haKV+8RbiSzLjicowUfc7h2fTClZHX/nz9SRUecf4IEZUEu2T78OgM/TzqZvL7rA3+/fKqp5iI+3PN3OA75Sdg==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/global": "^5.0.0", - "telejson": "^7.2.0", - "tiny-invariant": "^1.3.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/cli": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-8.0.4.tgz", - "integrity": "sha512-8jb8hrulRMfyFyNXFEapxHBS51xb42ZZGfVAacXIsHOJtjOd5CnOoSUYn0aOkVl19VF/snoa9JOW7BaW/50Eqw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.23.0", - "@babel/types": "^7.23.0", - "@ndelangen/get-tarball": "^3.0.7", - "@storybook/codemod": "8.0.4", - "@storybook/core-common": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/core-server": "8.0.4", - "@storybook/csf-tools": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/telemetry": "8.0.4", - "@storybook/types": "8.0.4", - "@types/semver": "^7.3.4", - "@yarnpkg/fslib": "2.10.3", - "@yarnpkg/libzip": "2.3.0", - "chalk": "^4.1.0", - "commander": "^6.2.1", - "cross-spawn": "^7.0.3", - "detect-indent": "^6.1.0", - "envinfo": "^7.7.3", - "execa": "^5.0.0", - "find-up": "^5.0.0", - "fs-extra": "^11.1.0", - "get-npm-tarball-url": "^2.0.3", - "giget": "^1.0.0", - "globby": "^11.0.2", - "jscodeshift": "^0.15.1", - "leven": "^3.1.0", - "ora": "^5.4.1", - "prettier": "^3.1.1", - "prompts": "^2.4.0", - "read-pkg-up": "^7.0.1", - "semver": "^7.3.7", - "strip-json-comments": "^3.0.1", - "tempy": "^1.0.1", - "tiny-invariant": "^1.3.1", - "ts-dedent": "^2.0.0" - }, - "bin": { - "getstorybook": "bin/index.js", - "sb": "bin/index.js" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/cli/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@storybook/cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@storybook/cli/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@storybook/cli/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@storybook/cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/cli/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/cli/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/cli/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/cli/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@storybook/client-logger": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-8.0.4.tgz", - "integrity": "sha512-2SeEg3PT/d0l/+EAVtyj9hmMLTyTPp+bRBSzxYouBjtJPM1jrdKpFagj1o3uBRovwWm9SIVX6/ZsoRC33PEV1g==", - "dev": true, - "dependencies": { - "@storybook/global": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/codemod": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.0.4.tgz", - "integrity": "sha512-bysG46P4wjlR3RCpr/ntNAUaupWpzLcWYWti3iNtIyZ/iPrX6KtXoA9QCIwJZrlv41us6F+KEZbzLzkgWbymtQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.23.2", - "@babel/preset-env": "^7.23.2", - "@babel/types": "^7.23.0", - "@storybook/csf": "^0.1.2", - "@storybook/csf-tools": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/types": "8.0.4", - "@types/cross-spawn": "^6.0.2", - "cross-spawn": "^7.0.3", - "globby": "^11.0.2", - "jscodeshift": "^0.15.1", - "lodash": "^4.17.21", - "prettier": "^3.1.1", - "recast": "^0.23.5", - "tiny-invariant": "^1.3.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/codemod/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@storybook/codemod/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/components": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.0.4.tgz", - "integrity": "sha512-i5ngl5GTOLB9nZ1cmpxTjtWct5IuH9UxzFC73a0jHMkCwN26w16IqufRVDaoQv0AvZN4pd4fNM2in/XVHA10dw==", - "dev": true, - "dependencies": { - "@radix-ui/react-slot": "^1.0.2", - "@storybook/client-logger": "8.0.4", - "@storybook/csf": "^0.1.2", - "@storybook/global": "^5.0.0", - "@storybook/icons": "^1.2.5", - "@storybook/theming": "8.0.4", - "@storybook/types": "8.0.4", - "memoizerific": "^1.11.3", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/core-common": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-8.0.4.tgz", - "integrity": "sha512-dzFRLm5FxUa2EFE6Rx/KLDTJNLBIp1S2/+Q1K+rG8V+CLvewCc2Cd486rStZqSXEKI7vDnsRs/aMla+N0X/++Q==", - "dev": true, - "dependencies": { - "@storybook/core-events": "8.0.4", - "@storybook/csf-tools": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/types": "8.0.4", - "@yarnpkg/fslib": "2.10.3", - "@yarnpkg/libzip": "2.3.0", - "chalk": "^4.1.0", - "cross-spawn": "^7.0.3", - "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0", - "esbuild-register": "^3.5.0", - "execa": "^5.0.0", - "file-system-cache": "2.3.0", - "find-cache-dir": "^3.0.0", - "find-up": "^5.0.0", - "fs-extra": "^11.1.0", - "glob": "^10.0.0", - "handlebars": "^4.7.7", - "lazy-universal-dotenv": "^4.0.0", - "node-fetch": "^2.0.0", - "picomatch": "^2.3.0", - "pkg-dir": "^5.0.0", - "pretty-hrtime": "^1.0.3", - "resolve-from": "^5.0.0", - "semver": "^7.3.7", - "tempy": "^1.0.1", - "tiny-invariant": "^1.3.1", - "ts-dedent": "^2.0.0", - "util": "^0.12.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/core-common/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@storybook/core-common/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@storybook/core-common/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/core-common/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/core-common/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/core-common/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/core-common/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@storybook/core-events": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-8.0.4.tgz", - "integrity": "sha512-1FgLacIGi9i6/fyxw7ZJDC621RK47IMaA3keH4lc11ASRzCSwJ4YOrXjBFjfPc79EF2BuX72DDJNbhj6ynfF3g==", - "dev": true, - "dependencies": { - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/core-server": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-8.0.4.tgz", - "integrity": "sha512-/633Pp7LPcDWXkPLSW+W9VUYUbVkdVBG6peXjuzogV0vzdM0dM9af/T0uV2NQxUhzoy6/7QdSDljE+eEOBs2Lw==", - "dev": true, - "dependencies": { - "@aw-web-design/x-default-browser": "1.4.126", - "@babel/core": "^7.23.9", - "@discoveryjs/json-ext": "^0.5.3", - "@storybook/builder-manager": "8.0.4", - "@storybook/channels": "8.0.4", - "@storybook/core-common": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/csf": "^0.1.2", - "@storybook/csf-tools": "8.0.4", - "@storybook/docs-mdx": "3.0.0", - "@storybook/global": "^5.0.0", - "@storybook/manager": "8.0.4", - "@storybook/manager-api": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/preview-api": "8.0.4", - "@storybook/telemetry": "8.0.4", - "@storybook/types": "8.0.4", - "@types/detect-port": "^1.3.0", - "@types/node": "^18.0.0", - "@types/pretty-hrtime": "^1.0.0", - "@types/semver": "^7.3.4", - "better-opn": "^3.0.2", - "chalk": "^4.1.0", - "cli-table3": "^0.6.1", - "compression": "^1.7.4", - "detect-port": "^1.3.0", - "express": "^4.17.3", - "fs-extra": "^11.1.0", - "globby": "^11.0.2", - "ip": "^2.0.1", - "lodash": "^4.17.21", - "open": "^8.4.0", - "pretty-hrtime": "^1.0.3", - "prompts": "^2.4.0", - "read-pkg-up": "^7.0.1", - "semver": "^7.3.7", - "telejson": "^7.2.0", - "tiny-invariant": "^1.3.1", - "ts-dedent": "^2.0.0", - "util": "^0.12.4", - "util-deprecate": "^1.0.2", - "watchpack": "^2.2.0", - "ws": "^8.2.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/core-server/node_modules/@types/node": { - "version": "18.19.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", - "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@storybook/core-server/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@storybook/core-server/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@storybook/core-server/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@storybook/core-server/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/core-server/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/core-server/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/core-server/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/core-server/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/core-server/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@storybook/core-webpack": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.0.4.tgz", - "integrity": "sha512-sECeoJtT6iFWzgZaQbS1TEZvBrXIT4qb9fa0x2/I5YhCTPnprCNL1yyN90hFQTpdLco5vfQ86YnpzMRntODn7A==", - "dev": true, - "dependencies": { - "@storybook/core-common": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/types": "8.0.4", - "@types/node": "^18.0.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/core-webpack/node_modules/@types/node": { - "version": "18.19.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", - "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@storybook/csf": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.3.tgz", - "integrity": "sha512-IPZvXXo4b3G+gpmgBSBqVM81jbp2ePOKsvhgJdhyZJtkYQCII7rg9KKLQhvBQM5sLaF1eU6r0iuwmyynC9d9SA==", - "dev": true, - "dependencies": { - "type-fest": "^2.19.0" - } - }, - "node_modules/@storybook/csf-plugin": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.0.4.tgz", - "integrity": "sha512-pEgctWuS/qeKMFZJJUM2JuKwjKBt27ye+216ft7xhNqpsrmCgumJYrkU/ii2CsFJU/qr5Fu9EYw+N+vof1OalQ==", - "dev": true, - "dependencies": { - "@storybook/csf-tools": "8.0.4", - "unplugin": "^1.3.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/csf-tools": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-8.0.4.tgz", - "integrity": "sha512-dMSZxWnXBhmXGOZZOAJ4DKZRCYdA0HaqqZ4/eF9MLLsI+qvW4EklcpjVY6bsIzACgubRWtRZkTpxTnjExi/N1A==", - "dev": true, - "dependencies": { - "@babel/generator": "^7.23.0", - "@babel/parser": "^7.23.0", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0", - "@storybook/csf": "^0.1.2", - "@storybook/types": "8.0.4", - "fs-extra": "^11.1.0", - "recast": "^0.23.5", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/docs-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@storybook/docs-mdx/-/docs-mdx-3.0.0.tgz", - "integrity": "sha512-NmiGXl2HU33zpwTv1XORe9XG9H+dRUC1Jl11u92L4xr062pZtrShLmD4VKIsOQujxhhOrbxpwhNOt+6TdhyIdQ==", - "dev": true - }, - "node_modules/@storybook/docs-tools": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-8.0.4.tgz", - "integrity": "sha512-PONfG8j/AOHi79NbEkneFRZIscrShbA0sgA+62zeejH4r9+fuIkIKtLnKcAxvr8Bm6uo9aSQbISJZUcBG42WhQ==", - "dev": true, - "dependencies": { - "@storybook/core-common": "8.0.4", - "@storybook/preview-api": "8.0.4", - "@storybook/types": "8.0.4", - "@types/doctrine": "^0.0.3", - "assert": "^2.1.0", - "doctrine": "^3.0.0", - "lodash": "^4.17.21" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/global": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", - "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", - "dev": true - }, - "node_modules/@storybook/icons": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.2.9.tgz", - "integrity": "sha512-cOmylsz25SYXaJL/gvTk/dl3pyk7yBFRfeXTsHvTA3dfhoU/LWSq0NKL9nM7WBasJyn6XPSGnLS4RtKXLw5EUg==", - "dev": true, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/instrumenter": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.0.4.tgz", - "integrity": "sha512-lkHv1na12oMTZvuDbzufgqrtFlV1XqdXrAAg7YXZOia/oMz6Z/XMldEqwLPUCLGVodbFJofrpE67Wtw8dNTDQg==", - "dev": true, - "dependencies": { - "@storybook/channels": "8.0.4", - "@storybook/client-logger": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/global": "^5.0.0", - "@storybook/preview-api": "8.0.4", - "@vitest/utils": "^1.3.1", - "util": "^0.12.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/manager": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-8.0.4.tgz", - "integrity": "sha512-M5IofDSxbIQIdAglxUtZOGKjZ1EAq1Mdbh4UolVsF1PKF6dAvBQJLVW6TiLjEbmPBtqgeYKMgrmmYiFNqVcdBQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/manager-api": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.0.4.tgz", - "integrity": "sha512-TudiRmWlsi8kdjwqW0DDLen76Zp4Sci/AnvTbZvZOWe8C2mruxcr6aaGwuIug6y+uxIyXDvURF6Cek5Twz4isg==", - "dev": true, - "dependencies": { - "@storybook/channels": "8.0.4", - "@storybook/client-logger": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/csf": "^0.1.2", - "@storybook/global": "^5.0.0", - "@storybook/icons": "^1.2.5", - "@storybook/router": "8.0.4", - "@storybook/theming": "8.0.4", - "@storybook/types": "8.0.4", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "store2": "^2.14.2", - "telejson": "^7.2.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/nextjs": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/nextjs/-/nextjs-8.0.4.tgz", - "integrity": "sha512-60OmklpKB48l57Tfo3X5+RxSuz15iudjrwyeTJBq6Afi0fFa7hWk4jq/n+LdCjhOxavLtHRv/qFEQrMDmGH0gA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.23.2", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.22.5", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.11", - "@babel/plugin-transform-numeric-separator": "^7.22.11", - "@babel/plugin-transform-object-rest-spread": "^7.22.15", - "@babel/plugin-transform-runtime": "^7.23.2", - "@babel/preset-env": "^7.23.2", - "@babel/preset-react": "^7.22.15", - "@babel/preset-typescript": "^7.23.2", - "@babel/runtime": "^7.23.2", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", - "@storybook/addon-actions": "8.0.4", - "@storybook/builder-webpack5": "8.0.4", - "@storybook/core-common": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/preset-react-webpack": "8.0.4", - "@storybook/preview-api": "8.0.4", - "@storybook/react": "8.0.4", - "@storybook/types": "8.0.4", - "@types/node": "^18.0.0", - "@types/semver": "^7.3.4", - "babel-loader": "^9.1.3", - "css-loader": "^6.7.3", - "find-up": "^5.0.0", - "fs-extra": "^11.1.0", - "image-size": "^1.0.0", - "loader-utils": "^3.2.1", - "node-polyfill-webpack-plugin": "^2.0.1", - "pnp-webpack-plugin": "^1.7.0", - "postcss": "^8.4.21", - "postcss-loader": "^7.0.2", - "react-refresh": "^0.14.0", - "resolve-url-loader": "^5.0.0", - "sass-loader": "^12.4.0", - "semver": "^7.3.5", - "sharp": "^0.32.6", - "style-loader": "^3.3.1", - "styled-jsx": "5.1.1", - "ts-dedent": "^2.0.0", - "tsconfig-paths": "^4.0.0", - "tsconfig-paths-webpack-plugin": "^4.0.1" - }, - "engines": { - "node": ">=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "next": "^13.5.0 || ^14.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/@storybook/nextjs/node_modules/@types/node": { - "version": "18.19.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", - "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@storybook/nextjs/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/nextjs/node_modules/sass-loader": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", - "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", - "dev": true, - "dependencies": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } - }, - "node_modules/@storybook/nextjs/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/nextjs/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@storybook/node-logger": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-8.0.4.tgz", - "integrity": "sha512-cALLHuX53vLQsoJamGRlquh2pfhPq9copXou2JTmFT6mrCcipo77SzhBDfeeuhaGv6vUWPfmGjPBEHXWGPe4+g==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/preset-react-webpack": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.0.4.tgz", - "integrity": "sha512-XldgoZJOXNbZLGhvP6FqVeRnXigEZXV88uhEveREH4zRceYxXUmiCjFUnFy5aXaYZLcv09GHpqTPCqRoOZ+upg==", - "dev": true, - "dependencies": { - "@storybook/core-webpack": "8.0.4", - "@storybook/docs-tools": "8.0.4", - "@storybook/node-logger": "8.0.4", - "@storybook/react": "8.0.4", - "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", - "@types/node": "^18.0.0", - "@types/semver": "^7.3.4", - "find-up": "^5.0.0", - "fs-extra": "^11.1.0", - "magic-string": "^0.30.5", - "react-docgen": "^7.0.0", - "resolve": "^1.22.8", - "semver": "^7.3.7", - "tsconfig-paths": "^4.2.0", - "webpack": "5" - }, - "engines": { - "node": ">=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@storybook/preset-react-webpack/node_modules/@types/node": { - "version": "18.19.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", - "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@storybook/preset-react-webpack/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/preset-react-webpack/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/preset-react-webpack/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@storybook/preview": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-8.0.4.tgz", - "integrity": "sha512-dJa13bIxQBfa5ZsXAeL6X/oXI6b87Fy31pvpKPkW1o+7M6MC4OvwGQBqgAd7m8yn6NuIHxrdwjEupa7l7PGb6w==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/preview-api": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.0.4.tgz", - "integrity": "sha512-uZCgZ/7BZkFTNudCBWx3YPFVdReMQSZJj9EfQVhQaPmfGORHGMvZMRsQXl0ONhPy7zDD4rVQxu5dSKWmIiYoWQ==", - "dev": true, - "dependencies": { - "@storybook/channels": "8.0.4", - "@storybook/client-logger": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/csf": "^0.1.2", - "@storybook/global": "^5.0.0", - "@storybook/types": "8.0.4", - "@types/qs": "^6.9.5", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "qs": "^6.10.0", - "tiny-invariant": "^1.3.1", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/react": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.0.4.tgz", - "integrity": "sha512-p4wQSJIhG48UD2fZ6tFDT9zaqrVnvZxjV18+VjSi3dez/pDoEMJ3SWZWcmeDenKwvvk+SPdRH7k5mUHW1Rh0xg==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "8.0.4", - "@storybook/docs-tools": "8.0.4", - "@storybook/global": "^5.0.0", - "@storybook/preview-api": "8.0.4", - "@storybook/react-dom-shim": "8.0.4", - "@storybook/types": "8.0.4", - "@types/escodegen": "^0.0.6", - "@types/estree": "^0.0.51", - "@types/node": "^18.0.0", - "acorn": "^7.4.1", - "acorn-jsx": "^5.3.1", - "acorn-walk": "^7.2.0", - "escodegen": "^2.1.0", - "html-tags": "^3.1.0", - "lodash": "^4.17.21", - "prop-types": "^15.7.2", - "react-element-to-jsx-string": "^15.0.0", - "semver": "^7.3.7", - "ts-dedent": "^2.0.0", - "type-fest": "~2.19", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "typescript": ">= 4.2.x" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@storybook/react-docgen-typescript-plugin": { - "version": "1.0.6--canary.9.0c3f3b7.0", - "resolved": "https://registry.npmjs.org/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz", - "integrity": "sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "endent": "^2.0.1", - "find-cache-dir": "^3.3.1", - "flat-cache": "^3.0.4", - "micromatch": "^4.0.2", - "react-docgen-typescript": "^2.2.2", - "tslib": "^2.0.0" - }, - "peerDependencies": { - "typescript": ">= 4.x", - "webpack": ">= 4" - } - }, - "node_modules/@storybook/react-dom-shim": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.0.4.tgz", - "integrity": "sha512-H8bci23e+G40WsdYPuPrhAjCeeXypXuAV6mTVvLHGKH+Yb+3wiB1weaXrot/TgzPbkDNybuhTI3Qm48FPLt0bw==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/react/node_modules/@types/node": { - "version": "18.19.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.26.tgz", - "integrity": "sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@storybook/react/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/react/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/react/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@storybook/router": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-8.0.4.tgz", - "integrity": "sha512-hlR80QvmLBflAqMeGcgtDuSe6TJlzdizwEAkBLE1lDvFI6tvvEyAliCAXBpIDdOZTe0u/zeeJkOUXKSx33caoQ==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "8.0.4", - "memoizerific": "^1.11.3", - "qs": "^6.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/telemetry": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-8.0.4.tgz", - "integrity": "sha512-Q3ITY6J46R/TrrPRIU1fs3WNs69ExpTJZ9UlB8087qOUyV90Ex33SYk3i10xVWRczxCmyC1V58Xuht6nxz7mNQ==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "8.0.4", - "@storybook/core-common": "8.0.4", - "@storybook/csf-tools": "8.0.4", - "chalk": "^4.1.0", - "detect-package-manager": "^2.0.1", - "fetch-retry": "^5.0.2", - "fs-extra": "^11.1.0", - "read-pkg-up": "^7.0.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/telemetry/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@storybook/telemetry/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@storybook/telemetry/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/telemetry/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/test": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.0.4.tgz", - "integrity": "sha512-/uvE8Rtu7tIcuyQBUzKq7uuDCsjmADI18BApLdwo/qthmN8ERDxRSz0Ngj2gvBMQFv99At8ESi/xh6oFGu3rWg==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "8.0.4", - "@storybook/core-events": "8.0.4", - "@storybook/instrumenter": "8.0.4", - "@storybook/preview-api": "8.0.4", - "@testing-library/dom": "^9.3.4", - "@testing-library/jest-dom": "^6.4.2", - "@testing-library/user-event": "^14.5.2", - "@vitest/expect": "1.3.1", - "@vitest/spy": "^1.3.1", - "chai": "^4.4.1", - "util": "^0.12.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/testing-library": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.2.tgz", - "integrity": "sha512-L8sXFJUHmrlyU2BsWWZGuAjv39Jl1uAqUHdxmN42JY15M4+XCMjGlArdCCjDe1wpTSW6USYISA9axjZojgtvnw==", - "dev": true, - "dependencies": { - "@testing-library/dom": "^9.0.0", - "@testing-library/user-event": "^14.4.0", - "ts-dedent": "^2.2.0" - } - }, - "node_modules/@storybook/theming": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.0.4.tgz", - "integrity": "sha512-NxtTU2wMC0lj375ejoT3Npdcqwv6NeUpLaJl6EZCMXSR41ve9WG4suUNWQ63olhqKxirjzAz0IL7ggH7c3hPvA==", - "dev": true, - "dependencies": { - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@storybook/client-logger": "8.0.4", - "@storybook/global": "^5.0.0", - "memoizerific": "^1.11.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@storybook/types": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-8.0.4.tgz", - "integrity": "sha512-OO7QY+qZFCYkItDUBACtIV32p75O7sNziAiyS1V2Oxgo7Ln7fwZwr3mJcA1ruBed6ZcrW3c87k7Xs40T2zAWcg==", - "dev": true, - "dependencies": { - "@storybook/channels": "8.0.4", - "@types/express": "^4.7.0", - "file-system-cache": "2.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@swc/helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", - "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tanstack/react-virtual": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.2.0.tgz", - "integrity": "sha512-OEdMByf2hEfDa6XDbGlZN8qO6bTjlNKqjM3im9JG+u3mCL8jALy0T/67oDI001raUUPh1Bdmfn4ZvPOV5knpcg==", - "dependencies": { - "@tanstack/virtual-core": "3.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@tanstack/virtual-core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.2.0.tgz", - "integrity": "sha512-P5XgYoAw/vfW65byBbJQCw+cagdXDT/qH6wmABiLt4v4YBT2q2vqCOhihe+D1Nt325F/S/0Tkv6C5z0Lv+VBQQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@testing-library/dom": { - "version": "9.3.4", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", - "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.2.tgz", - "integrity": "sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==", - "dev": true, - "dependencies": { - "@adobe/css-tools": "^4.3.2", - "@babel/runtime": "^7.9.2", - "aria-query": "^5.0.0", - "chalk": "^3.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.6.3", - "lodash": "^4.17.15", - "redent": "^3.0.0" - }, - "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1" - }, - "peerDependencies": { - "@jest/globals": ">= 28", - "@types/bun": "latest", - "@types/jest": ">= 28", - "jest": ">= 28", - "vitest": ">= 0.32" - }, - "peerDependenciesMeta": { - "@jest/globals": { - "optional": true - }, - "@types/bun": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "jest": { - "optional": true - }, - "vitest": { - "optional": true - } - } - }, - "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", - "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", - "dev": true - }, - "node_modules/@testing-library/jest-dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/user-event": { - "version": "14.5.2", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", - "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", - "dev": true, - "engines": { - "node": ">=12", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" - } - }, - "node_modules/@tremor/react": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/@tremor/react/-/react-3.14.1.tgz", - "integrity": "sha512-0LMxFIeBXsAaPnR6mXRK4fbZaTNLFfVngFpoOt+6Tf797k/c6yUkB48/QPB5vO02qzkV74D91hng9r6HwfDW5g==", - "dependencies": { - "@floating-ui/react": "^0.19.2", - "@headlessui/react": "^1.7.18", - "@headlessui/tailwindcss": "^0.2.0", - "date-fns": "^2.30.0", - "react-day-picker": "^8.9.1", - "react-transition-state": "^2.1.1", - "recharts": "^2.10.3", - "tailwind-merge": "^1.14.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": ">=16.6.0" - } - }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" - }, - "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" - }, - "node_modules/@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" - }, - "node_modules/@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@types/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" - }, - "node_modules/@types/d3-scale": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", - "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@types/d3-shape": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", - "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", - "dependencies": { - "@types/d3-path": "*" - } - }, - "node_modules/@types/d3-time": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", - "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" - }, - "node_modules/@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" - }, - "node_modules/@types/detect-port": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/detect-port/-/detect-port-1.3.5.tgz", - "integrity": "sha512-Rf3/lB9WkDfIL9eEKaSYKc+1L/rNVYBjThk22JTqQw0YozXarX8YljFAz+HCoC6h4B4KwCMsBPZHaFezwT4BNA==", - "dev": true - }, - "node_modules/@types/doctrine": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.3.tgz", - "integrity": "sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA==", - "dev": true - }, - "node_modules/@types/ejs": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.5.tgz", - "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==", - "dev": true - }, - "node_modules/@types/emscripten": { - "version": "1.39.10", - "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.10.tgz", - "integrity": "sha512-TB/6hBkYQJxsZHSqyeuO1Jt0AB/bW6G7rHt9g7lML7SOF6lbgcHvw/Lr+69iqN0qxgXLhWKScAon73JNnptuDw==", - "dev": true - }, - "node_modules/@types/escodegen": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.6.tgz", - "integrity": "sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==", - "dev": true - }, - "node_modules/@types/eslint": { - "version": "8.56.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", - "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/find-cache-dir": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/find-cache-dir/-/find-cache-dir-3.2.1.tgz", - "integrity": "sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==", - "dev": true - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "dev": true, - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", - "dev": true - }, - "node_modules/@types/mdx": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.12.tgz", - "integrity": "sha512-H9VZ9YqE+H28FQVchC83RCs5xQ2J7mAAv6qdDEaWmXEVl3OpdH+xfrSUzQ1lp7U7oSTRZ0RvW08ASPJsYBi7Cw==", - "dev": true - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.11.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", - "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "dev": true, - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA==", - "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", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" - }, - "node_modules/@types/qs": { - "version": "6.9.14", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", - "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true - }, - "node_modules/@types/react": { - "version": "18.2.70", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.70.tgz", - "integrity": "sha512-hjlM2hho2vqklPhopNkXkdkeq6Lv8WSZTpr7956zY+3WS5cfYUewtCzsJLsbW5dEv3lfSeQ4W14ZFeKC437JRQ==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.2.22", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.22.tgz", - "integrity": "sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-transition-group": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", - "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/resolve": { - "version": "1.20.6", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", - "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", - "dev": true - }, - "node_modules/@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" - }, - "node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "dev": true - }, - "node_modules/@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", - "dev": true - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@vitest/expect": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz", - "integrity": "sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==", - "dev": true, - "dependencies": { - "@vitest/spy": "1.3.1", - "@vitest/utils": "1.3.1", - "chai": "^4.3.10" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/expect/node_modules/@vitest/spy": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz", - "integrity": "sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==", - "dev": true, - "dependencies": { - "tinyspy": "^2.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/expect/node_modules/@vitest/utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.1.tgz", - "integrity": "sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==", - "dev": true, - "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@vitest/expect/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@vitest/expect/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/@vitest/spy": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", - "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", - "dev": true, - "dependencies": { - "tinyspy": "^2.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", - "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", - "dev": true, - "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@vitest/utils/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@vitest/utils/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/@yarnpkg/esbuild-plugin-pnp": { - "version": "3.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@yarnpkg/esbuild-plugin-pnp/-/esbuild-plugin-pnp-3.0.0-rc.15.tgz", - "integrity": "sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==", - "dev": true, - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "esbuild": ">=0.10.0" - } - }, - "node_modules/@yarnpkg/fslib": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.10.3.tgz", - "integrity": "sha512-41H+Ga78xT9sHvWLlFOZLIhtU6mTGZ20pZ29EiZa97vnxdohJD2AF42rCoAoWfqUz486xY6fhjMH+DYEM9r14A==", - "dev": true, - "dependencies": { - "@yarnpkg/libzip": "^2.3.0", - "tslib": "^1.13.0" - }, - "engines": { - "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0" - } - }, - "node_modules/@yarnpkg/fslib/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/@yarnpkg/libzip": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.3.0.tgz", - "integrity": "sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==", - "dev": true, - "dependencies": { - "@types/emscripten": "^1.39.6", - "tslib": "^1.13.0" - }, - "engines": { - "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0" - } - }, - "node_modules/@yarnpkg/libzip/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-styles/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ansi-styles/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/app-root-dir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/app-root-dir/-/app-root-dir-1.0.2.tgz", - "integrity": "sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==", - "dev": true - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/aria-hidden": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", - "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", - "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.1.0", - "es-shim-unscopables": "^1.0.2" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/assert": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", - "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/ast-types": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", - "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", - "dev": true, - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/autoprefixer": { - "version": "10.4.19", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", - "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", - "dev": true, - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "dev": true - }, - "node_modules/babel-core": { - "version": "7.0.0-bridge.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", - "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", - "dev": true, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "dev": true, - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "node_modules/babel-loader/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/babel-loader/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/babel-loader/node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "dev": true, - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/babel-loader/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/babel-loader/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/babel-loader/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/babel-loader/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/babel-loader/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/babel-loader/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/babel-loader/node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "dev": true, - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/babel-loader/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/babel-loader/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/bare-events": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", - "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", - "dev": true, - "optional": true - }, - "node_modules/bare-fs": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.2.tgz", - "integrity": "sha512-X9IqgvyB0/VA5OZJyb5ZstoN62AzD7YxVGog13kkfYWYqJYcK0kcqLZ6TrmH5qr4/8//ejVcX4x/a0UvaogXmA==", - "dev": true, - "optional": true, - "dependencies": { - "bare-events": "^2.0.0", - "bare-os": "^2.0.0", - "bare-path": "^2.0.0", - "streamx": "^2.13.0" - } - }, - "node_modules/bare-os": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.1.tgz", - "integrity": "sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w==", - "dev": true, - "optional": true - }, - "node_modules/bare-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.0.tgz", - "integrity": "sha512-DIIg7ts8bdRKwJRJrUMy/PICEaQZaPGZ26lsSx9MJSwIhSrcdHn7/C8W+XmnG/rKi6BaRcz+JO00CjZteybDtw==", - "dev": true, - "optional": true, - "dependencies": { - "bare-os": "^2.1.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/better-opn": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", - "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", - "dev": true, - "dependencies": { - "open": "^8.0.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "node_modules/bplist-parser": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", - "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.44" - }, - "engines": { - "node": ">= 5.10.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-assert": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz", - "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", - "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.5", - "hash-base": "~3.0", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.7", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/browserify-sign/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/browserify-sign/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/camelize": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001600", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", - "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/case-sensitive-paths-webpack-plugin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", - "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/citty": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", - "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", - "dev": true, - "dependencies": { - "consola": "^3.2.3" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true - }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" - }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "dev": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", - "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dev": true, - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/consola": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", - "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", - "dev": true, - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "node_modules/copy-anything": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", - "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", - "dev": true, - "dependencies": { - "is-what": "^3.14.1" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", - "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", - "dev": true, - "dependencies": { - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.1", - "globby": "^14.0.0", - "normalize-path": "^3.0.0", - "schema-utils": "^4.2.0", - "serialize-javascript": "^6.0.2" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/copy-webpack-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/core-js-compat": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", - "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", - "dev": true, - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.1.tgz", - "integrity": "sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/css-loader": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", - "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", - "dev": true, - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.4", - "postcss-modules-scope": "^3.1.1", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-loader/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/css-loader/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/css-loader/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-to-react-native": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", - "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", - "dependencies": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "dependencies": { - "internmap": "1 - 2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "dependencies": { - "d3-array": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "dependencies": { - "d3-time": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", - "dependencies": { - "@babel/runtime": "^7.21.0" - }, - "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js-light": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", - "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", - "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", - "dev": true, - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "dev": true - }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/del/node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/del/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node-es": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" - }, - "node_modules/detect-package-manager": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-package-manager/-/detect-package-manager-2.0.1.tgz", - "integrity": "sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==", - "dev": true, - "dependencies": { - "execa": "^5.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dev": true, - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domain-browser": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", - "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://bevry.me/fund" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/dotenv-expand": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", - "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/duplexify/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/duplexify/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexify/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/duplexify/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, - "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", - "dev": true, - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.715", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.715.tgz", - "integrity": "sha512-XzWNH4ZSa9BwVUQSDorPWAUQ5WGuYz7zJUNpNif40zFCiCl20t8zgylmreNmn26h5kiyw2lg7RfTmeMBsDklqg==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/email-addresses": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", - "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/endent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/endent/-/endent-2.1.0.tgz", - "integrity": "sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==", - "dev": true, - "dependencies": { - "dedent": "^0.7.0", - "fast-json-parse": "^1.0.3", - "objectorarray": "^1.0.5" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", - "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "optional": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "dev": true, - "dependencies": { - "stackframe": "^1.3.4" - } - }, - "node_modules/es-abstract": { - "version": "1.23.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", - "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", - "dev": true, + "node_modules/@radix-ui/react-toast": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.1.5.tgz", + "integrity": "sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.5", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "engines": { - "node": ">= 0.4" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dev": true, + "node_modules/@radix-ui/react-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz", + "integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.7", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.2" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, - "engines": { - "node": ">= 0.4" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/es-module-lexer": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.2.tgz", - "integrity": "sha512-7nOqkomXZEaxUDJw21XZNtRk739QvrPSoZoRtbsEfcii00vdzZUh6zh1CQwHhrib8MdEtJfv5rJiGeb4KuV/vw==", - "dev": true - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz", + "integrity": "sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==", "dependencies": { - "es-errors": "^1.3.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-toggle": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" }, - "engines": { - "node": ">= 0.4" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", + "integrity": "sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==", "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.3", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" }, - "engines": { - "node": ">= 0.4" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", "dependencies": { - "hasown": "^2.0.0" + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" }, - "engines": { - "node": ">= 0.4" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" }, - "engines": { - "node": ">=12" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/esbuild-plugin-alias": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz", - "integrity": "sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==", - "dev": true + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } }, - "node_modules/esbuild-register": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.5.0.tgz", - "integrity": "sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==", - "dev": true, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", "dependencies": { - "debug": "^4.3.4" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "esbuild": ">=0.12 <1" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", + "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": ">=6.0" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", + "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.1" }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/eslint-config-next": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.4.tgz", - "integrity": "sha512-cihIahbhYAWwXJwZkAaRPpUi5t9aOi/HdfWXOjZeUOqNWXHD8X22kd1KG58Dc3MVaRx3HoR/oMGk2ltcrqDn8g==", - "dev": true, + "node_modules/@radix-ui/react-use-size": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz", + "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==", "dependencies": { - "@next/eslint-plugin-next": "14.1.4", - "@rushstack/eslint-patch": "^1.3.3", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { - "eslint": "^7.23.0 || ^8.0.0", - "typescript": ">=3.3.1" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, "peerDependenciesMeta": { - "typescript": { + "@types/react": { "optional": true } } }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz", + "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { - "eslint": ">=7.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, + "node_modules/@radix-ui/rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", + "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" + "@babel/runtime": "^7.13.10" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/@rushstack/eslint-patch": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.9.0.tgz", + "integrity": "sha512-AAWymnpvHbGty1BmgbdfbqQDboXs6xN6h2yAacO4yKVyyUUBnpYkp+P9jjPrV9zrAGw7JVVriRtGOHPInnfjZQ==", + "dev": true + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", "dependencies": { - "ms": "^2.1.1" + "tslib": "^2.4.0" } }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", - "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", - "dev": true, + "node_modules/@tanstack/react-virtual": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.2.0.tgz", + "integrity": "sha512-OEdMByf2hEfDa6XDbGlZN8qO6bTjlNKqjM3im9JG+u3mCL8jALy0T/67oDI001raUUPh1Bdmfn4ZvPOV5knpcg==", "dependencies": { - "debug": "^4.3.4", - "enhanced-resolve": "^5.12.0", - "eslint-module-utils": "^2.7.4", - "fast-glob": "^3.3.1", - "get-tsconfig": "^4.5.0", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" + "@tanstack/virtual-core": "3.2.0" }, "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, + "node_modules/@tanstack/virtual-core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.2.0.tgz", + "integrity": "sha512-P5XgYoAw/vfW65byBbJQCw+cagdXDT/qH6wmABiLt4v4YBT2q2vqCOhihe+D1Nt325F/S/0Tkv6C5z0Lv+VBQQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tremor/react": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/@tremor/react/-/react-3.15.0.tgz", + "integrity": "sha512-TNhLzlGV9ph0Bzd7uTFHaE7Je9diIDuqt7Khnm5XkqO7y0jTE+9aGT/gcV6qTZV/9dfkcv8Aw1J/NpxH+hynGQ==", "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" + "@floating-ui/react": "^0.19.2", + "@headlessui/react": "^1.7.18", + "@headlessui/tailwindcss": "^0.2.0", + "date-fns": "^2.30.0", + "react-day-picker": "^8.9.1", + "react-transition-state": "^2.1.1", + "recharts": "^2.10.3", + "tailwind-merge": "^1.14.0" }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "peerDependencies": { + "react": "^18.0.0", + "react-dom": ">=16.6.0" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", "dependencies": { - "ms": "^2.1.1" + "@types/d3-color": "*" } }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "@types/d3-time": "*" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/eslint": { + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" + "@types/eslint": "*", + "@types/estree": "*" } }, - "node_modules/eslint-plugin-import/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" + "undici-types": "~5.26.4" } }, - "node_modules/eslint-plugin-import/node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + }, + "node_modules/@types/react": { + "version": "18.2.73", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.73.tgz", + "integrity": "sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA==", "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "@types/prop-types": "*", + "csstype": "^3.0.2" } }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", - "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", - "dev": true, + "node_modules/@types/react-dom": { + "version": "18.2.22", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.22.tgz", + "integrity": "sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==", "dependencies": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "=4.7.0", - "axobject-query": "^3.2.1", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.15", - "hasown": "^2.0.0", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "@types/react": "*" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "dependencies": { - "dequal": "^2.0.3" + "@types/react": "*" } }, - "node_modules/eslint-plugin-react": { - "version": "7.34.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", - "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "node_modules/@types/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlast": "^1.2.4", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", - "array.prototype.tosorted": "^1.1.3", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.17", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7", - "object.hasown": "^1.1.3", - "object.values": "^1.1.7", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.10" + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=4" + "node": "^16.0.0 || >=18.0.0" }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true, - "engines": { - "node": ">=10" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" + "eslint": "^7.0.0 || ^8.0.0" }, - "engines": { - "node": ">=0.10.0" + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, - "bin": { - "resolve": "bin/resolve" + "engines": { + "node": "^16.0.0 || >=18.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/eslint-plugin-storybook": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.8.0.tgz", - "integrity": "sha512-CZeVO5EzmPY7qghO2t64oaFM+8FTaD4uzOEjHKp516exyTKo+skKAL9GI3QALS2BXhyALJjNtwbmr1XinGE8bA==", + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, - "dependencies": { - "@storybook/csf": "^0.0.1", - "@typescript-eslint/utils": "^5.62.0", - "requireindex": "^1.2.0", - "ts-dedent": "^2.2.0" - }, "engines": { - "node": ">= 18" + "node": "^16.0.0 || >=18.0.0" }, - "peerDependencies": { - "eslint": ">=6" - } - }, - "node_modules/eslint-plugin-storybook/node_modules/@storybook/csf": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", - "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=8" + "node": "^16.0.0 || >=18.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/espree/node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "@xtuc/long": "4.2.2" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, - "engines": { - "node": ">=4.0" + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@types/estree": "^1.0.0" + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" } }, - "node_modules/estree-walker/node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "dev": true }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">= 0.6" + "node": ">=0.4.0" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, - "engines": { - "node": ">=6" + "peerDependencies": { + "acorn": "^8" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "engines": { - "node": ">=0.8.x" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "ajv": "^8.0.0" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "ajv": "^8.0.0" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "engines": { - "node": ">=6" + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/fast-equals": { + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", - "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { - "node": ">=6.0.0" + "node": ">=8" } }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=8.6.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { - "is-glob": "^4.0.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": ">= 6" + "node": ">= 8" } }, - "node_modules/fast-json-parse": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz", - "integrity": "sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dependencies": { - "reusify": "^1.0.4" - } + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, - "node_modules/fetch-retry": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-5.0.6.tgz", - "integrity": "sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", "dependencies": { - "flat-cache": "^3.0.4" + "tslib": "^2.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10" } }, - "node_modules/file-system-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/file-system-cache/-/file-system-cache-2.3.0.tgz", - "integrity": "sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ==", + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "dependencies": { - "fs-extra": "11.1.1", - "ramda": "0.29.0" + "dequal": "^2.0.3" } }, - "node_modules/file-system-cache/node_modules/fs-extra": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", - "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" }, "engines": { - "node": ">=14.14" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "dependencies": { - "minimatch": "^5.0.1" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", "dev": true, "dependencies": { - "ms": "2.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" } }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", "dev": true, "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" } }, - "node_modules/find-cache-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/find-cache-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "p-locate": "^4.1.0" + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" }, "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/find-cache-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "possible-typed-array-names": "^1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/find-cache-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/find-cache-dir/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", "dev": true, "dependencies": { - "find-up": "^4.0.0" + "dequal": "^2.0.3" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" }, "engines": { - "node": ">=8" + "node": ">=10", + "npm": ">=6" } }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=8" } }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/flow-parser": { - "version": "0.231.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.231.0.tgz", - "integrity": "sha512-WVzuqwq7ZnvBceCG0DGeTQebZE+iIU0mlk5PmJgYj9DDrt+0isGC2m1ezW9vxL4V+HERJJo9ExppOnwKH2op6Q==", + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, "engines": { - "node": ">=0.4.0" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dependencies": { - "is-callable": "^1.1.3" + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" } }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { - "node": ">=14" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=6" } }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz", - "integrity": "sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.7", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "fs-extra": "^10.0.0", - "memfs": "^3.4.1", - "minimatch": "^3.0.4", - "node-abort-controller": "^3.0.1", - "schema-utils": "^3.1.1", - "semver": "^7.3.5", - "tapable": "^2.2.1" - }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", "engines": { - "node": ">=12.13.0", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "typescript": ">3.6.0", - "webpack": "^5.11.0" + "node": ">= 6" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "node_modules/caniuse-lite": { + "version": "1.0.30001600", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", + "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -13392,521 +3140,489 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=12" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { - "yallist": "^4.0.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=10" + "node": ">= 6" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, "engines": { - "node": ">=10" + "node": ">=6.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dependencies": { - "has-flag": "^4.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": "*" + "node": ">=10" }, "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", "engines": { - "node": ">= 0.6" + "node": ">=6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=14.14" + "node": ">=7.0.0" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=16" } }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, - "node_modules/fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 0.6" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "dependencies": { + "is-what": "^3.14.1" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">= 18.12.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">=10" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/cosmiconfig/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=8" } }, - "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", - "dev": true, - "engines": { - "node": ">=18" + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 8" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", "engines": { - "node": "*" + "node": ">=4" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/get-npm-tarball-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-npm-tarball-url/-/get-npm-tarball-url-2.1.0.tgz", - "integrity": "sha512-ro+DiMu5DXgRBabqXupW38h7WPZ9+Ad8UjwhvsmmN8w1sU7ab0nzAXvVZ4kqYg57OrqomRtJvepX5/xvFKNtjA==", - "dev": true, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", "engines": { - "node": ">=12.17" + "node": ">=12" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", - "dev": true, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "dependencies": { - "resolve-pkg-maps": "^1.0.0" + "d3-color": "1 - 3" }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "engines": { + "node": ">=12" } }, - "node_modules/gh-pages": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.1.1.tgz", - "integrity": "sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw==", - "dev": true, - "dependencies": { - "async": "^3.2.4", - "commander": "^11.0.0", - "email-addresses": "^5.0.0", - "filenamify": "^4.3.0", - "find-cache-dir": "^3.3.1", - "fs-extra": "^11.1.1", - "globby": "^6.1.0" - }, - "bin": { - "gh-pages": "bin/gh-pages.js", - "gh-pages-clean": "bin/gh-pages-clean.js" - }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/gh-pages/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", "dependencies": { - "array-uniq": "^1.0.1" + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/gh-pages/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "d3-path": "^3.1.0" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=12" } }, - "node_modules/gh-pages/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", - "dev": true, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "d3-array": "2 - 3" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/giget": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz", - "integrity": "sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==", - "dev": true, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", "dependencies": { - "citty": "^0.1.6", - "consola": "^3.2.3", - "defu": "^6.1.4", - "node-fetch-native": "^1.6.3", - "nypm": "^0.3.8", - "ohash": "^1.1.3", - "pathe": "^1.1.2", - "tar": "^6.2.0" + "d3-time": "1 - 3" }, - "bin": { - "giget": "dist/cli.mjs" + "engines": { + "node": ">=12" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, - "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, "dependencies": { - "is-glob": "^4.0.3" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=10.13.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "dependencies": { - "brace-expansion": "^2.0.1" + "@babel/runtime": "^7.21.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=0.11" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "opencollective", + "url": "https://opencollective.com/date-fns" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": ">=4" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { - "define-properties": "^1.1.3" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -13915,183 +3631,197 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", - "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby/node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, - "node_modules/gunzip-maybe": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", - "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "dependencies": { - "browserify-zlib": "^0.1.4", - "is-deflate": "^1.0.0", - "is-gzip": "^1.0.0", - "peek-stream": "^1.1.0", - "pumpify": "^1.3.3", - "through2": "^2.0.3" + "path-type": "^4.0.0" }, - "bin": { - "gunzip-maybe": "bin.js" + "engines": { + "node": ">=8" } }, - "node_modules/gunzip-maybe/node_modules/browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==", + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "dependencies": { - "pako": "~0.2.0" + "engines": { + "node": ">=8" } }, - "node_modules/gunzip-maybe/node_modules/pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", - "dev": true + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" + "esutils": "^2.0.2" }, "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "node": ">=6.0.0" } }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" } }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } + "node_modules/electron-to-chromium": { + "version": "1.4.719", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.719.tgz", + "integrity": "sha512-FbWy2Q2YgdFzkFUW/W5jBjE9dj+804+98E4Pup78JBPnbdb3pv6IneY2JCPKdeKLh3AOKHQeYf+KwLr7mxGh6Q==", + "dev": true }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/enhanced-resolve": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", "dev": true, "dependencies": { - "es-define-property": "^1.0.0" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, - "engines": { - "node": ">= 0.4" + "optional": true, + "dependencies": { + "prr": "~1.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "errno": "cli.js" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "node_modules/es-abstract": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", + "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", "dev": true, "dependencies": { - "has-symbols": "^1.0.3" + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -14100,917 +3830,822 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "get-intrinsic": "^1.2.4" }, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, "engines": { "node": ">= 0.4" } }, - "node_modules/hast-util-heading-rank": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", - "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", - "dev": true, - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "dev": true, - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz", - "integrity": "sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==", + "node_modules/es-iterator-helpers": { + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", + "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", "dev": true, "dependencies": { - "@types/hast": "^3.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" + "engines": { + "node": ">= 0.4" } }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "node_modules/es-module-lexer": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", + "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==", "dev": true }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" + "es-errors": "^1.3.0" }, "engines": { - "node": ">=12" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "node": ">= 0.4" } }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" + "hasown": "^2.0.0" } }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "node": ">= 0.4" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">=6" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { - "node": ">= 4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/image-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", - "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { - "queue": "6.0.2" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "bin": { - "image-size": "bin/image-size.js" + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=16.x" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/eslint-config-next": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.4.tgz", + "integrity": "sha512-cihIahbhYAWwXJwZkAaRPpUi5t9aOi/HdfWXOjZeUOqNWXHD8X22kd1KG58Dc3MVaRx3HoR/oMGk2ltcrqDn8g==", + "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "@next/eslint-plugin-next": "14.1.4", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "engines": { - "node": ">=4" + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "engines": { - "node": ">=0.8.19" + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "ms": "^2.1.1" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", "dev": true, "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 0.4" - } - }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "engines": { - "node": ">=12" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", - "dev": true - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-absolute-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", - "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "debug": "^3.2.7" }, "engines": { - "node": ">= 0.4" + "node": ">=4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "ms": "^2.1.1" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { - "node": ">= 0.4" + "node": ">=4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "ms": "^2.1.1" } }, - "node_modules/is-binary-path": { + "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" }, "engines": { - "node": ">= 0.4" + "node": ">=4.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "node_modules/eslint-plugin-react": { + "version": "7.34.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", + "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.17", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.10" + }, "engines": { - "node": ">= 0.4" + "node": ">=4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "is-typed-array": "^1.1.13" + "esutils": "^2.0.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "engines": { - "node": ">= 0.4" + "bin": { + "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-deflate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz", - "integrity": "sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==", - "dev": true - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" + "semver": "bin/semver.js" } }, - "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.10" } }, - "node_modules/is-gzip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", - "integrity": "sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4.0" } }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/is-map": { + "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.8.x" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", "engines": { - "node": ">=0.12.0" + "node": ">=6.0.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dependencies": { - "has-tostringtag": "^1.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8.6.0" } }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=6" + "node": ">= 6" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", "dev": true, "dependencies": { - "call-bind": "^1.0.7" + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "which-typed-array": "^1.1.14" + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "dev": true, "engines": { - "node": ">= 0.4" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "patreon", + "url": "https://github.com/sponsors/rawify" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -15019,492 +4654,405 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", - "dev": true - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isarray": { + "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" - } - }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" + "hasown": "^2.0.0" }, "engines": { - "node": ">=14" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", - "dev": true, - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", "engines": { - "node": ">=10" + "node": ">=6" } }, - "node_modules/jake/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" + "resolve-pkg-maps": "^1.0.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/jake/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/gh-pages": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-6.1.1.tgz", + "integrity": "sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw==", "dev": true, + "dependencies": { + "async": "^3.2.4", + "commander": "^11.0.0", + "email-addresses": "^5.0.0", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^11.1.1", + "globby": "^6.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/jake/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/gh-pages/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "array-uniq": "^1.0.1" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "node_modules/gh-pages/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/gh-pages/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dependencies": { - "has-flag": "^4.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", - "funding": { - "url": "https://github.com/sponsors/panva" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dependencies": { - "argparse": "^2.0.1" + "is-glob": "^4.0.3" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/jscodeshift": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.15.2.tgz", - "integrity": "sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.23.0", - "@babel/parser": "^7.23.0", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.23.0", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", - "@babel/plugin-transform-optional-chaining": "^7.23.0", - "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/preset-flow": "^7.22.15", - "@babel/preset-typescript": "^7.23.0", - "@babel/register": "^7.22.15", - "babel-core": "^7.0.0-bridge.0", - "chalk": "^4.1.2", - "flow-parser": "0.*", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "neo-async": "^2.5.0", - "node-dir": "^0.1.17", - "recast": "^0.23.3", - "temp": "^0.8.4", - "write-file-atomic": "^2.3.0" - }, - "bin": { - "jscodeshift": "bin/jscodeshift.js" - }, - "peerDependencies": { - "@babel/preset-env": "^7.1.6" - }, - "peerDependenciesMeta": { - "@babel/preset-env": { - "optional": true - } + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/jscodeshift/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dependencies": { - "color-convert": "^2.0.1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jscodeshift/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jscodeshift/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jscodeshift/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/globby": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "dependencies": { + "get-intrinsic": "^1.1.3" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, "engines": { - "node": ">=4.0" + "node": ">=8" } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, "engines": { - "node": ">= 8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/language-subtag-registry": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", - "dev": true - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "language-subtag-registry": "^0.3.20" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=0.10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lazy-universal-dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/lazy-universal-dotenv/-/lazy-universal-dotenv-4.0.0.tgz", - "integrity": "sha512-aXpZJRnTkpK6gQ/z4nk+ZBLd/Qdp118cvPruLSIQzQNRhKwEcdXCOzXuF55VDqIiuAaY3UGZ10DJtvZzDcvsxg==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { - "app-root-dir": "^1.0.2", - "dotenv": "^16.0.0", - "dotenv-expand": "^10.0.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.4" } }, - "node_modules/less": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", - "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", - "dev": true, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "dependencies": { - "copy-anything": "^2.0.1", - "parse-node-version": "^1.0.1", - "tslib": "^2.3.0" - }, - "bin": { - "lessc": "bin/lessc" + "react-is": "^16.7.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "needle": "^3.1.0", - "source-map": "~0.6.0" + "node": ">=0.10.0" } }, - "node_modules/less-loader": { - "version": "11.1.4", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.4.tgz", - "integrity": "sha512-6/GrYaB6QcW6Vj+/9ZPgKKs6G10YZai/l/eJ4SLwbzqNTBsAqt5hSLVF47TgsiBxV1P6eAU0GYRH3YRuQU9V3A==", + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "less": "^3.5.0 || ^4.0.0", - "webpack": "^5.0.0" + "node": ">= 4" } }, - "node_modules/less/node_modules/image-size": { + "node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", @@ -15517,1169 +5065,1136 @@ "node": ">=0.10.0" } }, - "node_modules/less/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "optional": true, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/less/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "optional": true, "engines": { - "node": ">=6" - } - }, - "node_modules/less/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "optional": true, - "bin": { - "semver": "bin/semver" + "node": ">=0.8.19" } }, - "node_modules/less/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" }, "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "engines": { - "node": ">=10" + "node": ">= 0.4" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", "engines": { - "node": ">=6.11.5" + "node": ">=12" } }, - "node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", - "dev": true, - "engines": { - "node": ">= 12.13.0" + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { - "p-locate": "^5.0.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "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.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", "dev": true, "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "is-typed-array": "^1.1.13" }, "engines": { - "node": ">=8" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" + "node": ">= 0.4" }, - "bin": { - "loose-envify": "cli.js" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "dependencies": { - "get-func-name": "^2.0.1" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "dependencies": { - "tslib": "^2.0.3" + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/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==", + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", "dev": true, "dependencies": { - "yallist": "^3.0.2" + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lucide-react": { - "version": "0.354.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.354.0.tgz", - "integrity": "sha512-qI0x/hhcuHieaUUxFejesm5T/ditszQ2x1gUkqKnTMZRAOdxT2nGzbOFYrhc0wRjuA2MN1o5JCrcRPYcHH3l8A==", - "peerDependencies": { - "react": "^16.5.1 || ^17.0.0 || ^18.0.0" + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" } }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, - "bin": { - "lz-string": "bin/bin.js" + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", - "dev": true, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/map-or-similar": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", - "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", - "dev": true - }, - "node_modules/markdown-to-jsx": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz", - "integrity": "sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q==", + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { - "node": ">= 10" + "node": ">= 0.4" }, - "peerDependencies": { - "react": ">= 0.14.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/material-symbols": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/material-symbols/-/material-symbols-0.17.1.tgz", - "integrity": "sha512-1kJan8t3U3Fmuu/YPu2MVsL/ODSja71o+J7ODROQfMaCzzal0izY4SATafEKgXUXU+jL0zIiBQdyzsno7vXBvA==" + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { - "fs-monkey": "^1.0.4" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">= 4.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" - }, - "node_modules/memoizerific": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", - "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", "dev": true, - "dependencies": { - "map-or-similar": "^1.5.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "engines": { - "node": ">= 8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "call-bind": "^1.0.7" }, "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "node": ">= 0.4" }, - "bin": { - "miller-rabin": "bin/miller-rabin" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "bin": { - "mime": "cli.js" + "dependencies": { + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "dependencies": { - "mime-db": "1.52.0" + "which-typed-array": "^1.1.14" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "call-bind": "^1.0.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", "dev": true }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "engines": { - "node": ">=16 || 14 >=14.17" + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" } }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">= 8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=8" + "node": ">= 10.13.0" } }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "bin": { + "jiti": "bin/jiti.js" + } }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "engines": { - "node": "*" + "node_modules/jose": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "node_modules/moment-timezone": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", - "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, "dependencies": { - "moment": "^2.29.4" + "argparse": "^2.0.1" }, - "engines": { - "node": "*" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/monaco-editor": { - "version": "0.47.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.47.0.tgz", - "integrity": "sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==", - "peer": true - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/needle": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", - "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, - "optional": true, "dependencies": { - "iconv-lite": "^0.6.3", - "sax": "^1.2.4" + "minimist": "^1.2.0" }, "bin": { - "needle": "bin/needle" + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" }, "engines": { - "node": ">= 4.4.x" + "node": ">=4.0" } }, - "node_modules/needle/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, - "optional": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" + "json-buffer": "3.0.1" } }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, "engines": { - "node": ">= 0.6" + "node": ">=0.10" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/next": { - "version": "14.1.4", - "resolved": "https://registry.npmjs.org/next/-/next-14.1.4.tgz", - "integrity": "sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ==", + "node_modules/less": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", + "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", + "dev": true, "dependencies": { - "@next/env": "14.1.4", - "@swc/helpers": "0.5.2", - "busboy": "1.6.0", - "caniuse-lite": "^1.0.30001579", - "graceful-fs": "^4.2.11", - "postcss": "8.4.31", - "styled-jsx": "5.1.1" + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" }, "bin": { - "next": "dist/bin/next" + "lessc": "bin/lessc" }, "engines": { - "node": ">=18.17.0" + "node": ">=6" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.1.4", - "@next/swc-darwin-x64": "14.1.4", - "@next/swc-linux-arm64-gnu": "14.1.4", - "@next/swc-linux-arm64-musl": "14.1.4", - "@next/swc-linux-x64-gnu": "14.1.4", - "@next/swc-linux-x64-musl": "14.1.4", - "@next/swc-win32-arm64-msvc": "14.1.4", - "@next/swc-win32-ia32-msvc": "14.1.4", - "@next/swc-win32-x64-msvc": "14.1.4" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "sass": { - "optional": true - } + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" } }, - "node_modules/next-auth": { - "version": "4.24.7", - "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.7.tgz", - "integrity": "sha512-iChjE8ov/1K/z98gdKbn2Jw+2vLgJtVV39X+rCP5SGnVQuco7QOr19FRNGMIrD8d3LYhHWV9j9sKLzq1aDWWQQ==", + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, "dependencies": { - "@babel/runtime": "^7.20.13", - "@panva/hkdf": "^1.0.2", - "cookie": "^0.5.0", - "jose": "^4.15.5", - "oauth": "^0.9.15", - "openid-client": "^5.4.0", - "preact": "^10.6.3", - "preact-render-to-string": "^5.1.19", - "uuid": "^8.3.2" - }, - "peerDependencies": { - "next": "^12.2.5 || ^13 || ^14", - "nodemailer": "^6.6.5", - "react": "^17.0.2 || ^18", - "react-dom": "^17.0.2 || ^18" + "pify": "^4.0.1", + "semver": "^5.6.0" }, - "peerDependenciesMeta": { - "nodemailer": { - "optional": true - } + "engines": { + "node": ">=6" } }, - "node_modules/next-auth/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "node_modules/less/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true, "engines": { - "node": ">= 0.6" + "node": ">=6" } }, - "node_modules/next-auth/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "optional": true, "bin": { - "uuid": "dist/bin/uuid" + "semver": "bin/semver" } }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">= 0.8.0" } }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" + "engines": { + "node": ">=6.11.5" } }, - "node_modules/node-abi": { - "version": "3.56.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz", - "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==", + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "semver": "^7.3.5" + "p-locate": "^5.0.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "node_modules/node-abi/node_modules/lru-cache": { + "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lucide-react": { + "version": "0.363.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.363.0.tgz", + "integrity": "sha512-AlsfPCsXQyQx7wwsIgzcKOL9LwC498LIMAo+c0Es5PkHJa33xwmYAkkSoKoJWWWSYQEStqu58/jT4tL2gi32uQ==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "semver": "^6.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/material-symbols": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/material-symbols/-/material-symbols-0.17.1.tgz", + "integrity": "sha512-1kJan8t3U3Fmuu/YPu2MVsL/ODSja71o+J7ODROQfMaCzzal0izY4SATafEKgXUXU+jL0zIiBQdyzsno7vXBvA==" }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", - "dev": true + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" }, - "node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "node_modules/node-dir": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", - "dev": true, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { - "minimatch": "^3.0.2" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">= 0.10.5" + "node": ">=8.6" } }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" + "optional": true, + "bin": { + "mime": "cli.js" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "node": ">=4" } }, - "node_modules/node-fetch-native": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", - "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==", - "dev": true + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "node_modules/node-polyfill-webpack-plugin": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-2.0.1.tgz", - "integrity": "sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A==", - "dev": true, - "dependencies": { - "assert": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.12.0", - "domain-browser": "^4.22.0", - "events": "^3.3.0", - "filter-obj": "^2.0.2", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^4.0.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "^0.0.1", - "type-fest": "^2.14.0", - "url": "^0.11.0", - "util": "^0.12.4", - "vm-browserify": "^1.1.2" + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" }, "engines": { - "node": ">=12" - }, - "peerDependencies": { - "webpack": ">=5" + "node": ">= 0.6" } }, - "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==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "bin": { - "semver": "bin/semver" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, + "node_modules/moment-timezone": { + "version": "0.5.45", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", + "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", "dependencies": { - "path-key": "^3.0.0" + "moment": "^2.29.4" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, + "node_modules/monaco-editor": { + "version": "0.47.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.47.0.tgz", + "integrity": "sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==", + "peer": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" } }, - "node_modules/nypm": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.8.tgz", - "integrity": "sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==", - "dev": true, - "dependencies": { - "citty": "^0.1.6", - "consola": "^3.2.3", - "execa": "^8.0.1", - "pathe": "^1.1.2", - "ufo": "^1.4.0" - }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { - "nypm": "dist/cli.mjs" + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": "^14.16.0 || >=16.10.0" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/nypm/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", "dev": true, + "optional": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" }, - "engines": { - "node": ">=16.17" + "bin": { + "needle": "bin/needle" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/nypm/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 4.4.x" } }, - "node_modules/nypm/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, - "node_modules/nypm/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node_modules/next": { + "version": "14.1.4", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.4.tgz", + "integrity": "sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ==", + "dependencies": { + "@next/env": "14.1.4", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nypm/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, "engines": { - "node": ">=12" + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.1.4", + "@next/swc-darwin-x64": "14.1.4", + "@next/swc-linux-arm64-gnu": "14.1.4", + "@next/swc-linux-arm64-musl": "14.1.4", + "@next/swc-linux-x64-gnu": "14.1.4", + "@next/swc-linux-x64-musl": "14.1.4", + "@next/swc-win32-arm64-msvc": "14.1.4", + "@next/swc-win32-ia32-msvc": "14.1.4", + "@next/swc-win32-x64-msvc": "14.1.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "sass": { + "optional": true + } } }, - "node_modules/nypm/node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, + "node_modules/next-auth": { + "version": "4.24.7", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.7.tgz", + "integrity": "sha512-iChjE8ov/1K/z98gdKbn2Jw+2vLgJtVV39X+rCP5SGnVQuco7QOr19FRNGMIrD8d3LYhHWV9j9sKLzq1aDWWQQ==", "dependencies": { - "path-key": "^4.0.0" + "@babel/runtime": "^7.20.13", + "@panva/hkdf": "^1.0.2", + "cookie": "^0.5.0", + "jose": "^4.15.5", + "oauth": "^0.9.15", + "openid-client": "^5.4.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "peerDependencies": { + "next": "^12.2.5 || ^13 || ^14", + "nodemailer": "^6.6.5", + "react": "^17.0.2 || ^18", + "react-dom": "^17.0.2 || ^18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "nodemailer": { + "optional": true + } } }, - "node_modules/nypm/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "mimic-fn": "^4.0.0" + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^10 || ^12 || >=14" } }, - "node_modules/nypm/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "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==", + "dev": true }, - "node_modules/nypm/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=0.10.0" } }, - "node_modules/nypm/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, "node_modules/oauth": { @@ -16712,22 +6227,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -16835,18 +6334,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/objectorarray": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/objectorarray/-/objectorarray-1.0.5.tgz", - "integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==", - "dev": true - }, - "node_modules/ohash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", - "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", - "dev": true - }, "node_modules/oidc-token-hash": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", @@ -16855,27 +6342,6 @@ "node": "^10.13.0 || >=12.0.0" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -16885,38 +6351,6 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/openid-client": { "version": "5.6.5", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.5.tgz", @@ -16931,22 +6365,6 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/openid-client/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/openid-client/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -16964,87 +6382,6 @@ "node": ">= 0.8.0" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ora/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -17075,44 +6412,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" + "engines": { + "node": ">=6" } }, "node_modules/parent-module": { @@ -17126,23 +6432,6 @@ "node": ">=6" } }, - "node_modules/parse-asn1": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", - "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", - "dev": true, - "dependencies": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "hash-base": "~3.0", - "pbkdf2": "^3.1.2", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -17169,31 +6458,6 @@ "node": ">= 0.10" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -17226,11 +6490,11 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { @@ -17248,60 +6512,16 @@ "node": "14 || >=16.14" } }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true - }, "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, "engines": { - "node": "*" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "node": ">=12" }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/peek-stream": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", - "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "duplexify": "^3.5.0", - "through2": "^2.0.3" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/picocolors": { @@ -17358,39 +6578,67 @@ } }, "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "find-up": "^5.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/pnp-webpack-plugin": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz", - "integrity": "sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==", + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "ts-pnp": "^1.1.6" + "p-try": "^2.0.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/polished": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", - "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "@babel/runtime": "^7.17.8" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, "node_modules/possible-typed-array-names": { @@ -17519,146 +6767,6 @@ "node": ">= 14" } }, - "node_modules/postcss-loader": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", - "dev": true, - "dependencies": { - "cosmiconfig": "^8.3.5", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-loader/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/postcss-loader/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postcss-loader/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/postcss-loader/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", - "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", - "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/postcss-nested": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", @@ -17714,85 +6822,6 @@ "preact": ">=10" } }, - "node_modules/preact-render-to-string/node_modules/pretty-format": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", - "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" - }, - "node_modules/prebuild-install": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", - "dev": true, - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/prebuild-install/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prebuild-install/node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/prebuild-install/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -17837,50 +6866,10 @@ } } }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true, - "engines": { - "node": ">= 0.8" - } + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" }, "node_modules/prisma": { "version": "5.11.0", @@ -17898,34 +6887,6 @@ "node": ">=16.13" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -17936,11 +6897,6 @@ "react-is": "^16.13.1" } }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, "node_modules/protobufjs": { "version": "7.2.6", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", @@ -17964,19 +6920,6 @@ "node": ">=12.0.0" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -17984,57 +6927,6 @@ "dev": true, "optional": true }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -18044,39 +6936,6 @@ "node": ">=6" } }, - "node_modules/qs": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", - "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dev": true, - "dependencies": { - "inherits": "~2.0.3" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -18096,22 +6955,6 @@ } ] }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, - "node_modules/ramda": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz", - "integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ramda" - } - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -18121,64 +6964,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -18190,16 +6975,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-colorful": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", - "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", - "dev": true, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "node_modules/react-day-picker": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.0.tgz", @@ -18213,42 +6988,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/react-docgen": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.0.3.tgz", - "integrity": "sha512-i8aF1nyKInZnANZ4uZrH49qn1paRgBZ7wZiCNBMnenlPzEv0mRl+ShpTVEI6wZNl8sSc79xZkivtgLKQArcanQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.18.9", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9", - "@types/babel__core": "^7.18.0", - "@types/babel__traverse": "^7.18.0", - "@types/doctrine": "^0.0.9", - "@types/resolve": "^1.20.2", - "doctrine": "^3.0.0", - "resolve": "^1.22.1", - "strip-indent": "^4.0.0" - }, - "engines": { - "node": ">=16.14.0" - } - }, - "node_modules/react-docgen-typescript": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz", - "integrity": "sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==", - "dev": true, - "peerDependencies": { - "typescript": ">= 4.3.x" - } - }, - "node_modules/react-docgen/node_modules/@types/doctrine": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", - "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", - "dev": true - }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -18261,41 +7000,10 @@ "react": "^18.2.0" } }, - "node_modules/react-element-to-jsx-string": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz", - "integrity": "sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==", - "dev": true, - "dependencies": { - "@base2/pretty-print-object": "1.0.1", - "is-plain-object": "5.0.0", - "react-is": "18.1.0" - }, - "peerDependencies": { - "react": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", - "react-dom": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0" - } - }, - "node_modules/react-element-to-jsx-string/node_modules/react-is": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", - "dev": true - }, "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/react-refresh": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", - "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-remove-scroll": { "version": "2.5.5", @@ -18386,187 +7094,69 @@ } }, "node_modules/react-style-singleton": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", - "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", - "dependencies": { - "get-nonce": "^1.0.0", - "invariant": "^2.2.4", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-toastify": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", - "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==", - "dependencies": { - "clsx": "^2.1.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, - "node_modules/react-transition-state": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-2.1.1.tgz", - "integrity": "sha512-kQx5g1FVu9knoz1T1WkapjUgFz08qQ/g1OmuWGi3/AoEFfS0kStxrPlZx81urjCXdz2d+1DqLpU6TyLW/Ro04Q==", - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", "dependencies": { - "p-try": "^2.0.0" + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "node_modules/react-toastify": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz", + "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==", "dependencies": { - "p-limit": "^2.2.0" + "clsx": "^2.1.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" } }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" } }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" + "node_modules/react-transition-state": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-2.1.1.tgz", + "integrity": "sha512-kQx5g1FVu9knoz1T1WkapjUgFz08qQ/g1OmuWGi3/AoEFfS0kStxrPlZx81urjCXdz2d+1DqLpU6TyLW/Ro04Q==", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, - "node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "dev": true, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "pify": "^2.3.0" } }, "node_modules/readdirp": { @@ -18580,31 +7170,6 @@ "node": ">=8.10.0" } }, - "node_modules/recast": { - "version": "0.23.6", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.6.tgz", - "integrity": "sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ==", - "dev": true, - "dependencies": { - "ast-types": "^0.16.1", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tiny-invariant": "^1.3.3", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/recast/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/recharts": { "version": "2.12.3", "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.3.tgz", @@ -18635,36 +7200,6 @@ "decimal.js-light": "^2.4.1" } }, - "node_modules/recharts/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/redent/node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", @@ -18686,44 +7221,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", - "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", - "dev": true - }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -18742,101 +7244,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dev": true, - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/rehype-external-links": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rehype-external-links/-/rehype-external-links-3.0.0.tgz", - "integrity": "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==", - "dev": true, - "dependencies": { - "@types/hast": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-is-element": "^3.0.0", - "is-absolute-url": "^4.0.0", - "space-separated-tokens": "^2.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-slug": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", - "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", - "dev": true, - "dependencies": { - "@types/hast": "^3.0.0", - "github-slugger": "^2.0.0", - "hast-util-heading-rank": "^3.0.0", - "hast-util-to-string": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dev": true, - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -18854,15 +7261,6 @@ "node": ">=0.10.0" } }, - "node_modules/requireindex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", - "dev": true, - "engines": { - "node": ">=0.10.5" - } - }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -18880,12 +7278,11 @@ } }, "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/resolve-pkg-maps": { @@ -18897,64 +7294,6 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/resolve-url-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", - "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", - "dev": true, - "dependencies": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.14", - "source-map": "0.6.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/resolve-url-loader/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/resolve-url-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/resolve-url-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -18999,16 +7338,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -19090,44 +7419,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sass-loader": { - "version": "13.3.3", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.3.tgz", - "integrity": "sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==", "dev": true, - "dependencies": { - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } + "optional": true }, "node_modules/sax": { "version": "1.3.0", @@ -19145,76 +7438,72 @@ } }, "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">= 0.8.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "dependencies": { - "ms": "2.0.0" + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, "node_modules/serialize-javascript": { "version": "6.0.2", @@ -19225,21 +7514,6 @@ "randombytes": "^2.1.0" } }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -19272,104 +7546,11 @@ "node": ">= 0.4" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, - "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -19403,282 +7584,64 @@ "engines": { "node": ">= 0.4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", - "dev": true - }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", - "dev": true - }, - "node_modules/state-local": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", - "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dev": true, - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/store2": { - "version": "2.14.3", - "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.3.tgz", - "integrity": "sha512-4QcZ+yx7nzEFiV4BMLnr/pRa5HYzNITX2ri0Zh6sT9EyQHbBHacC6YigllUPU9X3D0f/22QCgfokpKs52YRrUg==", - "dev": true - }, - "node_modules/storybook": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.0.4.tgz", - "integrity": "sha512-FUr3Uc2dSAQ80jINH5fSXz7zD7Ncn08OthROjwRtHAH+jMf4wxyZ+RhF3heFy9xLot2/HXOLIWyHyzZZMtGhxg==", - "dev": true, - "dependencies": { - "@storybook/cli": "8.0.4" - }, - "bin": { - "sb": "index.js", - "storybook": "index.js" + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, - "dependencies": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stream-browserify/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "dev": true + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" }, "node_modules/streamsearch": { "version": "1.1.0", @@ -19688,28 +7651,6 @@ "node": ">=10.0.0" } }, - "node_modules/streamx": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", - "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-width": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", @@ -19886,30 +7827,6 @@ "node": ">=4" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", - "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -19934,20 +7851,13 @@ "node": ">=0.10.0" } }, - "node_modules/style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" + "node": ">=0.8.0" } }, "node_modules/styled-components": { @@ -20081,14 +7991,15 @@ } }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -20114,12 +8025,6 @@ "react": "^16.11.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/synchronous-promise": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.17.tgz", - "integrity": "sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==", - "dev": true - }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", @@ -20135,9 +8040,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", - "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", + "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -20147,7 +8052,7 @@ "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.19.1", + "jiti": "^1.21.0", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", @@ -20196,160 +8101,10 @@ "node": ">=6" } }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", - "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", - "dev": true, - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^2.1.1", - "bare-path": "^2.1.0" - } - }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/telejson": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.2.0.tgz", - "integrity": "sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==", - "dev": true, - "dependencies": { - "memoizerific": "^1.11.3" - } - }, - "node_modules/temp": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", - "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", - "dev": true, - "dependencies": { - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/temp/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/temp/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/tempy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", - "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", - "dev": true, - "dependencies": { - "del": "^6.0.0", - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/terser": { - "version": "5.29.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz", - "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==", + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.0.tgz", + "integrity": "sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -20398,16 +8153,22 @@ } } }, - "node_modules/terser/node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" }, "engines": { - "node": ">=0.4.0" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser/node_modules/commander": { @@ -20441,77 +8202,10 @@ "node": ">=0.8" } }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, - "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -20532,27 +8226,6 @@ "node": ">=8.0" } }, - "node_modules/tocbot": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/tocbot/-/tocbot-4.25.0.tgz", - "integrity": "sha512-kE5wyCQJ40hqUaRVkyQ4z5+4juzYsv/eK+aqD97N62YH0TxFhzJvo22RUQQZdO3YnXAk42ZOfOpjVdy+Z0YokA==", - "dev": true - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, "node_modules/trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", @@ -20565,6 +8238,15 @@ "node": ">=0.10.0" } }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -20577,112 +8259,21 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", - "dev": true, - "engines": { - "node": ">=6.10" - } - }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, - "node_modules/ts-pnp": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", - "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { - "json5": "^2.2.2", + "@types/json5": "^0.0.29", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tsconfig-paths-webpack-plugin": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", - "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.7.0", - "tsconfig-paths": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" } }, "node_modules/tslib": { @@ -20690,45 +8281,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -20741,40 +8293,18 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { - "node": ">=12.20" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", @@ -20854,216 +8384,52 @@ "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "dev": true, "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", - "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", - "dev": true - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dev": true, - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dev": true, - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dev": true, - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, "engines": { - "node": ">= 0.8" + "node": ">=14.17" } }, - "node_modules/unplugin": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.10.0.tgz", - "integrity": "sha512-CuZtvvO8ua2Wl+9q2jEaqH6m3DoQ38N7pvBYQbbaeNlWGvK2l6GHiKi29aIHDPoSxdUzQ7Unevf1/ugil5X6Pg==", + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "dependencies": { - "acorn": "^8.11.3", - "chokidar": "^3.6.0", - "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.6.1" + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" }, - "engines": { - "node": ">=14.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unplugin/node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, "engines": { - "node": ">=0.4.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/unplugin/node_modules/webpack-virtual-modules": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.1.tgz", - "integrity": "sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==", - "dev": true - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 10.0.0" } }, "node_modules/update-browserslist-db": { @@ -21105,22 +8471,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "dev": true, - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, "node_modules/use-callback-ref": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", @@ -21154,19 +8504,6 @@ } } }, - "node_modules/use-resize-observer": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz", - "integrity": "sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==", - "dev": true, - "dependencies": { - "@juggle/resize-observer": "^3.3.1" - }, - "peerDependencies": { - "react": "16.8.0 - 18", - "react-dom": "16.8.0 - 18" - } - }, "node_modules/use-sidecar": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", @@ -21197,9 +8534,9 @@ } }, "node_modules/usehooks-ts": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-2.16.0.tgz", - "integrity": "sha512-bez95WqYujxp6hFdM/CpRDiVPirZPxlMzOH2QB8yopoKQMXpscyZoxOjpEdaxvV+CAWUDSM62cWnqHE0E/MZ7w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-3.0.2.tgz", + "integrity": "sha512-qJScCj8YOxa8RV3Iz2T+2IsydLG0EID5FouTGE7aNFEpFlCXmRrnJiPCESDArKr1FLTaUQSfDQ43UDn7yMLExw==", "dependencies": { "lodash.debounce": "^4.0.8" }, @@ -21210,71 +8547,19 @@ "react": "^16.8.0 || ^17 || ^18" } }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/victory-vendor": { "version": "36.9.2", "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", @@ -21296,12 +8581,6 @@ "d3-timer": "^3.0.1" } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, "node_modules/watchpack": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", @@ -21315,21 +8594,6 @@ "node": ">=10.13.0" } }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, "node_modules/webpack": { "version": "5.91.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", @@ -21377,98 +8641,6 @@ } } }, - "node_modules/webpack-dev-middleware": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.2.tgz", - "integrity": "sha512-Wu+EHmX326YPYUpQLKmKbTyZZJIB8/n6R09pTmB03kJmnMsVPTo9COzHZFr01txwaCAuZvfBJE4ZCHRcKs5JaQ==", - "dev": true, - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.12", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-hot-middleware": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz", - "integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==", - "dev": true, - "dependencies": { - "ansi-html-community": "0.0.8", - "html-entities": "^2.1.0", - "strip-ansi": "^6.0.0" - } - }, "node_modules/webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", @@ -21478,39 +8650,6 @@ "node": ">=10.13.0" } }, - "node_modules/webpack-virtual-modules": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz", - "integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==", - "dev": true - }, - "node_modules/webpack/node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -21533,14 +8672,22 @@ "node": ">=4.0" } }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/which": { @@ -21636,12 +8783,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -21675,20 +8816,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -21765,47 +8892,6 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -21815,10 +8901,9 @@ } }, "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { "version": "1.10.2", diff --git a/ui/package.json b/ui/package.json index 0ea0b49cea..fb85a66d78 100644 --- a/ui/package.json +++ b/ui/package.json @@ -7,14 +7,10 @@ "build": "next build", "start": "next start", "lint": "next lint", - "format": "prettier --write .", - "storybook": "storybook dev -p 6006", - "storybook:clean": "rm -rf ./storybook-static", - "storybook:build": "storybook build", - "storybook:deploy": "storybook build && touch storybook-static/.nojekyll && rm storybook-static/.gitignore && gh-pages -t -d storybook-static && rm -rf ./storybook-static" + "format": "prettier --write ." }, "dependencies": { - "@grpc/grpc-js": "^1.10.3", + "@grpc/grpc-js": "^1.10.4", "@monaco-editor/react": "^4.6.0", "@prisma/client": "^5.11.0", "@radix-ui/react-checkbox": "^1.0.4", @@ -32,13 +28,13 @@ "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-toggle-group": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", - "@tremor/react": "^3.14.1", + "@tremor/react": "^3.15.0", "@types/node": "^20.11.30", - "@types/react": "^18.2.70", + "@types/react": "^18.2.73", "@types/react-dom": "^18.2.22", "classnames": "^2.5.1", "long": "^5.2.3", - "lucide-react": "^0.354.0", + "lucide-react": "^0.363.0", "material-symbols": "^0.17.1", "moment": "^2.30.1", "moment-timezone": "^0.5.45", @@ -53,33 +49,23 @@ "react-toastify": "^10.0.5", "styled-components": "^6.1.8", "swr": "^2.2.5", - "usehooks-ts": "^2.16.0", + "usehooks-ts": "^3.0.2", "zod": "^3.22.4" }, "devDependencies": { - "@storybook/addon-essentials": "^8.0.4", - "@storybook/addon-interactions": "^8.0.4", - "@storybook/addon-links": "^8.0.4", - "@storybook/addon-styling": "^1.3.7", - "@storybook/blocks": "^8.0.0", - "@storybook/nextjs": "^8.0.4", - "@storybook/react": "^8.0.0", - "@storybook/testing-library": "^0.2.2", "autoprefixer": "^10.4.19", "copy-webpack-plugin": "^12.0.2", "eslint": "^8.57.0", "eslint-config-next": "^14.1.4", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-storybook": "^0.8.0", "gh-pages": "^6.1.1", "less": "^4.2.0", "postcss": "^8.4.38", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", "prisma": "^5.11.0", - "storybook": "^8.0.4", "string-width": "^7.1.0", - "tailwindcss": "^3.4.1", + "tailwindcss": "^3.4.3", "tailwindcss-animate": "^1.0.7", "typescript": "^5.4.3", "webpack": "^5.91.0" From bb8545a6c6f1f6e70d940f58fef322a423fae152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 28 Mar 2024 16:36:39 +0000 Subject: [PATCH 26/48] qrep: list views, materialized views, & foreign tables in drop down (#1550) Runs into issues with GetTableSchema when trying to create table on destination --- flow/cmd/peer_data.go | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/flow/cmd/peer_data.go b/flow/cmd/peer_data.go index b61936dc2b..7f8089bb26 100644 --- a/flow/cmd/peer_data.go +++ b/flow/cmd/peer_data.go @@ -88,25 +88,14 @@ func (h *FlowRequestHandler) GetTablesInSchema( defer peerConn.Close(ctx) rows, err := peerConn.Query(ctx, `SELECT DISTINCT ON (t.relname) - t.relname, - CASE - WHEN con.contype = 'p' OR t.relreplident = 'i' OR t.relreplident = 'f' THEN true - ELSE false - END AS can_mirror, - pg_size_pretty(pg_total_relation_size(t.oid)) :: text AS table_size - FROM - pg_class t - LEFT JOIN - pg_namespace n ON t.relnamespace = n.oid - LEFT JOIN - pg_constraint con ON con.conrelid = t.oid AND con.contype = 'p' - WHERE - n.nspname = $1 - AND - t.relkind = 'r' - ORDER BY - t.relname, - can_mirror DESC; + t.relname, + (con.contype = 'p' OR t.relreplident in ('i', 'f')) AS can_mirror, + pg_size_pretty(pg_total_relation_size(t.oid))::text AS table_size + FROM pg_class t + LEFT JOIN pg_namespace n ON t.relnamespace = n.oid + LEFT JOIN pg_constraint con ON con.conrelid = t.oid AND con.contype = 'p' + WHERE n.nspname = $1 AND t.relkind = 'r' + ORDER BY t.relname, can_mirror DESC; `, req.SchemaName) if err != nil { slog.Info("failed to fetch publications", slog.Any("error", err)) @@ -161,7 +150,7 @@ func (h *FlowRequestHandler) GetAllTables( rows, err := peerConn.Query(ctx, "SELECT n.nspname || '.' || c.relname AS schema_table "+ "FROM pg_class c "+ "JOIN pg_namespace n ON c.relnamespace = n.oid "+ - "WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' AND c.relkind = 'r';") + "WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' AND c.relkind IN ('r', 'v', 'm', 'f');") if err != nil { return &protos.AllTablesResponse{Tables: nil}, err } From b2543259c776735a373b947f53385d65328ddcd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Fri, 29 Mar 2024 12:44:11 +0000 Subject: [PATCH 27/48] Snowflake: null out numerics >38 digits (#1554) [See Snowflake docs for numerics](https://docs.snowflake.com/en/sql-reference/data-types-numeric#number) It turns out if decimal in avro is >16 bytes Snowflake rejects the record Avro scale factor always counts against precision. `numeric(10, 3)` with value `10.5` is 5 digits --- flow/connectors/bigquery/qrep.go | 3 +- flow/connectors/bigquery/qrep_avro_sync.go | 41 +++++---- flow/connectors/bigquery/qvalue_convert.go | 42 ++++++---- flow/connectors/clickhouse/qrep_avro_sync.go | 3 +- .../postgres/qrep_query_executor.go | 10 +-- flow/connectors/s3/qrep.go | 3 +- .../snowflake/avro_file_writer_test.go | 8 +- flow/connectors/snowflake/qrep_avro_sync.go | 4 +- flow/connectors/sql/query_executor.go | 14 ++-- flow/connectors/utils/avro/avro_writer.go | 19 ++--- flow/connectors/utils/stream.go | 4 +- flow/e2e/bigquery/bigquery_helper.go | 42 ++-------- flow/e2e/snowflake/peer_flow_sf_test.go | 84 +++++++++++++++---- flow/e2e/snowflake/snowflake_helper.go | 2 +- .../e2e/sqlserver/qrep_flow_sqlserver_test.go | 7 +- flow/e2e/sqlserver/sqlserver_helper.go | 4 +- flow/e2e/test_utils.go | 6 +- flow/model/conversion_avro.go | 46 +++++----- flow/model/qrecord_batch.go | 6 +- flow/model/qrecord_stream.go | 8 +- flow/model/qvalue/avro_converter.go | 68 +++++++++++---- flow/model/{ => qvalue}/qschema.go | 10 +-- 22 files changed, 250 insertions(+), 184 deletions(-) rename flow/model/{ => qvalue}/qschema.go (87%) diff --git a/flow/connectors/bigquery/qrep.go b/flow/connectors/bigquery/qrep.go index e2c2ef58e5..71dda2eea1 100644 --- a/flow/connectors/bigquery/qrep.go +++ b/flow/connectors/bigquery/qrep.go @@ -10,6 +10,7 @@ import ( "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/shared" ) @@ -43,7 +44,7 @@ func (c *BigQueryConnector) replayTableSchemaDeltasQRep( ctx context.Context, config *protos.QRepConfig, partition *protos.QRepPartition, - srcSchema *model.QRecordSchema, + srcSchema *qvalue.QRecordSchema, ) (*bigquery.TableMetadata, error) { destDatasetTable, _ := c.convertToDatasetTable(config.DestinationTableIdentifier) bqTable := c.client.DatasetInProject(c.projectID, destDatasetTable.dataset).Table(destDatasetTable.table) diff --git a/flow/connectors/bigquery/qrep_avro_sync.go b/flow/connectors/bigquery/qrep_avro_sync.go index 82f0d7e687..fce53eebcc 100644 --- a/flow/connectors/bigquery/qrep_avro_sync.go +++ b/flow/connectors/bigquery/qrep_avro_sync.go @@ -247,28 +247,18 @@ func DefineAvroSchema(dstTableName string, syncedAtCol string, softDeleteCol string, ) (*model.QRecordAvroSchemaDefinition, error) { - avroFields := []AvroField{} - nullableFields := make(map[string]struct{}) - + avroFields := make([]AvroField, 0, len(dstTableMetadata.Schema)) + qFields := make([]qvalue.QField, 0, len(avroFields)) for _, bqField := range dstTableMetadata.Schema { if bqField.Name == syncedAtCol || bqField.Name == softDeleteCol { continue } - avroType, err := GetAvroType(bqField) + avroField, err := GetAvroField(bqField) if err != nil { return nil, err } - - // If a field is nullable, its Avro type should be ["null", actualType] - if !bqField.Required { - avroType = []interface{}{"null", avroType} - nullableFields[bqField.Name] = struct{}{} - } - - avroFields = append(avroFields, AvroField{ - Name: bqField.Name, - Type: avroType, - }) + avroFields = append(avroFields, avroField) + qFields = append(qFields, BigQueryFieldToQField(bqField)) } avroSchema := AvroSchema{ @@ -283,8 +273,8 @@ func DefineAvroSchema(dstTableName string, } return &model.QRecordAvroSchemaDefinition{ - Schema: string(avroSchemaJSON), - NullableFields: nullableFields, + Schema: string(avroSchemaJSON), + Fields: qFields, }, nil } @@ -396,6 +386,23 @@ func GetAvroType(bqField *bigquery.FieldSchema) (interface{}, error) { } } +func GetAvroField(bqField *bigquery.FieldSchema) (AvroField, error) { + avroType, err := GetAvroType(bqField) + if err != nil { + return AvroField{}, err + } + + // If a field is nullable, its Avro type should be ["null", actualType] + if !bqField.Required { + avroType = []interface{}{"null", avroType} + } + + return AvroField{ + Name: bqField.Name, + Type: avroType, + }, nil +} + func (s *QRepAvroSyncMethod) writeToStage( ctx context.Context, syncID string, diff --git a/flow/connectors/bigquery/qvalue_convert.go b/flow/connectors/bigquery/qvalue_convert.go index 6a21b217bd..db96a2d590 100644 --- a/flow/connectors/bigquery/qvalue_convert.go +++ b/flow/connectors/bigquery/qvalue_convert.go @@ -1,8 +1,6 @@ package connbigquery import ( - "fmt" - "cloud.google.com/go/bigquery" "github.com/PeerDB-io/peer-flow/model/qvalue" @@ -61,35 +59,35 @@ func qValueKindToBigQueryType(colType string) bigquery.FieldType { } } -// bigqueryTypeToQValueKind converts a bigquery FieldType to a QValueKind. -func BigQueryTypeToQValueKind(fieldType bigquery.FieldType) (qvalue.QValueKind, error) { +// BigQueryTypeToQValueKind converts a bigquery.FieldType to a QValueKind +func BigQueryTypeToQValueKind(fieldType bigquery.FieldType) qvalue.QValueKind { switch fieldType { case bigquery.StringFieldType: - return qvalue.QValueKindString, nil + return qvalue.QValueKindString case bigquery.BytesFieldType: - return qvalue.QValueKindBytes, nil + return qvalue.QValueKindBytes case bigquery.IntegerFieldType: - return qvalue.QValueKindInt64, nil + return qvalue.QValueKindInt64 case bigquery.FloatFieldType: - return qvalue.QValueKindFloat64, nil + return qvalue.QValueKindFloat64 case bigquery.BooleanFieldType: - return qvalue.QValueKindBoolean, nil + return qvalue.QValueKindBoolean case bigquery.TimestampFieldType: - return qvalue.QValueKindTimestamp, nil + return qvalue.QValueKindTimestamp case bigquery.DateFieldType: - return qvalue.QValueKindDate, nil + return qvalue.QValueKindDate case bigquery.TimeFieldType: - return qvalue.QValueKindTime, nil + return qvalue.QValueKindTime case bigquery.RecordFieldType: - return qvalue.QValueKindStruct, nil + return qvalue.QValueKindStruct case bigquery.NumericFieldType, bigquery.BigNumericFieldType: - return qvalue.QValueKindNumeric, nil + return qvalue.QValueKindNumeric case bigquery.GeographyFieldType: - return qvalue.QValueKindGeography, nil + return qvalue.QValueKindGeography case bigquery.JSONFieldType: - return qvalue.QValueKindJSON, nil + return qvalue.QValueKindJSON default: - return "", fmt.Errorf("unsupported bigquery field type: %v", fieldType) + return qvalue.QValueKindInvalid } } @@ -105,3 +103,13 @@ func qValueKindToBigQueryTypeString(colType string) string { } return bqTypeAsString } + +func BigQueryFieldToQField(bqField *bigquery.FieldSchema) qvalue.QField { + return qvalue.QField{ + Name: bqField.Name, + Type: BigQueryTypeToQValueKind(bqField.Type), + Precision: int16(bqField.Precision), + Scale: int16(bqField.Scale), + Nullable: !bqField.Required, + } +} diff --git a/flow/connectors/clickhouse/qrep_avro_sync.go b/flow/connectors/clickhouse/qrep_avro_sync.go index 93627ace71..6b30d48db7 100644 --- a/flow/connectors/clickhouse/qrep_avro_sync.go +++ b/flow/connectors/clickhouse/qrep_avro_sync.go @@ -14,6 +14,7 @@ import ( avro "github.com/PeerDB-io/peer-flow/connectors/utils/avro" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/shared" ) @@ -154,7 +155,7 @@ func (s *ClickhouseAvroSyncMethod) SyncQRepRecords( func (s *ClickhouseAvroSyncMethod) getAvroSchema( dstTableName string, - schema *model.QRecordSchema, + schema *qvalue.QRecordSchema, ) (*model.QRecordAvroSchemaDefinition, error) { avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, protos.DBType_CLICKHOUSE) if err != nil { diff --git a/flow/connectors/postgres/qrep_query_executor.go b/flow/connectors/postgres/qrep_query_executor.go index ea21752720..059ed901a3 100644 --- a/flow/connectors/postgres/qrep_query_executor.go +++ b/flow/connectors/postgres/qrep_query_executor.go @@ -83,8 +83,8 @@ func (qe *QRepQueryExecutor) executeQueryInTx(ctx context.Context, tx pgx.Tx, cu } // FieldDescriptionsToSchema converts a slice of pgconn.FieldDescription to a QRecordSchema. -func (qe *QRepQueryExecutor) fieldDescriptionsToSchema(fds []pgconn.FieldDescription) *model.QRecordSchema { - qfields := make([]model.QField, len(fds)) +func (qe *QRepQueryExecutor) fieldDescriptionsToSchema(fds []pgconn.FieldDescription) *qvalue.QRecordSchema { + qfields := make([]qvalue.QField, len(fds)) for i, fd := range fds { cname := fd.Name ctype := qe.postgresOIDToQValueKind(fd.DataTypeOID) @@ -101,7 +101,7 @@ func (qe *QRepQueryExecutor) fieldDescriptionsToSchema(fds []pgconn.FieldDescrip cnullable := true if ctype == qvalue.QValueKindNumeric { precision, scale := numeric.ParseNumericTypmod(fd.TypeModifier) - qfields[i] = model.QField{ + qfields[i] = qvalue.QField{ Name: cname, Type: ctype, Nullable: cnullable, @@ -109,14 +109,14 @@ func (qe *QRepQueryExecutor) fieldDescriptionsToSchema(fds []pgconn.FieldDescrip Scale: scale, } } else { - qfields[i] = model.QField{ + qfields[i] = qvalue.QField{ Name: cname, Type: ctype, Nullable: cnullable, } } } - return model.NewQRecordSchema(qfields) + return qvalue.NewQRecordSchema(qfields) } func (qe *QRepQueryExecutor) ProcessRows( diff --git a/flow/connectors/s3/qrep.go b/flow/connectors/s3/qrep.go index 0824776c77..a7cfb1df3c 100644 --- a/flow/connectors/s3/qrep.go +++ b/flow/connectors/s3/qrep.go @@ -9,6 +9,7 @@ import ( avro "github.com/PeerDB-io/peer-flow/connectors/utils/avro" "github.com/PeerDB-io/peer-flow/generated/protos" "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/shared" ) @@ -42,7 +43,7 @@ func (c *S3Connector) SyncQRepRecords( func getAvroSchema( dstTableName string, - schema *model.QRecordSchema, + schema *qvalue.QRecordSchema, ) (*model.QRecordAvroSchemaDefinition, error) { avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, protos.DBType_S3) if err != nil { diff --git a/flow/connectors/snowflake/avro_file_writer_test.go b/flow/connectors/snowflake/avro_file_writer_test.go index 9c609a2dd2..10dbb1fee9 100644 --- a/flow/connectors/snowflake/avro_file_writer_test.go +++ b/flow/connectors/snowflake/avro_file_writer_test.go @@ -74,7 +74,7 @@ func generateRecords( nullable bool, numRows uint32, allnulls bool, -) (*model.QRecordStream, *model.QRecordSchema) { +) (*model.QRecordStream, *qvalue.QRecordSchema) { t.Helper() allQValueKinds := []qvalue.QValueKind{ @@ -102,8 +102,8 @@ func generateRecords( numKinds := len(allQValueKinds) - schema := &model.QRecordSchema{ - Fields: make([]model.QField, numKinds), + schema := &qvalue.QRecordSchema{ + Fields: make([]qvalue.QField, numKinds), } // Create sample records @@ -113,7 +113,7 @@ func generateRecords( } for i, kind := range allQValueKinds { - schema.Fields[i] = model.QField{ + schema.Fields[i] = qvalue.QField{ Name: string(kind), Type: kind, Nullable: nullable, diff --git a/flow/connectors/snowflake/qrep_avro_sync.go b/flow/connectors/snowflake/qrep_avro_sync.go index c4b248fc04..0c840bf805 100644 --- a/flow/connectors/snowflake/qrep_avro_sync.go +++ b/flow/connectors/snowflake/qrep_avro_sync.go @@ -141,7 +141,7 @@ func (s *SnowflakeAvroSyncHandler) SyncQRepRecords( func (s *SnowflakeAvroSyncHandler) addMissingColumns( ctx context.Context, - schema *model.QRecordSchema, + schema *qvalue.QRecordSchema, dstTableSchema []*sql.ColumnType, dstTableName string, partition *protos.QRepPartition, @@ -205,7 +205,7 @@ func (s *SnowflakeAvroSyncHandler) addMissingColumns( func (s *SnowflakeAvroSyncHandler) getAvroSchema( dstTableName string, - schema *model.QRecordSchema, + schema *qvalue.QRecordSchema, ) (*model.QRecordAvroSchemaDefinition, error) { avroSchema, err := model.GetAvroSchemaDefinition(dstTableName, schema, protos.DBType_SNOWFLAKE) if err != nil { diff --git a/flow/connectors/sql/query_executor.go b/flow/connectors/sql/query_executor.go index 447da7c712..c5b9dadf0e 100644 --- a/flow/connectors/sql/query_executor.go +++ b/flow/connectors/sql/query_executor.go @@ -29,7 +29,7 @@ type SQLQueryExecutor interface { CheckSchemaExists(ctx context.Context, schemaName string) (bool, error) RecreateSchema(ctx context.Context, schemaName string) error - CreateTable(ctx context.Context, schema *model.QRecordSchema, schemaName string, tableName string) error + CreateTable(ctx context.Context, schema *qvalue.QRecordSchema, schemaName string, tableName string) error CountRows(ctx context.Context, schemaName string, tableName string) (int64, error) ExecuteAndProcessQuery(ctx context.Context, query string, args ...interface{}) (*model.QRecordBatch, error) @@ -101,7 +101,7 @@ func (g *GenericSQLQueryExecutor) RecreateSchema(ctx context.Context, schemaName return nil } -func (g *GenericSQLQueryExecutor) CreateTable(ctx context.Context, schema *model.QRecordSchema, schemaName string, tableName string) error { +func (g *GenericSQLQueryExecutor) CreateTable(ctx context.Context, schema *qvalue.QRecordSchema, schemaName string, tableName string) error { fields := make([]string, 0, len(schema.Fields)) for _, field := range schema.Fields { dbType, ok := g.qvalueKindToDBType[field.Type] @@ -151,15 +151,15 @@ func (g *GenericSQLQueryExecutor) CountSRIDs( return count.Int64, err } -func (g *GenericSQLQueryExecutor) columnTypeToQField(ct *sql.ColumnType) (model.QField, error) { +func (g *GenericSQLQueryExecutor) columnTypeToQField(ct *sql.ColumnType) (qvalue.QField, error) { qvKind, ok := g.dbtypeToQValueKind[ct.DatabaseTypeName()] if !ok { - return model.QField{}, fmt.Errorf("unsupported database type %s", ct.DatabaseTypeName()) + return qvalue.QField{}, fmt.Errorf("unsupported database type %s", ct.DatabaseTypeName()) } nullable, ok := ct.Nullable() - return model.QField{ + return qvalue.QField{ Name: ct.Name(), Type: qvKind, Nullable: ok && nullable, @@ -173,7 +173,7 @@ func (g *GenericSQLQueryExecutor) processRows(ctx context.Context, rows *sqlx.Ro } // Convert dbColTypes to QFields - qfields := make([]model.QField, len(dbColTypes)) + qfields := make([]qvalue.QField, len(dbColTypes)) for i, ct := range dbColTypes { qfield, err := g.columnTypeToQField(ct) if err != nil { @@ -264,7 +264,7 @@ func (g *GenericSQLQueryExecutor) processRows(ctx context.Context, rows *sqlx.Ro // Return a QRecordBatch return &model.QRecordBatch{ Records: records, - Schema: model.NewQRecordSchema(qfields), + Schema: qvalue.NewQRecordSchema(qfields), }, nil } diff --git a/flow/connectors/utils/avro/avro_writer.go b/flow/connectors/utils/avro/avro_writer.go index d9f72dc50a..5ac5b3942e 100644 --- a/flow/connectors/utils/avro/avro_writer.go +++ b/flow/connectors/utils/avro/avro_writer.go @@ -127,8 +127,6 @@ func (p *peerDBOCFWriter) writeRecordsToOCFWriter(ctx context.Context, ocfWriter return 0, fmt.Errorf("failed to get schema from stream: %w", err) } - colNames := schema.GetColumnNames() - numRows := atomic.Uint32{} if ctx != nil { @@ -139,21 +137,20 @@ func (p *peerDBOCFWriter) writeRecordsToOCFWriter(ctx context.Context, ocfWriter defer shutdown() } + avroConverter := model.NewQRecordAvroConverter( + p.avroSchema, + p.targetDWH, + schema.GetColumnNames(), + logger, + ) + for qRecordOrErr := range p.stream.Records { if qRecordOrErr.Err != nil { logger.Error("[avro] failed to get record from stream", slog.Any("error", qRecordOrErr.Err)) return 0, fmt.Errorf("[avro] failed to get record from stream: %w", qRecordOrErr.Err) } - avroConverter := model.NewQRecordAvroConverter( - qRecordOrErr.Record, - p.targetDWH, - p.avroSchema.NullableFields, - colNames, - logger, - ) - - avroMap, err := avroConverter.Convert() + avroMap, err := avroConverter.Convert(qRecordOrErr.Record) if err != nil { logger.Error("failed to convert QRecord to Avro compatible map: ", slog.Any("error", err)) return 0, fmt.Errorf("failed to convert QRecord to Avro compatible map: %w", err) diff --git a/flow/connectors/utils/stream.go b/flow/connectors/utils/stream.go index d6729ca242..9cbe22a362 100644 --- a/flow/connectors/utils/stream.go +++ b/flow/connectors/utils/stream.go @@ -13,8 +13,8 @@ import ( func RecordsToRawTableStream(req *model.RecordsToStreamRequest) (*model.QRecordStream, error) { recordStream := model.NewQRecordStream(1 << 17) - err := recordStream.SetSchema(&model.QRecordSchema{ - Fields: []model.QField{ + err := recordStream.SetSchema(&qvalue.QRecordSchema{ + Fields: []qvalue.QField{ { Name: "_peerdb_uid", Type: qvalue.QValueKindString, diff --git a/flow/e2e/bigquery/bigquery_helper.go b/flow/e2e/bigquery/bigquery_helper.go index 25b7b94e41..c3a429d031 100644 --- a/flow/e2e/bigquery/bigquery_helper.go +++ b/flow/e2e/bigquery/bigquery_helper.go @@ -308,33 +308,13 @@ func toQValue(bqValue bigquery.Value) (qvalue.QValue, error) { } } -func bqFieldSchemaToQField(fieldSchema *bigquery.FieldSchema) (model.QField, error) { - qValueKind, err := peer_bq.BigQueryTypeToQValueKind(fieldSchema.Type) - if err != nil { - return model.QField{}, err - } - - return model.QField{ - Name: fieldSchema.Name, - Type: qValueKind, - Nullable: !fieldSchema.Required, - }, nil -} - // bqSchemaToQRecordSchema converts a bigquery schema to a QRecordSchema. -func bqSchemaToQRecordSchema(schema bigquery.Schema) (*model.QRecordSchema, error) { - fields := make([]model.QField, 0, len(schema)) +func bqSchemaToQRecordSchema(schema bigquery.Schema) *qvalue.QRecordSchema { + fields := make([]qvalue.QField, 0, len(schema)) for _, fieldSchema := range schema { - qField, err := bqFieldSchemaToQField(fieldSchema) - if err != nil { - return nil, err - } - fields = append(fields, qField) + fields = append(fields, peer_bq.BigQueryFieldToQField(fieldSchema)) } - - return &model.QRecordSchema{ - Fields: fields, - }, nil + return &qvalue.QRecordSchema{Fields: fields} } func (b *BigQueryTestHelper) ExecuteAndProcessQuery(query string) (*model.QRecordBatch, error) { @@ -369,17 +349,9 @@ func (b *BigQueryTestHelper) ExecuteAndProcessQuery(query string) (*model.QRecor records = append(records, qValues) } - // Now you should fill the column names as well. Here we assume the schema is - // retrieved from the query itself - var schema *model.QRecordSchema - if it.Schema != nil { - schema, err = bqSchemaToQRecordSchema(it.Schema) - if err != nil { - return nil, err - } - } + // Now fill column names as well. Assume the schema is retrieved from the query itself + schema := bqSchemaToQRecordSchema(it.Schema) - // Return a QRecordBatch return &model.QRecordBatch{ Records: records, Schema: schema, @@ -485,7 +457,7 @@ func qValueKindToBqColTypeString(val qvalue.QValueKind) (string, error) { } } -func (b *BigQueryTestHelper) CreateTable(tableName string, schema *model.QRecordSchema) error { +func (b *BigQueryTestHelper) CreateTable(tableName string, schema *qvalue.QRecordSchema) error { fields := make([]string, 0, len(schema.Fields)) for _, field := range schema.Fields { bqType, err := qValueKindToBqColTypeString(field.Type) diff --git a/flow/e2e/snowflake/peer_flow_sf_test.go b/flow/e2e/snowflake/peer_flow_sf_test.go index f75730658b..34c8b6581e 100644 --- a/flow/e2e/snowflake/peer_flow_sf_test.go +++ b/flow/e2e/snowflake/peer_flow_sf_test.go @@ -82,12 +82,70 @@ func (s PeerFlowE2ETestSuiteSF) Test_Flow_ReplicaIdentity_Index_No_Pkey() { e2e.RequireEnvCanceled(s.t, env) } -func (s PeerFlowE2ETestSuiteSF) Test_Invalid_Geo_SF_Avro_CDC() { +func (s PeerFlowE2ETestSuiteSF) Test_Invalid_Numeric() { + tableName := "test_invalid_numeric" + srcTableName := s.attachSchemaSuffix(tableName) + dstTableName := fmt.Sprintf("%s.%s", s.sfHelper.testSchemaName, tableName) + + _, err := s.Conn().Exec(context.Background(), fmt.Sprintf(` + CREATE TABLE IF NOT EXISTS %s ( + id INT PRIMARY KEY, + num1 NUMERIC(100, 50) NOT NULL, + num2 NUMERIC(100, 50) NOT NULL + ); + `, srcTableName)) + require.NoError(s.t, err) + + _, err = s.Conn().Exec(context.Background(), + fmt.Sprintf("INSERT INTO %s (id, num1, num2) VALUES (1,$1,$2)", srcTableName), + "999999999999999999999999999999999999999", + "9999999999999999") + require.NoError(s.t, err) + + connectionGen := e2e.FlowConnectionGenerationConfig{ + FlowJobName: s.attachSuffix(tableName), + TableNameMapping: map[string]string{srcTableName: dstTableName}, + Destination: s.sfHelper.Peer, + } + + flowConnConfig := connectionGen.GenerateFlowConnectionConfigs() + flowConnConfig.DoInitialSnapshot = true + tc := e2e.NewTemporalClient(s.t) + env := e2e.ExecutePeerflow(tc, peerflow.CDCFlowWorkflow, flowConnConfig, nil) + e2e.SetupCDCFlowStatusQuery(s.t, env, connectionGen) + + e2e.EnvWaitFor(s.t, env, 3*time.Minute, "normalize shapes", func() bool { + records, err := s.sfHelper.ExecuteAndProcessQuery("select num1, num2 from " + dstTableName + " where id = 1") + if err != nil || len(records.Records) == 0 { + return false + } + return records.Records[0][0].Value() == nil && records.Records[0][1].Value() != nil + }) + + // Fewer 9s this time are still invalid, with precision 2 `1` is 3 digits: `1.00` + _, err = s.Conn().Exec(context.Background(), + fmt.Sprintf("INSERT INTO %s (id, num1, num2) VALUES (2,$1,$2)", srcTableName), + "9999999999999999999999999999999999", + "9999999999999999") + e2e.EnvNoError(s.t, env, err) + + e2e.EnvWaitFor(s.t, env, 3*time.Minute, "normalize shapes", func() bool { + records, err := s.sfHelper.ExecuteAndProcessQuery("select num1, num2 from " + dstTableName + " where id = 2") + if err != nil || len(records.Records) == 0 { + return false + } + return records.Records[0][0].Value() == nil && records.Records[0][1].Value() != nil + }) + env.Cancel() + e2e.RequireEnvCanceled(s.t, env) +} + +func (s PeerFlowE2ETestSuiteSF) Test_Invalid_Geo_SF_Avro_CDC() { tableName := "test_invalid_geo_sf_avro_cdc" srcTableName := s.attachSchemaSuffix(tableName) - dstTableName := fmt.Sprintf("%s.%s", s.sfHelper.testSchemaName, "test_invalid_geo_sf_avro_cdc") + dstTableName := fmt.Sprintf("%s.%s", s.sfHelper.testSchemaName, tableName) _, err := s.Conn().Exec(context.Background(), fmt.Sprintf(` CREATE TABLE IF NOT EXISTS %s ( @@ -105,10 +163,10 @@ func (s PeerFlowE2ETestSuiteSF) Test_Invalid_Geo_SF_Avro_CDC() { } flowConnConfig := connectionGen.GenerateFlowConnectionConfigs() - flowConnConfig.MaxBatchSize = 100 // wait for PeerFlowStatusQuery to finish setup // and then insert 10 rows into the source table + tc := e2e.NewTemporalClient(s.t) env := e2e.ExecutePeerflow(tc, peerflow.CDCFlowWorkflow, flowConnConfig, nil) e2e.SetupCDCFlowStatusQuery(s.t, env, connectionGen) // insert 4 invalid shapes and 6 valid shapes into the source table @@ -138,19 +196,19 @@ func (s PeerFlowE2ETestSuiteSF) Test_Invalid_Geo_SF_Avro_CDC() { e2e.EnvWaitFor(s.t, env, 3*time.Minute, "normalize shapes", func() bool { // We inserted 4 invalid shapes in each, // which should be filtered out as null on destination. - lineCount, err := s.sfHelper.CountNonNullRows("test_invalid_geo_sf_avro_cdc", "line") + lineCount, err := s.sfHelper.CountNonNullRows(tableName, "line") if err != nil { return false } // Make sure SRIDs are set - sridCount, err := s.sfHelper.CountSRIDs("test_invalid_geo_sf_avro_cdc", "line") + sridCount, err := s.sfHelper.CountSRIDs(tableName, "line") if err != nil { s.t.Log(err) return false } - polyCount, err := s.sfHelper.CountNonNullRows("test_invalid_geo_sf_avro_cdc", "poly") + polyCount, err := s.sfHelper.CountNonNullRows(tableName, "poly") if err != nil { return false } @@ -167,8 +225,8 @@ func (s PeerFlowE2ETestSuiteSF) Test_Invalid_Geo_SF_Avro_CDC() { return true }) - env.Cancel() + env.Cancel() e2e.RequireEnvCanceled(s.t, env) } @@ -441,11 +499,10 @@ func (s PeerFlowE2ETestSuiteSF) Test_Types_SF() { e2e.EnvWaitFor(s.t, env, 3*time.Minute, "normalize types", func() bool { noNulls, err := s.sfHelper.CheckNull("test_types_sf", []string{ - "c41", "c1", "c2", "c3", "c4", - "c6", "c39", "c40", "id", "c9", "c11", "c12", "c13", "c14", "c15", "c16", "c17", "c18", - "c21", "c22", "c23", "c24", "c28", "c29", "c30", "c31", "c33", "c34", "c35", "c36", - "c37", "c38", "c7", "c8", "c32", "c42", "c43", "c44", "c45", "c46", "c47", "c48", "c49", - "c50", "c51", "c52", "c53", "c54", + "c41", "c1", "c2", "c3", "c4", "c6", "c39", "c40", "id", "c9", "c11", "c12", "c13", + "c14", "c15", "c16", "c17", "c18", "c21", "c22", "c23", "c24", "c28", "c29", "c30", + "c31", "c33", "c34", "c35", "c36", "c37", "c38", "c7", "c8", "c32", "c42", "c43", + "c44", "c45", "c46", "c47", "c48", "c49", "c50", "c51", "c52", "c53", "c54", }) if err != nil { return false @@ -1004,8 +1061,7 @@ func (s PeerFlowE2ETestSuiteSF) Test_Soft_Delete_UD_Same_Batch() { "id,c1,c2,t", ) e2e.EnvWaitFor(s.t, env, 3*time.Minute, "checking soft delete", func() bool { - newerSyncedAtQuery := fmt.Sprintf(` - SELECT COUNT(*) FROM %s WHERE _PEERDB_IS_DELETED`, dstTableName) + newerSyncedAtQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE _PEERDB_IS_DELETED", dstTableName) numNewRows, err := s.sfHelper.RunIntQuery(newerSyncedAtQuery) e2e.EnvNoError(s.t, env, err) return numNewRows == 1 diff --git a/flow/e2e/snowflake/snowflake_helper.go b/flow/e2e/snowflake/snowflake_helper.go index c2a6001b01..84f1f2d0a0 100644 --- a/flow/e2e/snowflake/snowflake_helper.go +++ b/flow/e2e/snowflake/snowflake_helper.go @@ -150,7 +150,7 @@ func (s *SnowflakeTestHelper) ExecuteAndProcessQuery(query string) (*model.QReco return s.testClient.ExecuteAndProcessQuery(context.Background(), query) } -func (s *SnowflakeTestHelper) CreateTable(tableName string, schema *model.QRecordSchema) error { +func (s *SnowflakeTestHelper) CreateTable(tableName string, schema *qvalue.QRecordSchema) error { return s.testClient.CreateTable(context.Background(), schema, s.testSchemaName, tableName) } diff --git a/flow/e2e/sqlserver/qrep_flow_sqlserver_test.go b/flow/e2e/sqlserver/qrep_flow_sqlserver_test.go index 153fa07cc6..358e7c90da 100644 --- a/flow/e2e/sqlserver/qrep_flow_sqlserver_test.go +++ b/flow/e2e/sqlserver/qrep_flow_sqlserver_test.go @@ -17,7 +17,6 @@ import ( "github.com/PeerDB-io/peer-flow/e2e" "github.com/PeerDB-io/peer-flow/e2eshared" "github.com/PeerDB-io/peer-flow/generated/protos" - "github.com/PeerDB-io/peer-flow/model" "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/shared" ) @@ -124,9 +123,9 @@ func (s PeerFlowE2ETestSuiteSQLServer) setupPGDestinationTable(tableName string) require.NoError(s.t, err) } -func getSimpleTableSchema() *model.QRecordSchema { - return &model.QRecordSchema{ - Fields: []model.QField{ +func getSimpleTableSchema() *qvalue.QRecordSchema { + return &qvalue.QRecordSchema{ + Fields: []qvalue.QField{ {Name: "id", Type: qvalue.QValueKindString, Nullable: true}, {Name: "card_id", Type: qvalue.QValueKindString, Nullable: true}, {Name: "v_from", Type: qvalue.QValueKindTimestamp, Nullable: true}, diff --git a/flow/e2e/sqlserver/sqlserver_helper.go b/flow/e2e/sqlserver/sqlserver_helper.go index fe8438dcdb..f764b7accf 100644 --- a/flow/e2e/sqlserver/sqlserver_helper.go +++ b/flow/e2e/sqlserver/sqlserver_helper.go @@ -9,7 +9,7 @@ import ( peersql "github.com/PeerDB-io/peer-flow/connectors/sql" connsqlserver "github.com/PeerDB-io/peer-flow/connectors/sqlserver" "github.com/PeerDB-io/peer-flow/generated/protos" - "github.com/PeerDB-io/peer-flow/model" + "github.com/PeerDB-io/peer-flow/model/qvalue" "github.com/PeerDB-io/peer-flow/shared" ) @@ -65,7 +65,7 @@ func NewSQLServerHelper(name string) (*SQLServerHelper, error) { }, nil } -func (h *SQLServerHelper) CreateTable(schema *model.QRecordSchema, tableName string) error { +func (h *SQLServerHelper) CreateTable(schema *qvalue.QRecordSchema, tableName string) error { err := h.E.CreateTable(context.Background(), schema, h.SchemaName, tableName) if err != nil { return err diff --git a/flow/e2e/test_utils.go b/flow/e2e/test_utils.go index f653c4732e..b50653b062 100644 --- a/flow/e2e/test_utils.go +++ b/flow/e2e/test_utils.go @@ -439,9 +439,9 @@ func RunXminFlowWorkflow(tc client.Client, config *protos.QRepConfig) WorkflowRu return ExecutePeerflow(tc, peerflow.XminFlowWorkflow, config, state) } -func GetOwnersSchema() *model.QRecordSchema { - return &model.QRecordSchema{ - Fields: []model.QField{ +func GetOwnersSchema() *qvalue.QRecordSchema { + return &qvalue.QRecordSchema{ + Fields: []qvalue.QField{ {Name: "id", Type: qvalue.QValueKindString, Nullable: true}, {Name: "card_id", Type: qvalue.QValueKindString, Nullable: true}, {Name: "from", Type: qvalue.QValueKindTimestamp, Nullable: true}, diff --git a/flow/model/conversion_avro.go b/flow/model/conversion_avro.go index 1df765dde4..17a3f2b3f3 100644 --- a/flow/model/conversion_avro.go +++ b/flow/model/conversion_avro.go @@ -11,47 +11,41 @@ import ( ) type QRecordAvroConverter struct { - logger log.Logger - QRecord []qvalue.QValue - NullableFields map[string]struct{} - ColNames []string - TargetDWH protos.DBType + logger log.Logger + Schema *QRecordAvroSchemaDefinition + ColNames []string + TargetDWH protos.DBType } func NewQRecordAvroConverter( - q []qvalue.QValue, + schema *QRecordAvroSchemaDefinition, targetDWH protos.DBType, - nullableFields map[string]struct{}, colNames []string, logger log.Logger, ) *QRecordAvroConverter { return &QRecordAvroConverter{ - QRecord: q, - TargetDWH: targetDWH, - NullableFields: nullableFields, - ColNames: colNames, - logger: logger, + Schema: schema, + TargetDWH: targetDWH, + ColNames: colNames, + logger: logger, } } -func (qac *QRecordAvroConverter) Convert() (map[string]interface{}, error) { - m := make(map[string]interface{}, len(qac.QRecord)) - - for idx, val := range qac.QRecord { - key := qac.ColNames[idx] - _, nullable := qac.NullableFields[key] +func (qac *QRecordAvroConverter) Convert(qrecord []qvalue.QValue) (map[string]interface{}, error) { + m := make(map[string]interface{}, len(qrecord)) + for idx, val := range qrecord { avroVal, err := qvalue.QValueToAvro( val, + &qac.Schema.Fields[idx], qac.TargetDWH, - nullable, qac.logger, ) if err != nil { return nil, fmt.Errorf("failed to convert QValue to Avro-compatible value: %w", err) } - m[key] = avroVal + m[qac.ColNames[idx]] = avroVal } return m, nil @@ -69,17 +63,16 @@ type QRecordAvroSchema struct { } type QRecordAvroSchemaDefinition struct { - NullableFields map[string]struct{} - Schema string + Schema string + Fields []qvalue.QField } func GetAvroSchemaDefinition( dstTableName string, - qRecordSchema *QRecordSchema, + qRecordSchema *qvalue.QRecordSchema, targetDWH protos.DBType, ) (*QRecordAvroSchemaDefinition, error) { avroFields := make([]QRecordAvroField, 0, len(qRecordSchema.Fields)) - nullableFields := make(map[string]struct{}) for _, qField := range qRecordSchema.Fields { avroType, err := qvalue.GetAvroSchemaFromQValueKind(qField.Type, targetDWH, qField.Precision, qField.Scale) @@ -89,7 +82,6 @@ func GetAvroSchemaDefinition( if qField.Nullable { avroType = []interface{}{"null", avroType} - nullableFields[qField.Name] = struct{}{} } avroFields = append(avroFields, QRecordAvroField{ @@ -110,7 +102,7 @@ func GetAvroSchemaDefinition( } return &QRecordAvroSchemaDefinition{ - Schema: string(avroSchemaJSON), - NullableFields: nullableFields, + Schema: string(avroSchemaJSON), + Fields: qRecordSchema.Fields, }, nil } diff --git a/flow/model/qrecord_batch.go b/flow/model/qrecord_batch.go index aaa13ea3e2..6e8fe5f40f 100644 --- a/flow/model/qrecord_batch.go +++ b/flow/model/qrecord_batch.go @@ -16,7 +16,7 @@ import ( // QRecordBatch holds a batch of []QValue slices type QRecordBatch struct { - Schema *QRecordSchema + Schema *qvalue.QRecordSchema Records [][]qvalue.QValue } @@ -30,9 +30,7 @@ func (q *QRecordBatch) ToQRecordStream(buffer int) (*QRecordStream, error) { } for _, record := range q.Records { - stream.Records <- QRecordOrError{ - Record: record, - } + stream.Records <- QRecordOrError{Record: record} } close(stream.Records) }() diff --git a/flow/model/qrecord_stream.go b/flow/model/qrecord_stream.go index b79ece015c..b0d6076294 100644 --- a/flow/model/qrecord_stream.go +++ b/flow/model/qrecord_stream.go @@ -18,14 +18,14 @@ type QRecordOrError struct { } type QRecordSchemaOrError struct { - Schema *QRecordSchema + Schema *qvalue.QRecordSchema Err error } type QRecordStream struct { schema chan QRecordSchemaOrError Records chan QRecordOrError - schemaCache *QRecordSchema + schemaCache *qvalue.QRecordSchema schemaSet bool } @@ -60,7 +60,7 @@ func NewQRecordStream(buffer int) *QRecordStream { } } -func (s *QRecordStream) Schema() (*QRecordSchema, error) { +func (s *QRecordStream) Schema() (*qvalue.QRecordSchema, error) { if s.schemaCache != nil { return s.schemaCache, nil } @@ -70,7 +70,7 @@ func (s *QRecordStream) Schema() (*QRecordSchema, error) { return schemaOrError.Schema, schemaOrError.Err } -func (s *QRecordStream) SetSchema(schema *QRecordSchema) error { +func (s *QRecordStream) SetSchema(schema *qvalue.QRecordSchema) error { if s.schemaSet { return errors.New("Schema already set") } diff --git a/flow/model/qvalue/avro_converter.go b/flow/model/qvalue/avro_converter.go index a3aa17911a..92e06f36e0 100644 --- a/flow/model/qvalue/avro_converter.go +++ b/flow/model/qvalue/avro_converter.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "log/slog" + "math" + "math/big" "time" "github.com/google/uuid" @@ -163,19 +165,19 @@ func GetAvroSchemaFromQValueKind(kind QValueKind, targetDWH protos.DBType, preci } type QValueAvroConverter struct { + *QField logger log.Logger TargetDWH protos.DBType - Nullable bool } -func QValueToAvro(value QValue, targetDWH protos.DBType, nullable bool, logger log.Logger) (interface{}, error) { - if nullable && value.Value() == nil { +func QValueToAvro(value QValue, field *QField, targetDWH protos.DBType, logger log.Logger) (interface{}, error) { + if value.Value() == nil { return nil, nil } c := &QValueAvroConverter{ + QField: field, TargetDWH: targetDWH, - Nullable: nullable, logger: logger, } @@ -289,7 +291,7 @@ func QValueToAvro(value QValue, targetDWH protos.DBType, nullable bool, logger l case QValueString, QValueCIDR, QValueINET, QValueMacaddr, QValueInterval: if c.TargetDWH == protos.DBType_SNOWFLAKE && v.Value() != nil && (len(v.Value().(string)) > 15*1024*1024) { - slog.Warn("Truncating TEXT value > 15MB for Snowflake!") + slog.Warn("Clearing TEXT value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") return c.processNullableUnion("string", "") } @@ -316,7 +318,7 @@ func QValueToAvro(value QValue, targetDWH protos.DBType, nullable bool, logger l case QValueBit: return c.processBytes(v.Val), nil case QValueJSON: - return c.processJSON(v.Val) + return c.processJSON(v.Val), nil case QValueHStore: return c.processHStore(v.Val) case QValueArrayFloat32: @@ -428,7 +430,43 @@ func (c *QValueAvroConverter) processNullableUnion( return value, nil } +var tenInt = big.NewInt(10) + +func countDigits(bi *big.Int) int { + if bi.IsUint64() { + u64 := bi.Uint64() + if u64 < (1 << 53) { + if u64 == 0 { + return 1 + } + return int(math.Log10(float64(u64))) + 1 + } + } else if bi.IsInt64() { + i64 := bi.Int64() + if i64 > -(1 << 53) { + return int(math.Log10(float64(-i64))) + 1 + } + } + + abs := new(big.Int).Abs(bi) + // lg10 may be off by 1, need to verify + lg10 := int(float64(abs.BitLen()) / math.Log2(10)) + check := big.NewInt(int64(lg10)) + return lg10 + abs.Cmp(check.Exp(tenInt, check, nil)) +} + func (c *QValueAvroConverter) processNumeric(num decimal.Decimal) interface{} { + if c.TargetDWH == protos.DBType_SNOWFLAKE { + bidigi := countDigits(num.BigInt()) + avroPrecision, avroScale := DetermineNumericSettingForDWH(c.Precision, c.Scale, c.TargetDWH) + + if bidigi+int(avroScale) > int(avroPrecision) { + slog.Warn("Clearing NUMERIC value with too many digits for Snowflake!", slog.Any("number", num)) + return nil + } else if num.Exponent() < -int32(avroScale) { + num = num.Round(int32(avroScale)) + } + } rat := num.Rat() if c.Nullable { return goavro.Union("bytes.decimal", rat) @@ -443,22 +481,22 @@ func (c *QValueAvroConverter) processBytes(byteData []byte) interface{} { return byteData } -func (c *QValueAvroConverter) processJSON(jsonString string) (interface{}, error) { +func (c *QValueAvroConverter) processJSON(jsonString string) interface{} { if c.Nullable { if c.TargetDWH == protos.DBType_SNOWFLAKE && len(jsonString) > 15*1024*1024 { - slog.Warn("Truncating JSON value > 15MB for Snowflake!") + slog.Warn("Clearing JSON value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") - return goavro.Union("string", ""), nil + return goavro.Union("string", "") } - return goavro.Union("string", jsonString), nil + return goavro.Union("string", jsonString) } if c.TargetDWH == protos.DBType_SNOWFLAKE && len(jsonString) > 15*1024*1024 { - slog.Warn("Truncating JSON value > 15MB for Snowflake!") + slog.Warn("Clearing JSON value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") - return "", nil + return "" } - return jsonString, nil + return jsonString } func (c *QValueAvroConverter) processArrayBoolean(arrayData []bool) interface{} { @@ -513,7 +551,7 @@ func (c *QValueAvroConverter) processHStore(hstore string) (interface{}, error) if c.Nullable { if c.TargetDWH == protos.DBType_SNOWFLAKE && len(jsonString) > 15*1024*1024 { - slog.Warn("Truncating HStore equivalent JSON value > 15MB for Snowflake!") + slog.Warn("Clearing HStore equivalent JSON value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") return goavro.Union("string", ""), nil } @@ -521,7 +559,7 @@ func (c *QValueAvroConverter) processHStore(hstore string) (interface{}, error) } if c.TargetDWH == protos.DBType_SNOWFLAKE && len(jsonString) > 15*1024*1024 { - slog.Warn("Truncating HStore equivalent JSON value > 15MB for Snowflake!") + slog.Warn("Clearing HStore equivalent JSON value > 15MB for Snowflake!") slog.Warn("Check this issue for details: https://github.com/PeerDB-io/peerdb/issues/309") return "", nil } diff --git a/flow/model/qschema.go b/flow/model/qvalue/qschema.go similarity index 87% rename from flow/model/qschema.go rename to flow/model/qvalue/qschema.go index 53fb8059b7..3c121f28c5 100644 --- a/flow/model/qschema.go +++ b/flow/model/qvalue/qschema.go @@ -1,14 +1,12 @@ -package model +package qvalue import ( "strings" - - "github.com/PeerDB-io/peer-flow/model/qvalue" ) type QField struct { Name string - Type qvalue.QValueKind + Type QValueKind Precision int16 Scale int16 Nullable bool @@ -20,9 +18,7 @@ type QRecordSchema struct { // NewQRecordSchema creates a new QRecordSchema. func NewQRecordSchema(fields []QField) *QRecordSchema { - return &QRecordSchema{ - Fields: fields, - } + return &QRecordSchema{Fields: fields} } // EqualNames returns true if the field names are equal. From 925f5bd47a01f3ee21f883b1acfdca58c07979a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Fri, 29 Mar 2024 13:03:04 +0000 Subject: [PATCH 28/48] model.go: move record logic to record.go (#1555) --- flow/model/model.go | 126 ---------------------------------------- flow/model/record.go | 133 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 126 deletions(-) create mode 100644 flow/model/record.go diff --git a/flow/model/model.go b/flow/model/model.go index 275e59f1f5..6e29554132 100644 --- a/flow/model/model.go +++ b/flow/model/model.go @@ -47,16 +47,6 @@ type PullRecordsRequest struct { IdleTimeout time.Duration } -type Record interface { - GetCheckpointID() int64 - GetCommitTime() time.Time - GetDestinationTableName() string - GetSourceTableName() string - // get columns and values for the record - GetItems() *RecordItems - PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) -} - type ToJSONOptions struct { UnnestColumns map[string]struct{} HStoreAsJSON bool @@ -76,37 +66,6 @@ func NewToJSONOptions(unnestCols []string, hstoreAsJSON bool) ToJSONOptions { } } -type BaseRecord struct { - // CheckpointID is the ID of the record. - CheckpointID int64 `json:"checkpointId"` - // BeginMessage.CommitTime.UnixNano(), 16 bytes smaller than time.Time - CommitTimeNano int64 `json:"commitTimeNano"` -} - -func (r *BaseRecord) GetCheckpointID() int64 { - return r.CheckpointID -} - -func (r *BaseRecord) GetCommitTime() time.Time { - return time.Unix(0, r.CommitTimeNano) -} - -type InsertRecord struct { - // Items is a map of column name to value. - Items *RecordItems - // Name of the source table - SourceTableName string - // Name of the destination table - DestinationTableName string - // CommitID is the ID of the commit corresponding to this record. - CommitID int64 - BaseRecord -} - -func (r *InsertRecord) GetDestinationTableName() string { - return r.DestinationTableName -} - func (r *InsertRecord) GetSourceTableName() string { return r.SourceTableName } @@ -122,70 +81,6 @@ func (r *InsertRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts } } -type UpdateRecord struct { - // OldItems is a map of column name to value. - OldItems *RecordItems - // NewItems is a map of column name to value. - NewItems *RecordItems - // unchanged toast columns - UnchangedToastColumns map[string]struct{} - // Name of the source table - SourceTableName string - // Name of the destination table - DestinationTableName string - BaseRecord -} - -func (r *UpdateRecord) GetDestinationTableName() string { - return r.DestinationTableName -} - -func (r *UpdateRecord) GetSourceTableName() string { - return r.SourceTableName -} - -func (r *UpdateRecord) GetItems() *RecordItems { - return r.NewItems -} - -func (r *UpdateRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { - recordCount, ok := mapOfCounts[r.DestinationTableName] - if ok { - recordCount.UpdateCount++ - } -} - -type DeleteRecord struct { - // Items is a map of column name to value. - Items *RecordItems - // unchanged toast columns, filled from latest UpdateRecord - UnchangedToastColumns map[string]struct{} - // Name of the source table - SourceTableName string - // Name of the destination table - DestinationTableName string - BaseRecord -} - -func (r *DeleteRecord) GetDestinationTableName() string { - return r.DestinationTableName -} - -func (r *DeleteRecord) GetSourceTableName() string { - return r.SourceTableName -} - -func (r *DeleteRecord) GetItems() *RecordItems { - return r.Items -} - -func (r *DeleteRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { - recordCount, ok := mapOfCounts[r.DestinationTableName] - if ok { - recordCount.DeleteCount++ - } -} - type TableWithPkey struct { TableName string // SHA256 hash of the primary key columns @@ -239,25 +134,4 @@ type NormalizeResponse struct { EndBatchID int64 } -// being clever and passing the delta back as a regular record instead of heavy CDC refactoring. -type RelationRecord struct { - TableSchemaDelta *protos.TableSchemaDelta `json:"tableSchemaDelta"` - BaseRecord -} - -func (r *RelationRecord) GetDestinationTableName() string { - return r.TableSchemaDelta.DstTableName -} - -func (r *RelationRecord) GetSourceTableName() string { - return r.TableSchemaDelta.SrcTableName -} - -func (r *RelationRecord) GetItems() *RecordItems { - return nil -} - -func (r *RelationRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { -} - type RelationMessageMapping map[uint32]*pglogrepl.RelationMessage diff --git a/flow/model/record.go b/flow/model/record.go new file mode 100644 index 0000000000..b3977943fe --- /dev/null +++ b/flow/model/record.go @@ -0,0 +1,133 @@ +package model + +import ( + "time" + + "github.com/PeerDB-io/peer-flow/generated/protos" +) + +type Record interface { + GetCheckpointID() int64 + GetCommitTime() time.Time + GetDestinationTableName() string + GetSourceTableName() string + // get columns and values for the record + GetItems() *RecordItems + PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) +} + +type BaseRecord struct { + // CheckpointID is the ID of the record. + CheckpointID int64 `json:"checkpointId"` + // BeginMessage.CommitTime.UnixNano(), 16 bytes smaller than time.Time + CommitTimeNano int64 `json:"commitTimeNano"` +} + +func (r *BaseRecord) GetCheckpointID() int64 { + return r.CheckpointID +} + +func (r *BaseRecord) GetCommitTime() time.Time { + return time.Unix(0, r.CommitTimeNano) +} + +type InsertRecord struct { + // Items is a map of column name to value. + Items *RecordItems + // Name of the source table + SourceTableName string + // Name of the destination table + DestinationTableName string + // CommitID is the ID of the commit corresponding to this record. + CommitID int64 + BaseRecord +} + +func (r *InsertRecord) GetDestinationTableName() string { + return r.DestinationTableName +} + +type UpdateRecord struct { + // OldItems is a map of column name to value. + OldItems *RecordItems + // NewItems is a map of column name to value. + NewItems *RecordItems + // unchanged toast columns + UnchangedToastColumns map[string]struct{} + // Name of the source table + SourceTableName string + // Name of the destination table + DestinationTableName string + BaseRecord +} + +func (r *UpdateRecord) GetDestinationTableName() string { + return r.DestinationTableName +} + +func (r *UpdateRecord) GetSourceTableName() string { + return r.SourceTableName +} + +func (r *UpdateRecord) GetItems() *RecordItems { + return r.NewItems +} + +func (r *UpdateRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { + recordCount, ok := mapOfCounts[r.DestinationTableName] + if ok { + recordCount.UpdateCount++ + } +} + +type DeleteRecord struct { + // Items is a map of column name to value. + Items *RecordItems + // unchanged toast columns, filled from latest UpdateRecord + UnchangedToastColumns map[string]struct{} + // Name of the source table + SourceTableName string + // Name of the destination table + DestinationTableName string + BaseRecord +} + +func (r *DeleteRecord) GetDestinationTableName() string { + return r.DestinationTableName +} + +func (r *DeleteRecord) GetSourceTableName() string { + return r.SourceTableName +} + +func (r *DeleteRecord) GetItems() *RecordItems { + return r.Items +} + +func (r *DeleteRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { + recordCount, ok := mapOfCounts[r.DestinationTableName] + if ok { + recordCount.DeleteCount++ + } +} + +// being clever and passing the delta back as a regular record instead of heavy CDC refactoring. +type RelationRecord struct { + TableSchemaDelta *protos.TableSchemaDelta `json:"tableSchemaDelta"` + BaseRecord +} + +func (r *RelationRecord) GetDestinationTableName() string { + return r.TableSchemaDelta.DstTableName +} + +func (r *RelationRecord) GetSourceTableName() string { + return r.TableSchemaDelta.SrcTableName +} + +func (r *RelationRecord) GetItems() *RecordItems { + return nil +} + +func (r *RelationRecord) PopulateCountMap(mapOfCounts map[string]*RecordTypeCounts) { +} From 366acabd9054c1739fbefbaf7a58538109c75ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 1 Apr 2024 13:06:26 +0000 Subject: [PATCH 29/48] PostgresMetadata: implement connector interfaces (#1560) Embed compositions for implicit connector implementations --- flow/cmd/handler.go | 4 +- flow/connectors/bigquery/bigquery.go | 46 ++++----------- flow/connectors/bigquery/qrep.go | 6 -- flow/connectors/bigquery/qrep_avro_sync.go | 4 +- flow/connectors/clickhouse/cdc.go | 37 +----------- flow/connectors/clickhouse/clickhouse.go | 6 +- flow/connectors/clickhouse/normalize.go | 11 +--- flow/connectors/eventhub/eventhub.go | 30 +++------- flow/connectors/external_metadata/store.go | 43 ++++++++------ flow/connectors/kafka/kafka.go | 34 +++-------- flow/connectors/postgres/qrep_sql_sync.go | 2 +- flow/connectors/pubsub/pubsub.go | 42 +++----------- flow/connectors/s3/s3.go | 56 ++++--------------- flow/connectors/snowflake/qrep.go | 6 -- flow/connectors/snowflake/qrep_avro_sync.go | 2 +- flow/connectors/snowflake/snowflake.go | 48 ++++------------ flow/e2e/bigquery/qrep_flow_bq_test.go | 6 +- flow/e2e/postgres/qrep_flow_pg_test.go | 8 +-- flow/e2e/s3/qrep_flow_s3_test.go | 4 +- flow/e2e/snowflake/qrep_flow_sf_test.go | 10 ++-- .../e2e/sqlserver/qrep_flow_sqlserver_test.go | 2 +- flow/e2e/test_utils.go | 2 +- 22 files changed, 112 insertions(+), 297 deletions(-) diff --git a/flow/cmd/handler.go b/flow/cmd/handler.go index 7493fb150b..946ace127b 100644 --- a/flow/cmd/handler.go +++ b/flow/cmd/handler.go @@ -86,7 +86,7 @@ func (h *FlowRequestHandler) createCdcJobEntry(ctx context.Context, return nil } -func (h *FlowRequestHandler) createQrepJobEntry(ctx context.Context, +func (h *FlowRequestHandler) createQRepJobEntry(ctx context.Context, req *protos.CreateQRepFlowRequest, workflowID string, ) error { sourcePeerName := req.QrepConfig.SourcePeer.Name @@ -221,7 +221,7 @@ func (h *FlowRequestHandler) CreateQRepFlow( }, } if req.CreateCatalogEntry { - err := h.createQrepJobEntry(ctx, req, workflowID) + err := h.createQRepJobEntry(ctx, req, workflowID) if err != nil { slog.Error("unable to create flow job entry", slog.Any("error", err), slog.String("flowName", cfg.FlowJobName)) diff --git a/flow/connectors/bigquery/bigquery.go b/flow/connectors/bigquery/bigquery.go index 8426ce6701..75a55f20cd 100644 --- a/flow/connectors/bigquery/bigquery.go +++ b/flow/connectors/bigquery/bigquery.go @@ -33,11 +33,11 @@ const ( ) type BigQueryConnector struct { + *metadataStore.PostgresMetadata logger log.Logger bqConfig *protos.BigqueryConfig client *bigquery.Client storageClient *storage.Client - pgMetadata *metadataStore.PostgresMetadataStore catalogPool *pgxpool.Pool datasetID string projectID string @@ -150,14 +150,14 @@ func NewBigQueryConnector(ctx context.Context, config *protos.BigqueryConfig) (* } return &BigQueryConnector{ - bqConfig: config, - client: client, - datasetID: datasetID, - projectID: projectID, - pgMetadata: metadataStore.NewPostgresMetadataStoreFromCatalog(logger, catalogPool), - storageClient: storageClient, - catalogPool: catalogPool, - logger: logger, + bqConfig: config, + client: client, + datasetID: datasetID, + projectID: projectID, + PostgresMetadata: metadataStore.NewPostgresMetadataFromCatalog(logger, catalogPool), + storageClient: storageClient, + catalogPool: catalogPool, + logger: logger, }, nil } @@ -179,10 +179,6 @@ func (c *BigQueryConnector) ConnectionActive(ctx context.Context) error { return nil } -func (c *BigQueryConnector) NeedsSetupMetadataTables(_ context.Context) bool { - return false -} - func (c *BigQueryConnector) waitForTableReady(ctx context.Context, datasetTable *datasetTable) error { table := c.client.DatasetInProject(c.projectID, datasetTable.dataset).Table(datasetTable.table) maxDuration := 5 * time.Minute @@ -240,26 +236,6 @@ func (c *BigQueryConnector) ReplayTableSchemaDeltas( return nil } -func (c *BigQueryConnector) SetupMetadataTables(_ context.Context) error { - return nil -} - -func (c *BigQueryConnector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.FetchLastOffset(ctx, jobName) -} - -func (c *BigQueryConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { - return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) -} - -func (c *BigQueryConnector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastBatchID(ctx, jobName) -} - -func (c *BigQueryConnector) GetLastNormalizeBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastNormalizeBatchID(ctx, jobName) -} - func (c *BigQueryConnector) getDistinctTableNamesInBatch( ctx context.Context, flowJobName string, @@ -423,7 +399,7 @@ func (c *BigQueryConnector) NormalizeRecords(ctx context.Context, req *model.Nor return nil, mergeErr } - err = c.pgMetadata.UpdateNormalizeBatchID(ctx, req.FlowJobName, batchId) + err = c.UpdateNormalizeBatchID(ctx, req.FlowJobName, batchId) if err != nil { return nil, err } @@ -710,7 +686,7 @@ func (c *BigQueryConnector) SetupNormalizedTable( } func (c *BigQueryConnector) SyncFlowCleanup(ctx context.Context, jobName string) error { - err := c.pgMetadata.DropMetadata(ctx, jobName) + err := c.PostgresMetadata.SyncFlowCleanup(ctx, jobName) if err != nil { return fmt.Errorf("unable to clear metadata for sync flow cleanup: %w", err) } diff --git a/flow/connectors/bigquery/qrep.go b/flow/connectors/bigquery/qrep.go index 71dda2eea1..1f11b97d11 100644 --- a/flow/connectors/bigquery/qrep.go +++ b/flow/connectors/bigquery/qrep.go @@ -103,9 +103,3 @@ func (c *BigQueryConnector) SetupQRepMetadataTables(ctx context.Context, config return nil } - -func (c *BigQueryConnector) IsQRepPartitionSynced(ctx context.Context, - req *protos.IsQRepPartitionSyncedInput, -) (bool, error) { - return c.pgMetadata.IsQrepPartitionSynced(ctx, req.FlowJobName, req.PartitionId) -} diff --git a/flow/connectors/bigquery/qrep_avro_sync.go b/flow/connectors/bigquery/qrep_avro_sync.go index fce53eebcc..738affb85e 100644 --- a/flow/connectors/bigquery/qrep_avro_sync.go +++ b/flow/connectors/bigquery/qrep_avro_sync.go @@ -89,7 +89,7 @@ func (s *QRepAvroSyncMethod) SyncRecords( } lastCP := req.Records.GetLastCheckpoint() - err = s.connector.pgMetadata.FinishBatch(ctx, req.FlowJobName, syncBatchID, lastCP) + err = s.connector.FinishBatch(ctx, req.FlowJobName, syncBatchID, lastCP) if err != nil { return nil, fmt.Errorf("failed to update metadata: %w", err) } @@ -213,7 +213,7 @@ func (s *QRepAvroSyncMethod) SyncQRepRecords( return -1, fmt.Errorf("failed to execute statements in a transaction: %w", err) } - err = s.connector.pgMetadata.FinishQrepPartition(ctx, partition, flowJobName, startTime) + err = s.connector.FinishQRepPartition(ctx, partition, flowJobName, startTime) if err != nil { return -1, err } diff --git a/flow/connectors/clickhouse/cdc.go b/flow/connectors/clickhouse/cdc.go index 9b0911955b..689057b79f 100644 --- a/flow/connectors/clickhouse/cdc.go +++ b/flow/connectors/clickhouse/cdc.go @@ -126,7 +126,7 @@ func (c *ClickhouseConnector) SyncRecords(ctx context.Context, req *model.SyncRe return nil, err } - err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, res.LastSyncedCheckpointID) + err = c.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, res.LastSyncedCheckpointID) if err != nil { c.logger.Error("failed to increment id", slog.Any("error", err)) return nil, err @@ -135,43 +135,8 @@ func (c *ClickhouseConnector) SyncRecords(ctx context.Context, req *model.SyncRe return res, nil } -func (c *ClickhouseConnector) SyncFlowCleanup(ctx context.Context, jobName string) error { - err := c.pgMetadata.DropMetadata(ctx, jobName) - if err != nil { - return err - } - return nil -} - func (c *ClickhouseConnector) ReplayTableSchemaDeltas(_ context.Context, flowJobName string, schemaDeltas []*protos.TableSchemaDelta, ) error { return nil } - -func (c *ClickhouseConnector) NeedsSetupMetadataTables(_ context.Context) bool { - return false -} - -func (c *ClickhouseConnector) SetupMetadataTables(_ context.Context) error { - return nil -} - -func (c *ClickhouseConnector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastBatchID(ctx, jobName) -} - -func (c *ClickhouseConnector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.FetchLastOffset(ctx, jobName) -} - -// update offset for a job -func (c *ClickhouseConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { - err := c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) - if err != nil { - c.logger.Error("failed to update last offset: ", slog.Any("error", err)) - return err - } - - return nil -} diff --git a/flow/connectors/clickhouse/clickhouse.go b/flow/connectors/clickhouse/clickhouse.go index fbd9b75eaa..648ac98906 100644 --- a/flow/connectors/clickhouse/clickhouse.go +++ b/flow/connectors/clickhouse/clickhouse.go @@ -21,8 +21,8 @@ import ( ) type ClickhouseConnector struct { + *metadataStore.PostgresMetadata database *sql.DB - pgMetadata *metadataStore.PostgresMetadataStore tableSchemaMapping map[string]*protos.TableSchema logger log.Logger config *protos.ClickhouseConfig @@ -96,7 +96,7 @@ func NewClickhouseConnector( return nil, fmt.Errorf("failed to open connection to Clickhouse peer: %w", err) } - pgMetadata, err := metadataStore.NewPostgresMetadataStore(ctx) + pgMetadata, err := metadataStore.NewPostgresMetadata(ctx) if err != nil { logger.Error("failed to create postgres metadata store", "error", err) return nil, err @@ -125,7 +125,7 @@ func NewClickhouseConnector( return &ClickhouseConnector{ database: database, - pgMetadata: pgMetadata, + PostgresMetadata: pgMetadata, tableSchemaMapping: nil, config: config, creds: clickhouseS3Creds, diff --git a/flow/connectors/clickhouse/normalize.go b/flow/connectors/clickhouse/normalize.go index de7bf66c6b..148ab771fd 100644 --- a/flow/connectors/clickhouse/normalize.go +++ b/flow/connectors/clickhouse/normalize.go @@ -233,7 +233,7 @@ func (c *ClickhouseConnector) NormalizeRecords(ctx context.Context, req *model.N } endNormalizeBatchId := normBatchID + 1 - err = c.pgMetadata.UpdateNormalizeBatchID(ctx, req.FlowJobName, endNormalizeBatchId) + err = c.UpdateNormalizeBatchID(ctx, req.FlowJobName, endNormalizeBatchId) if err != nil { c.logger.Error("[clickhouse] error while updating normalize batch id", "error", err) return nil, err @@ -286,12 +286,3 @@ func (c *ClickhouseConnector) getDistinctTableNamesInBatch( return tableNames, nil } - -func (c *ClickhouseConnector) GetLastNormalizeBatchID(ctx context.Context, flowJobName string) (int64, error) { - normalizeBatchID, err := c.pgMetadata.GetLastNormalizeBatchID(ctx, flowJobName) - if err != nil { - return 0, fmt.Errorf("error while getting last normalize batch id: %w", err) - } - - return normalizeBatchID, nil -} diff --git a/flow/connectors/eventhub/eventhub.go b/flow/connectors/eventhub/eventhub.go index 1a3e01456a..4ed9315872 100644 --- a/flow/connectors/eventhub/eventhub.go +++ b/flow/connectors/eventhub/eventhub.go @@ -19,8 +19,8 @@ import ( ) type EventHubConnector struct { + *metadataStore.PostgresMetadata config *protos.EventHubGroupConfig - pgMetadata *metadataStore.PostgresMetadataStore creds *azidentity.DefaultAzureCredential hubManager *EventHubManager logger log.Logger @@ -39,17 +39,17 @@ func NewEventHubConnector( } hubManager := NewEventHubManager(defaultAzureCreds, config) - pgMetadata, err := metadataStore.NewPostgresMetadataStore(ctx) + pgMetadata, err := metadataStore.NewPostgresMetadata(ctx) if err != nil { logger.Error("failed to create postgres metadata store", "error", err) return nil, err } return &EventHubConnector{ - config: config, - pgMetadata: pgMetadata, - creds: defaultAzureCreds, - hubManager: hubManager, + PostgresMetadata: pgMetadata, + config: config, + creds: defaultAzureCreds, + hubManager: hubManager, }, nil } @@ -79,18 +79,6 @@ func (c *EventHubConnector) SetupMetadataTables(_ context.Context) error { return nil } -func (c *EventHubConnector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastBatchID(ctx, jobName) -} - -func (c *EventHubConnector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.FetchLastOffset(ctx, jobName) -} - -func (c *EventHubConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { - return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) -} - // returns the number of records synced func (c *EventHubConnector) processBatch( ctx context.Context, @@ -205,7 +193,7 @@ func (c *EventHubConnector) SyncRecords(ctx context.Context, req *model.SyncReco } lastCheckpoint := req.Records.GetLastCheckpoint() - err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) + err = c.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) if err != nil { c.logger.Error("failed to increment id", slog.Any("error", err)) return nil, err @@ -251,7 +239,3 @@ func (c *EventHubConnector) ReplayTableSchemaDeltas(_ context.Context, flowJobNa c.logger.Info("ReplayTableSchemaDeltas for event hub is a no-op") return nil } - -func (c *EventHubConnector) SyncFlowCleanup(ctx context.Context, jobName string) error { - return c.pgMetadata.DropMetadata(ctx, jobName) -} diff --git a/flow/connectors/external_metadata/store.go b/flow/connectors/external_metadata/store.go index 49a4ed4784..e591259512 100644 --- a/flow/connectors/external_metadata/store.go +++ b/flow/connectors/external_metadata/store.go @@ -22,31 +22,31 @@ const ( qrepTableName = "metadata_qrep_partitions" ) -type PostgresMetadataStore struct { +type PostgresMetadata struct { pool *pgxpool.Pool logger log.Logger } -func NewPostgresMetadataStore(ctx context.Context) (*PostgresMetadataStore, error) { +func NewPostgresMetadata(ctx context.Context) (*PostgresMetadata, error) { pool, err := peerdbenv.GetCatalogConnectionPoolFromEnv(ctx) if err != nil { return nil, fmt.Errorf("failed to create catalog connection pool: %w", err) } - return &PostgresMetadataStore{ + return &PostgresMetadata{ pool: pool, logger: logger.LoggerFromCtx(ctx), }, nil } -func NewPostgresMetadataStoreFromCatalog(logger log.Logger, pool *pgxpool.Pool) *PostgresMetadataStore { - return &PostgresMetadataStore{ +func NewPostgresMetadataFromCatalog(logger log.Logger, pool *pgxpool.Pool) *PostgresMetadata { + return &PostgresMetadata{ pool: pool, logger: logger, } } -func (p *PostgresMetadataStore) Ping(ctx context.Context) error { +func (p *PostgresMetadata) Ping(ctx context.Context) error { pingErr := p.pool.Ping(ctx) if pingErr != nil { return fmt.Errorf("metadata db ping failed: %w", pingErr) @@ -55,14 +55,22 @@ func (p *PostgresMetadataStore) Ping(ctx context.Context) error { return nil } -func (p *PostgresMetadataStore) LogFlowInfo(ctx context.Context, flowName string, info string) error { +func (p *PostgresMetadata) LogFlowInfo(ctx context.Context, flowName string, info string) error { _, err := p.pool.Exec(ctx, "INSERT INTO peerdb_stats.flow_errors(flow_name,error_message,error_type) VALUES($1,$2,$3)", flowName, info, "info") return err } -func (p *PostgresMetadataStore) FetchLastOffset(ctx context.Context, jobName string) (int64, error) { +func (p *PostgresMetadata) NeedsSetupMetadataTables(_ context.Context) bool { + return false +} + +func (p *PostgresMetadata) SetupMetadataTables(_ context.Context) error { + return nil +} + +func (p *PostgresMetadata) GetLastOffset(ctx context.Context, jobName string) (int64, error) { row := p.pool.QueryRow(ctx, `SELECT last_offset FROM `+ lastSyncStateTableName+ @@ -83,7 +91,7 @@ func (p *PostgresMetadataStore) FetchLastOffset(ctx context.Context, jobName str return offset.Int64, nil } -func (p *PostgresMetadataStore) GetLastBatchID(ctx context.Context, jobName string) (int64, error) { +func (p *PostgresMetadata) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { row := p.pool.QueryRow(ctx, `SELECT sync_batch_id FROM `+lastSyncStateTableName+` WHERE job_name = $1`, jobName) @@ -103,7 +111,7 @@ func (p *PostgresMetadataStore) GetLastBatchID(ctx context.Context, jobName stri return syncBatchID.Int64, nil } -func (p *PostgresMetadataStore) GetLastNormalizeBatchID(ctx context.Context, jobName string) (int64, error) { +func (p *PostgresMetadata) GetLastNormalizeBatchID(ctx context.Context, jobName string) (int64, error) { rows := p.pool.QueryRow(ctx, `SELECT normalize_batch_id FROM `+ lastSyncStateTableName+ @@ -125,8 +133,7 @@ func (p *PostgresMetadataStore) GetLastNormalizeBatchID(ctx context.Context, job return normalizeBatchID.Int64, nil } -// update offset for a job -func (p *PostgresMetadataStore) UpdateLastOffset(ctx context.Context, jobName string, offset int64) error { +func (p *PostgresMetadata) SetLastOffset(ctx context.Context, jobName string, offset int64) error { p.logger.Info("updating last offset", "offset", offset) _, err := p.pool.Exec(ctx, ` INSERT INTO `+lastSyncStateTableName+` (job_name, last_offset, sync_batch_id) @@ -143,7 +150,7 @@ func (p *PostgresMetadataStore) UpdateLastOffset(ctx context.Context, jobName st return nil } -func (p *PostgresMetadataStore) FinishBatch(ctx context.Context, jobName string, syncBatchID int64, offset int64) error { +func (p *PostgresMetadata) FinishBatch(ctx context.Context, jobName string, syncBatchID int64, offset int64) error { p.logger.Info("finishing batch", "SyncBatchID", syncBatchID, "offset", offset) _, err := p.pool.Exec(ctx, ` INSERT INTO `+lastSyncStateTableName+` (job_name, last_offset, sync_batch_id) @@ -162,7 +169,7 @@ func (p *PostgresMetadataStore) FinishBatch(ctx context.Context, jobName string, return nil } -func (p *PostgresMetadataStore) UpdateNormalizeBatchID(ctx context.Context, jobName string, batchID int64) error { +func (p *PostgresMetadata) UpdateNormalizeBatchID(ctx context.Context, jobName string, batchID int64) error { p.logger.Info("updating normalize batch id for job") _, err := p.pool.Exec(ctx, `UPDATE `+lastSyncStateTableName+ @@ -175,7 +182,7 @@ func (p *PostgresMetadataStore) UpdateNormalizeBatchID(ctx context.Context, jobN return nil } -func (p *PostgresMetadataStore) FinishQrepPartition( +func (p *PostgresMetadata) FinishQRepPartition( ctx context.Context, partition *protos.QRepPartition, jobName string, @@ -195,19 +202,19 @@ func (p *PostgresMetadataStore) FinishQrepPartition( return err } -func (p *PostgresMetadataStore) IsQrepPartitionSynced(ctx context.Context, jobName string, partitionID string) (bool, error) { +func (p *PostgresMetadata) IsQRepPartitionSynced(ctx context.Context, req *protos.IsQRepPartitionSyncedInput) (bool, error) { var exists bool err := p.pool.QueryRow(ctx, `SELECT EXISTS(SELECT * FROM `+qrepTableName+ ` WHERE job_name = $1 AND partition_id = $2)`, - jobName, partitionID).Scan(&exists) + req.FlowJobName, req.PartitionId).Scan(&exists) if err != nil { return false, fmt.Errorf("failed to execute query: %w", err) } return exists, nil } -func (p *PostgresMetadataStore) DropMetadata(ctx context.Context, jobName string) error { +func (p *PostgresMetadata) SyncFlowCleanup(ctx context.Context, jobName string) error { _, err := p.pool.Exec(ctx, `DELETE FROM `+lastSyncStateTableName+` WHERE job_name = $1`, jobName) if err != nil { diff --git a/flow/connectors/kafka/kafka.go b/flow/connectors/kafka/kafka.go index 6d878f7bfd..aff9e31505 100644 --- a/flow/connectors/kafka/kafka.go +++ b/flow/connectors/kafka/kafka.go @@ -26,9 +26,9 @@ import ( ) type KafkaConnector struct { - client *kgo.Client - pgMetadata *metadataStore.PostgresMetadataStore - logger log.Logger + *metadataStore.PostgresMetadata + client *kgo.Client + logger log.Logger } func NewKafkaConnector( @@ -77,15 +77,15 @@ func NewKafkaConnector( return nil, fmt.Errorf("failed to create kafka client: %w", err) } - pgMetadata, err := metadataStore.NewPostgresMetadataStore(ctx) + pgMetadata, err := metadataStore.NewPostgresMetadata(ctx) if err != nil { return nil, err } return &KafkaConnector{ - client: client, - pgMetadata: pgMetadata, - logger: logger.LoggerFromCtx(ctx), + PostgresMetadata: pgMetadata, + client: client, + logger: logger.LoggerFromCtx(ctx), }, nil } @@ -104,18 +104,6 @@ func (c *KafkaConnector) CreateRawTable(ctx context.Context, req *protos.CreateR return &protos.CreateRawTableOutput{TableIdentifier: "n/a"}, nil } -func (c *KafkaConnector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastBatchID(ctx, jobName) -} - -func (c *KafkaConnector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.FetchLastOffset(ctx, jobName) -} - -func (c *KafkaConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { - return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) -} - func (c *KafkaConnector) NeedsSetupMetadataTables(_ context.Context) bool { return false } @@ -128,10 +116,6 @@ func (c *KafkaConnector) ReplayTableSchemaDeltas(_ context.Context, flowJobName return nil } -func (c *KafkaConnector) SyncFlowCleanup(ctx context.Context, jobName string) error { - return c.pgMetadata.DropMetadata(ctx, jobName) -} - func lvalueToKafkaRecord(ls *lua.LState, value lua.LValue) (*kgo.Record, error) { var kr *kgo.Record switch v := value.(type) { @@ -199,7 +183,7 @@ func (c *KafkaConnector) SyncRecords(ctx context.Context, req *model.SyncRecords for i := range top { ss[i] = ls.ToStringMeta(ls.Get(i + 1)).String() } - _ = c.pgMetadata.LogFlowInfo(ctx, req.FlowJobName, strings.Join(ss, "\t")) + _ = c.LogFlowInfo(ctx, req.FlowJobName, strings.Join(ss, "\t")) return 0 }) if err != nil { @@ -258,7 +242,7 @@ func (c *KafkaConnector) SyncRecords(ctx context.Context, req *model.SyncRecords } lastCheckpoint := req.Records.GetLastCheckpoint() - err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) + err = c.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) if err != nil { return nil, err } diff --git a/flow/connectors/postgres/qrep_sql_sync.go b/flow/connectors/postgres/qrep_sql_sync.go index bd0e78f32a..5a90cfdf18 100644 --- a/flow/connectors/postgres/qrep_sql_sync.go +++ b/flow/connectors/postgres/qrep_sql_sync.go @@ -203,7 +203,7 @@ func (s *QRepStagingTableSync) SyncQRepRecords( "INSERT INTO %s VALUES ($1, $2, $3, $4, $5);", metadataTableIdentifier.Sanitize(), ) - s.connector.logger.Info("Executing transaction inside Qrep sync", syncLog) + s.connector.logger.Info("Executing transaction inside QRep sync", syncLog) _, err = tx.Exec( context.Background(), insertMetadataStmt, diff --git a/flow/connectors/pubsub/pubsub.go b/flow/connectors/pubsub/pubsub.go index 111c9815d9..1481f624d6 100644 --- a/flow/connectors/pubsub/pubsub.go +++ b/flow/connectors/pubsub/pubsub.go @@ -20,9 +20,9 @@ import ( ) type PubSubConnector struct { - client *pubsub.Client - pgMetadata *metadataStore.PostgresMetadataStore - logger log.Logger + *metadataStore.PostgresMetadata + client *pubsub.Client + logger log.Logger } func NewPubSubConnector( @@ -35,15 +35,15 @@ func NewPubSubConnector( return nil, fmt.Errorf("failed to create pubsub client: %w", err) } - pgMetadata, err := metadataStore.NewPostgresMetadataStore(ctx) + pgMetadata, err := metadataStore.NewPostgresMetadata(ctx) if err != nil { return nil, err } return &PubSubConnector{ - client: client, - pgMetadata: pgMetadata, - logger: logger.LoggerFromCtx(ctx), + client: client, + PostgresMetadata: pgMetadata, + logger: logger.LoggerFromCtx(ctx), }, nil } @@ -64,34 +64,10 @@ func (c *PubSubConnector) CreateRawTable(ctx context.Context, req *protos.Create return &protos.CreateRawTableOutput{TableIdentifier: "n/a"}, nil } -func (c *PubSubConnector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastBatchID(ctx, jobName) -} - -func (c *PubSubConnector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.FetchLastOffset(ctx, jobName) -} - -func (c *PubSubConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { - return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) -} - -func (c *PubSubConnector) NeedsSetupMetadataTables(_ context.Context) bool { - return false -} - -func (c *PubSubConnector) SetupMetadataTables(_ context.Context) error { - return nil -} - func (c *PubSubConnector) ReplayTableSchemaDeltas(_ context.Context, flowJobName string, schemaDeltas []*protos.TableSchemaDelta) error { return nil } -func (c *PubSubConnector) SyncFlowCleanup(ctx context.Context, jobName string) error { - return c.pgMetadata.DropMetadata(ctx, jobName) -} - func lvalueToPubSubMessage(ls *lua.LState, value lua.LValue) (string, *pubsub.Message, error) { var topic string var msg *pubsub.Message @@ -143,7 +119,7 @@ func (c *PubSubConnector) SyncRecords(ctx context.Context, req *model.SyncRecord for i := range top { ss[i] = ls.ToStringMeta(ls.Get(i + 1)).String() } - _ = c.pgMetadata.LogFlowInfo(ctx, req.FlowJobName, strings.Join(ss, "\t")) + _ = c.LogFlowInfo(ctx, req.FlowJobName, strings.Join(ss, "\t")) return 0 }) if err != nil { @@ -247,7 +223,7 @@ func (c *PubSubConnector) SyncRecords(ctx context.Context, req *model.SyncRecord } lastCheckpoint := req.Records.GetLastCheckpoint() - err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) + err = c.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) if err != nil { return nil, err } diff --git a/flow/connectors/s3/s3.go b/flow/connectors/s3/s3.go index 3003f5eb53..3440bd26d5 100644 --- a/flow/connectors/s3/s3.go +++ b/flow/connectors/s3/s3.go @@ -23,11 +23,11 @@ const ( ) type S3Connector struct { - logger log.Logger - pgMetadata *metadataStore.PostgresMetadataStore - creds utils.S3PeerCredentials - url string - client s3.Client + *metadataStore.PostgresMetadata + logger log.Logger + creds utils.S3PeerCredentials + url string + client s3.Client } func NewS3Connector( @@ -66,17 +66,17 @@ func NewS3Connector( if err != nil { return nil, fmt.Errorf("failed to create S3 client: %w", err) } - pgMetadata, err := metadataStore.NewPostgresMetadataStore(ctx) + pgMetadata, err := metadataStore.NewPostgresMetadata(ctx) if err != nil { logger.Error("failed to create postgres metadata store", "error", err) return nil, err } return &S3Connector{ - url: config.Url, - pgMetadata: pgMetadata, - client: *s3Client, - creds: s3PeerCreds, - logger: logger, + url: config.Url, + PostgresMetadata: pgMetadata, + client: *s3Client, + creds: s3PeerCreds, + logger: logger, }, nil } @@ -117,14 +117,6 @@ func (c *S3Connector) ValidateCheck(ctx context.Context) error { return fmt.Errorf("failed to delete from bucket: %w", delErr) } - // check if we can ping external metadata - if c.pgMetadata != nil { - err := c.pgMetadata.Ping(ctx) - if err != nil { - return fmt.Errorf("failed to ping external metadata: %w", err) - } - } - return nil } @@ -132,26 +124,6 @@ func (c *S3Connector) ConnectionActive(ctx context.Context) error { return nil } -func (c *S3Connector) NeedsSetupMetadataTables(_ context.Context) bool { - return false -} - -func (c *S3Connector) SetupMetadataTables(_ context.Context) error { - return nil -} - -func (c *S3Connector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastBatchID(ctx, jobName) -} - -func (c *S3Connector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.FetchLastOffset(ctx, jobName) -} - -func (c *S3Connector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { - return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) -} - func (c *S3Connector) SyncRecords(ctx context.Context, req *model.SyncRecordsRequest) (*model.SyncResponse, error) { tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings) streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, req.SyncBatchID) @@ -173,7 +145,7 @@ func (c *S3Connector) SyncRecords(ctx context.Context, req *model.SyncRecordsReq c.logger.Info(fmt.Sprintf("Synced %d records", numRecords)) lastCheckpoint := req.Records.GetLastCheckpoint() - err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) + err = c.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint) if err != nil { c.logger.Error("failed to increment id", "error", err) return nil, err @@ -191,7 +163,3 @@ func (c *S3Connector) ReplayTableSchemaDeltas(_ context.Context, flowJobName str c.logger.Info("ReplayTableSchemaDeltas for S3 is a no-op") return nil } - -func (c *S3Connector) SyncFlowCleanup(ctx context.Context, jobName string) error { - return c.pgMetadata.DropMetadata(ctx, jobName) -} diff --git a/flow/connectors/snowflake/qrep.go b/flow/connectors/snowflake/qrep.go index 7ba84741a9..15cf3e5e72 100644 --- a/flow/connectors/snowflake/qrep.go +++ b/flow/connectors/snowflake/qrep.go @@ -283,9 +283,3 @@ func (c *SnowflakeConnector) dropStage(ctx context.Context, stagingPath string, func (c *SnowflakeConnector) getStageNameForJob(job string) string { return fmt.Sprintf("%s.peerdb_stage_%s", c.rawSchema, job) } - -func (c *SnowflakeConnector) IsQRepPartitionSynced(ctx context.Context, - req *protos.IsQRepPartitionSyncedInput, -) (bool, error) { - return c.pgMetadata.IsQrepPartitionSynced(ctx, req.FlowJobName, req.PartitionId) -} diff --git a/flow/connectors/snowflake/qrep_avro_sync.go b/flow/connectors/snowflake/qrep_avro_sync.go index 0c840bf805..118644bd93 100644 --- a/flow/connectors/snowflake/qrep_avro_sync.go +++ b/flow/connectors/snowflake/qrep_avro_sync.go @@ -129,7 +129,7 @@ func (s *SnowflakeAvroSyncHandler) SyncQRepRecords( } s.connector.logger.Info("Put file to stage in Avro sync for snowflake", partitionLog) - err = s.connector.pgMetadata.FinishQrepPartition(ctx, partition, config.FlowJobName, startTime) + err = s.connector.FinishQRepPartition(ctx, partition, config.FlowJobName, startTime) if err != nil { return -1, err } diff --git a/flow/connectors/snowflake/snowflake.go b/flow/connectors/snowflake/snowflake.go index 743c18a691..f2953392ff 100644 --- a/flow/connectors/snowflake/snowflake.go +++ b/flow/connectors/snowflake/snowflake.go @@ -79,10 +79,10 @@ const ( ) type SnowflakeConnector struct { - database *sql.DB - pgMetadata *metadataStore.PostgresMetadataStore - logger log.Logger - rawSchema string + *metadataStore.PostgresMetadata + database *sql.DB + logger log.Logger + rawSchema string } // creating this to capture array results from snowflake. @@ -213,16 +213,16 @@ func NewSnowflakeConnector( rawSchema = *snowflakeProtoConfig.MetadataSchema } - pgMetadata, err := metadataStore.NewPostgresMetadataStore(ctx) + pgMetadata, err := metadataStore.NewPostgresMetadata(ctx) if err != nil { return nil, fmt.Errorf("could not connect to metadata store: %w", err) } return &SnowflakeConnector{ - database: database, - pgMetadata: pgMetadata, - rawSchema: rawSchema, - logger: logger, + PostgresMetadata: pgMetadata, + database: database, + rawSchema: rawSchema, + logger: logger, }, nil } @@ -241,30 +241,6 @@ func (c *SnowflakeConnector) ConnectionActive(ctx context.Context) error { return c.database.PingContext(ctx) } -func (c *SnowflakeConnector) NeedsSetupMetadataTables(_ context.Context) bool { - return false -} - -func (c *SnowflakeConnector) SetupMetadataTables(_ context.Context) error { - return nil -} - -func (c *SnowflakeConnector) GetLastOffset(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.FetchLastOffset(ctx, jobName) -} - -func (c *SnowflakeConnector) SetLastOffset(ctx context.Context, jobName string, offset int64) error { - return c.pgMetadata.UpdateLastOffset(ctx, jobName, offset) -} - -func (c *SnowflakeConnector) GetLastSyncBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastBatchID(ctx, jobName) -} - -func (c *SnowflakeConnector) GetLastNormalizeBatchID(ctx context.Context, jobName string) (int64, error) { - return c.pgMetadata.GetLastNormalizeBatchID(ctx, jobName) -} - func (c *SnowflakeConnector) getDistinctTableNamesInBatch( ctx context.Context, flowJobName string, @@ -433,7 +409,7 @@ func (c *SnowflakeConnector) SyncRecords(ctx context.Context, req *model.SyncRec return nil, err } - err = c.pgMetadata.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, res.LastSyncedCheckpointID) + err = c.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, res.LastSyncedCheckpointID) if err != nil { return nil, err } @@ -515,7 +491,7 @@ func (c *SnowflakeConnector) NormalizeRecords(ctx context.Context, req *model.No return nil, mergeErr } - err = c.pgMetadata.UpdateNormalizeBatchID(ctx, req.FlowJobName, batchId) + err = c.UpdateNormalizeBatchID(ctx, req.FlowJobName, batchId) if err != nil { return nil, err } @@ -644,7 +620,7 @@ func (c *SnowflakeConnector) CreateRawTable(ctx context.Context, req *protos.Cre } func (c *SnowflakeConnector) SyncFlowCleanup(ctx context.Context, jobName string) error { - err := c.pgMetadata.DropMetadata(ctx, jobName) + err := c.PostgresMetadata.SyncFlowCleanup(ctx, jobName) if err != nil { return fmt.Errorf("unable to clear metadata for sync flow cleanup: %w", err) } diff --git a/flow/e2e/bigquery/qrep_flow_bq_test.go b/flow/e2e/bigquery/qrep_flow_bq_test.go index ae0841f153..182461cc7b 100644 --- a/flow/e2e/bigquery/qrep_flow_bq_test.go +++ b/flow/e2e/bigquery/qrep_flow_bq_test.go @@ -72,7 +72,7 @@ func (s PeerFlowE2ETestSuiteBQ) Test_Complete_QRep_Flow_Avro() { true, "") require.NoError(s.t, err) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) @@ -97,7 +97,7 @@ func (s PeerFlowE2ETestSuiteBQ) Test_Invalid_Timestamps_And_Date_QRep() { "") qrepConfig.WatermarkColumn = "watermark_ts" require.NoError(s.t, err) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) @@ -137,7 +137,7 @@ func (s PeerFlowE2ETestSuiteBQ) Test_PeerDB_Columns_QRep_BQ() { true, "_PEERDB_SYNCED_AT") require.NoError(s.t, err) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) diff --git a/flow/e2e/postgres/qrep_flow_pg_test.go b/flow/e2e/postgres/qrep_flow_pg_test.go index ec121b8930..962efea901 100644 --- a/flow/e2e/postgres/qrep_flow_pg_test.go +++ b/flow/e2e/postgres/qrep_flow_pg_test.go @@ -193,7 +193,7 @@ func (s PeerFlowE2ETestSuitePG) Test_Complete_QRep_Flow_Multi_Insert_PG() { require.NoError(s.t, err) tc := e2e.NewTemporalClient(s.t) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) @@ -230,7 +230,7 @@ func (s PeerFlowE2ETestSuitePG) Test_PeerDB_Columns_QRep_PG() { require.NoError(s.t, err) tc := e2e.NewTemporalClient(s.t) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) @@ -267,7 +267,7 @@ func (s PeerFlowE2ETestSuitePG) Test_No_Rows_QRep_PG() { require.NoError(s.t, err) tc := e2e.NewTemporalClient(s.t) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) } @@ -300,7 +300,7 @@ func (s PeerFlowE2ETestSuitePG) Test_Pause() { config.InitialCopyOnly = false tc := e2e.NewTemporalClient(s.t) - env := e2e.RunQrepFlowWorkflow(tc, config) + env := e2e.RunQRepFlowWorkflow(tc, config) e2e.SignalWorkflow(env, model.FlowSignal, model.PauseSignal) e2e.EnvWaitFor(s.t, env, 3*time.Minute, "pausing", func() bool { diff --git a/flow/e2e/s3/qrep_flow_s3_test.go b/flow/e2e/s3/qrep_flow_s3_test.go index d59378d52c..ecdc8218cf 100644 --- a/flow/e2e/s3/qrep_flow_s3_test.go +++ b/flow/e2e/s3/qrep_flow_s3_test.go @@ -117,7 +117,7 @@ func (s PeerFlowE2ETestSuiteS3) Test_Complete_QRep_Flow_S3() { require.NoError(s.t, err) qrepConfig.StagingPath = s.s3Helper.s3Config.Url - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) @@ -161,7 +161,7 @@ func (s PeerFlowE2ETestSuiteS3) Test_Complete_QRep_Flow_S3_CTID() { qrepConfig.InitialCopyOnly = true qrepConfig.WatermarkColumn = "ctid" - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) diff --git a/flow/e2e/snowflake/qrep_flow_sf_test.go b/flow/e2e/snowflake/qrep_flow_sf_test.go index 2d0d8c5d3a..6f7f79eaec 100644 --- a/flow/e2e/snowflake/qrep_flow_sf_test.go +++ b/flow/e2e/snowflake/qrep_flow_sf_test.go @@ -72,7 +72,7 @@ func (s PeerFlowE2ETestSuiteSF) Test_Complete_QRep_Flow_Avro_SF() { qrepConfig.SetupWatermarkTableOnDestination = true require.NoError(s.t, err) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) @@ -113,7 +113,7 @@ func (s PeerFlowE2ETestSuiteSF) Test_Complete_QRep_Flow_Avro_SF_Upsert_Simple() qrepConfig.SetupWatermarkTableOnDestination = true require.NoError(s.t, err) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) @@ -148,7 +148,7 @@ func (s PeerFlowE2ETestSuiteSF) Test_Complete_QRep_Flow_Avro_SF_S3() { qrepConfig.StagingPath = fmt.Sprintf("s3://peerdb-test-bucket/avro/%s", uuid.New()) qrepConfig.SetupWatermarkTableOnDestination = true - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 5*time.Minute) require.NoError(s.t, env.Error()) @@ -225,7 +225,7 @@ func (s PeerFlowE2ETestSuiteSF) Test_Complete_QRep_Flow_Avro_SF_S3_Integration() qrepConfig.StagingPath = fmt.Sprintf("s3://peerdb-test-bucket/avro/%s", uuid.New()) qrepConfig.SetupWatermarkTableOnDestination = true - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 5*time.Minute) require.NoError(s.t, env.Error()) @@ -263,7 +263,7 @@ func (s PeerFlowE2ETestSuiteSF) Test_PeerDB_Columns_QRep_SF() { qrepConfig.SetupWatermarkTableOnDestination = true require.NoError(s.t, err) - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) diff --git a/flow/e2e/sqlserver/qrep_flow_sqlserver_test.go b/flow/e2e/sqlserver/qrep_flow_sqlserver_test.go index 358e7c90da..8df35168b7 100644 --- a/flow/e2e/sqlserver/qrep_flow_sqlserver_test.go +++ b/flow/e2e/sqlserver/qrep_flow_sqlserver_test.go @@ -171,7 +171,7 @@ func (s PeerFlowE2ETestSuiteSQLServer) Test_Complete_QRep_Flow_SqlServer_Append( WaitBetweenBatchesSeconds: 5, } - env := e2e.RunQrepFlowWorkflow(tc, qrepConfig) + env := e2e.RunQRepFlowWorkflow(tc, qrepConfig) e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) require.NoError(s.t, env.Error()) diff --git a/flow/e2e/test_utils.go b/flow/e2e/test_utils.go index b50653b062..c7f5f74b2b 100644 --- a/flow/e2e/test_utils.go +++ b/flow/e2e/test_utils.go @@ -428,7 +428,7 @@ func CreateQRepWorkflowConfig( return qrepConfig, nil } -func RunQrepFlowWorkflow(tc client.Client, config *protos.QRepConfig) WorkflowRun { +func RunQRepFlowWorkflow(tc client.Client, config *protos.QRepConfig) WorkflowRun { state := peerflow.NewQRepFlowState() return ExecutePeerflow(tc, peerflow.QRepFlowWorkflow, config, state) } From 280c4aa6a9643b47e553f6b7e80961410f8a504d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Mon, 1 Apr 2024 13:13:24 +0000 Subject: [PATCH 30/48] pg: replace MajorVersionCheck with MajorVersion (#1558) Return PGVersion, leaving caller to do comparisons --- flow/cmd/validate_peer.go | 8 ++++---- flow/connectors/postgres/client.go | 26 +++++++++++++------------- flow/connectors/postgres/postgres.go | 8 ++++---- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/flow/cmd/validate_peer.go b/flow/cmd/validate_peer.go index 6a77fbe5ca..2f3b9bc095 100644 --- a/flow/cmd/validate_peer.go +++ b/flow/cmd/validate_peer.go @@ -40,17 +40,17 @@ func (h *FlowRequestHandler) ValidatePeer( defer conn.Close() if req.Peer.Type == protos.DBType_POSTGRES { - isValid, version, err := conn.(*connpostgres.PostgresConnector).MajorVersionCheck(ctx, connpostgres.POSTGRES_12) + pgversion, err := conn.(*connpostgres.PostgresConnector).MajorVersion(ctx) if err != nil { slog.Error("/peer/validate: pg version check", slog.Any("error", err)) return nil, err } - if !isValid { + if pgversion < connpostgres.POSTGRES_12 { return &protos.ValidatePeerResponse{ Status: protos.ValidatePeerStatus_INVALID, - Message: fmt.Sprintf("%s peer %s must be of version 12 or above. Current version: %d", - req.Peer.Type, req.Peer.Name, version), + Message: fmt.Sprintf("Postgres peer %s must be of PG12 or above. Current version: %d", + req.Peer.Name, pgversion), }, nil } } diff --git a/flow/connectors/postgres/client.go b/flow/connectors/postgres/client.go index 012b78a998..20a50cfdc4 100644 --- a/flow/connectors/postgres/client.go +++ b/flow/connectors/postgres/client.go @@ -19,7 +19,7 @@ import ( "github.com/PeerDB-io/peer-flow/shared" ) -type PGVersion int +type PGVersion int32 const ( POSTGRES_12 PGVersion = 120000 @@ -266,12 +266,12 @@ func getSlotInfo(ctx context.Context, conn *pgx.Conn, slotName string, database whereClause = "WHERE database=" + QuoteLiteral(database) } - hasWALStatus, _, err := majorVersionCheck(ctx, conn, POSTGRES_13) + pgversion, err := majorVersion(ctx, conn) if err != nil { return nil, err } walStatusSelector := "wal_status" - if !hasWALStatus { + if pgversion < POSTGRES_13 { walStatusSelector = "'unknown'" } rows, err := conn.Query(ctx, fmt.Sprintf(`SELECT slot_name, redo_lsn::Text,restart_lsn::text,%s, @@ -343,12 +343,12 @@ func (c *PostgresConnector) createSlotAndPublication( if !s.PublicationExists { // check and enable publish_via_partition_root - supportsPubViaRoot, _, err := c.MajorVersionCheck(ctx, POSTGRES_13) + pgversion, err := c.MajorVersion(ctx) if err != nil { return fmt.Errorf("error checking Postgres version: %w", err) } var pubViaRootString string - if supportsPubViaRoot { + if pgversion >= POSTGRES_13 { pubViaRootString = "WITH(publish_via_partition_root=true)" } // Create the publication to help filter changes only for the given tables @@ -390,7 +390,7 @@ func (c *PostgresConnector) createSlotAndPublication( return fmt.Errorf("[slot] error creating replication slot: %w", err) } - ok, _, err := c.MajorVersionCheck(ctx, POSTGRES_13) + pgversion, err := c.MajorVersion(ctx) if err != nil { return fmt.Errorf("[slot] error getting PG version: %w", err) } @@ -400,7 +400,7 @@ func (c *PostgresConnector) createSlotAndPublication( SlotName: res.SlotName, SnapshotName: res.SnapshotName, Err: nil, - SupportsTIDScans: ok, + SupportsTIDScans: pgversion >= POSTGRES_13, } signal.SlotCreated <- slotDetails c.logger.Info("Waiting for clone to complete") @@ -523,18 +523,18 @@ func (c *PostgresConnector) jobMetadataExists(ctx context.Context, jobName strin return result.Bool, nil } -func majorVersionCheck(ctx context.Context, conn *pgx.Conn, majorVersion PGVersion) (bool, int64, error) { - var version pgtype.Int8 +func majorVersion(ctx context.Context, conn *pgx.Conn) (PGVersion, error) { + var version int32 err := conn.QueryRow(ctx, "SELECT current_setting('server_version_num')::INTEGER").Scan(&version) if err != nil { - return false, 0, fmt.Errorf("failed to get server version: %w", err) + return 0, fmt.Errorf("failed to get server version: %w", err) } - return version.Int64 >= int64(majorVersion), version.Int64, nil + return PGVersion(version), nil } -func (c *PostgresConnector) MajorVersionCheck(ctx context.Context, majorVersion PGVersion) (bool, int64, error) { - return majorVersionCheck(ctx, c.conn, majorVersion) +func (c *PostgresConnector) MajorVersion(ctx context.Context) (PGVersion, error) { + return majorVersion(ctx, c.conn) } func (c *PostgresConnector) updateSyncMetadata(ctx context.Context, flowJobName string, lastCP int64, syncBatchID int64, diff --git a/flow/connectors/postgres/postgres.go b/flow/connectors/postgres/postgres.go index f013468534..2dcebb55c3 100644 --- a/flow/connectors/postgres/postgres.go +++ b/flow/connectors/postgres/postgres.go @@ -598,7 +598,7 @@ func (c *PostgresConnector) NormalizeRecords(ctx context.Context, req *model.Nor } }() - supportsMerge, _, err := c.MajorVersionCheck(ctx, POSTGRES_15) + pgversion, err := c.MajorVersion(ctx) if err != nil { return nil, err } @@ -615,7 +615,7 @@ func (c *PostgresConnector) NormalizeRecords(ctx context.Context, req *model.Nor SyncedAtColName: req.SyncedAtColName, SoftDelete: req.SoftDelete, }, - supportsMerge: supportsMerge, + supportsMerge: pgversion >= POSTGRES_15, metadataSchema: c.metadataSchema, logger: c.logger, } @@ -971,7 +971,7 @@ func (c *PostgresConnector) ExportTxSnapshot(ctx context.Context) (*protos.Expor return nil, nil, fmt.Errorf("[export-snapshot] error setting lock_timeout: %w", err) } - ok, _, err := c.MajorVersionCheck(ctx, POSTGRES_13) + pgversion, err := c.MajorVersion(ctx) if err != nil { return nil, nil, fmt.Errorf("[export-snapshot] error getting PG version: %w", err) } @@ -984,7 +984,7 @@ func (c *PostgresConnector) ExportTxSnapshot(ctx context.Context) (*protos.Expor return &protos.ExportTxSnapshotOutput{ SnapshotName: snapshotName, - SupportsTidScans: ok, + SupportsTidScans: pgversion >= POSTGRES_13, }, tx, err } From 64e098025f41518769a09e11cc923e17ecd4587a Mon Sep 17 00:00:00 2001 From: Amogh Bharadwaj Date: Mon, 1 Apr 2024 19:33:43 +0530 Subject: [PATCH 31/48] UI: Add create mirror buttons (#1556) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improves the empty mirrors page by showing buttons to take the user to create the relevant mirror they want Also some add text and link to quickstart Screenshot 2024-03-29 at 7 47 37 PM --- ui/app/dto/MirrorsDTO.ts | 6 +++ ui/app/mirrors/create/mirrorcards.tsx | 40 ++++++++---------- ui/app/mirrors/create/page.tsx | 32 ++++++++------ ui/app/mirrors/create/styles.tsx | 13 +++++- ui/app/mirrors/layout.tsx | 8 +++- ui/app/mirrors/page.tsx | 20 +++++++++ ui/app/mirrors/tables.tsx | 61 +++++++++++++++++---------- 7 files changed, 118 insertions(+), 62 deletions(-) diff --git a/ui/app/dto/MirrorsDTO.ts b/ui/app/dto/MirrorsDTO.ts index 0fbb8b9009..7bf9b0fac2 100644 --- a/ui/app/dto/MirrorsDTO.ts +++ b/ui/app/dto/MirrorsDTO.ts @@ -1,6 +1,12 @@ import { FlowConnectionConfigs, QRepConfig } from '@/grpc_generated/flow'; import { Dispatch, SetStateAction } from 'react'; +export enum MirrorType { + CDC = 'CDC', + QRep = 'Query Replication', + XMin = 'XMin', +} + export type UCreateMirrorResponse = { created: boolean; }; diff --git a/ui/app/mirrors/create/mirrorcards.tsx b/ui/app/mirrors/create/mirrorcards.tsx index 6cf2dcd348..e8e971bd3c 100644 --- a/ui/app/mirrors/create/mirrorcards.tsx +++ b/ui/app/mirrors/create/mirrorcards.tsx @@ -1,62 +1,55 @@ 'use client'; +import { MirrorType } from '@/app/dto/MirrorsDTO'; import { Label } from '@/lib/Label'; import { RowWithRadiobutton } from '@/lib/Layout'; import { RadioButton, RadioButtonGroup } from '@/lib/RadioButtonGroup'; import Link from 'next/link'; import { SetStateAction } from 'react'; +import { MirrorCardStyle } from './styles'; const MirrorCards = ({ + mirrorType, setMirrorType, }: { - setMirrorType: (value: SetStateAction) => void; + mirrorType: MirrorType; + setMirrorType: (value: SetStateAction) => void; }) => { const cards = [ { - title: 'CDC', + title: MirrorType.CDC, description: 'Change-data Capture or CDC refers to replication of changes on the source table to the target table with initial load. This is recommended.', link: 'https://docs.peerdb.io/usecases/Real-time%20CDC/overview', }, { - title: 'Query Replication', + title: MirrorType.QRep, description: 'Query Replication allows you to specify a set of rows to be synced via a SELECT query.', link: 'https://docs.peerdb.io/usecases/Streaming%20Query%20Replication/overview', }, { - title: 'XMIN', + title: MirrorType.XMin, description: 'XMIN mode uses the xmin system column of PostgreSQL as a watermark column for replication.', link: 'https://docs.peerdb.io/sql/commands/create-mirror#xmin-query-replication', }, ]; return ( - setMirrorType(value)}> + setMirrorType(value)} + >
{cards.map((card, index) => { return ( -
- Learn more - + ); })} diff --git a/ui/app/mirrors/create/page.tsx b/ui/app/mirrors/create/page.tsx index c19bc3b995..20937c3ad5 100644 --- a/ui/app/mirrors/create/page.tsx +++ b/ui/app/mirrors/create/page.tsx @@ -13,14 +13,14 @@ import { ProgressCircle } from '@/lib/ProgressCircle'; import { TextField } from '@/lib/TextField'; import { Divider } from '@tremor/react'; import Image from 'next/image'; -import { useRouter } from 'next/navigation'; +import { useRouter, useSearchParams } from 'next/navigation'; import { useEffect, useState } from 'react'; import ReactSelect from 'react-select'; import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import { InfoPopover } from '../../../components/InfoPopover'; import PeerDBCodeEditor from '../../../components/PeerDBEditor'; -import { CDCConfig, TableMapRow } from '../../dto/MirrorsDTO'; +import { CDCConfig, MirrorType, TableMapRow } from '../../dto/MirrorsDTO'; import CDCConfigForm from './cdc/cdc'; import { handleCreateCDC, @@ -58,8 +58,12 @@ function getPeerLabel(peer: Peer) { export default function CreateMirrors() { const router = useRouter(); + const mirrorParam = useSearchParams(); + const mirrorTypeParam = mirrorParam.get('type'); const [mirrorName, setMirrorName] = useState(''); - const [mirrorType, setMirrorType] = useState(''); + const [mirrorType, setMirrorType] = useState( + (mirrorTypeParam as MirrorType) ?? MirrorType.CDC + ); const [creating, setCreating] = useState(false); const [validating, setValidating] = useState(false); const [config, setConfig] = useState(blankCDCSetting); @@ -78,8 +82,8 @@ export default function CreateMirrors() { setPeers(res); }); - if (mirrorType === 'Query Replication' || mirrorType === 'XMIN') { - if (mirrorType === 'XMIN') { + if (mirrorType != MirrorType.CDC) { + if (mirrorType === MirrorType.XMin) { setConfig((curr) => { return { ...curr, setupWatermarkTableOnDestination: true }; }); @@ -120,7 +124,7 @@ export default function CreateMirrors() { > Mirror type - + Mirror Name} action={ @@ -156,7 +160,7 @@ export default function CreateMirrors() { placeholder={`Select the ${ peerEnd === 'src' ? 'source' : 'destination' } peer`} - onChange={(val, action) => + onChange={(val) => handlePeer(val, peerEnd as 'src' | 'dst', setConfig) } options={ @@ -187,7 +191,7 @@ export default function CreateMirrors() { - {mirrorType === 'Query Replication' && ( + {mirrorType === MirrorType.QRep && ( )} @@ -201,9 +205,9 @@ export default function CreateMirrors() { )} {!creating && } - {mirrorType === '' ? ( + {!mirrorType ? ( <> - ) : mirrorType === 'CDC' ? ( + ) : mirrorType === MirrorType.CDC ? ( )} {mirrorType && (
- {mirrorType === 'CDC' && ( + {mirrorType === MirrorType.CDC && ( diff --git a/ui/app/peers/create/[peerType]/schema.ts b/ui/app/peers/create/[peerType]/schema.ts index 687c5e2174..8868272f7e 100644 --- a/ui/app/peers/create/[peerType]/schema.ts +++ b/ui/app/peers/create/[peerType]/schema.ts @@ -1,3 +1,4 @@ +import { ehSchema } from '@/components/PeerForms/Eventhubs/schema'; import * as z from 'zod'; export const peerNameSchema = z @@ -421,3 +422,10 @@ export const psSchema = z.object({ .min(1, { message: 'Client Cert URL must be non-empty' }), }), }); + +export const ehGroupSchema = z.object({ + // string to ehSchema map + eventhubs: z.record(ehSchema).refine((obj) => Object.keys(obj).length > 0, { + message: 'At least 1 Event Hub is required', + }), +}); diff --git a/ui/components/PeerComponent.tsx b/ui/components/PeerComponent.tsx index 589476d226..0f7157cc0c 100644 --- a/ui/components/PeerComponent.tsx +++ b/ui/components/PeerComponent.tsx @@ -37,6 +37,8 @@ export const DBTypeToImageMapping = (peerType: DBType | string) => { case DBType.PUBSUB: case 'PUBSUB': return '/svgs/pubsub.svg'; + case 'EVENTHUBS': + return '/svgs/ms.svg'; default: return '/svgs/pg.svg'; } diff --git a/ui/components/PeerForms/Eventhubs/EventhubConfig.tsx b/ui/components/PeerForms/Eventhubs/EventhubConfig.tsx new file mode 100644 index 0000000000..b5eff969b4 --- /dev/null +++ b/ui/components/PeerForms/Eventhubs/EventhubConfig.tsx @@ -0,0 +1,188 @@ +'use client'; +import { PeerSetter } from '@/app/dto/PeersDTO'; +import { ehSetting } from '@/app/peers/create/[peerType]/helpers/eh'; +import { notifyErr } from '@/app/utils/notify'; +import { InfoPopover } from '@/components/InfoPopover'; +import { EventHubConfig } from '@/grpc_generated/peers'; +import { Button } from '@/lib/Button'; +import { Icon } from '@/lib/Icon'; +import { Label } from '@/lib/Label'; +import { RowWithTextField } from '@/lib/Layout'; +import { TextField } from '@/lib/TextField'; +import { Tooltip } from '@/lib/Tooltip'; +import { Dispatch, SetStateAction, useState } from 'react'; +import { ehSchema } from './schema'; + +interface EventhubConfigProps { + eventhubConfig: EventHubConfig & { + id: number; + }; + updateForms: Dispatch< + SetStateAction< + (EventHubConfig & { + id: number; + })[] + > + >; + onDelete: () => void; +} + +const EventhubsConfig = ({ + eventhubConfig, + updateForms, + onDelete, +}: EventhubConfigProps) => { + const [ehConfig, setEhConfig] = useState< + EventHubConfig & { + id: number; + } + >(eventhubConfig); + const [collapsed, setCollapsed] = useState(false); + + const handleSave = () => { + const ehConfigValidity = ehSchema.safeParse(ehConfig); + if (ehConfigValidity.success) { + updateForms((prev) => + prev.map((config) => { + if (config.id === ehConfig.id) { + return ehConfig; + } + return config; + }) + ); + setCollapsed(true); + } else { + notifyErr(ehConfigValidity.error.issues[0].message); + } + }; + + const getFieldValue = (label: string) => { + if (label === 'Namespace') { + return ehConfig.namespace; + } + if (label === 'Subscription ID') { + return ehConfig.subscriptionId; + } + if (label === 'Resource Group') { + return ehConfig.resourceGroup; + } + if (label === 'Location') { + return ehConfig.location; + } + if (label === 'Partition Count') { + return ehConfig.partitionCount; + } + if (label === 'Message Retention (Days)') { + return ehConfig.messageRetentionInDays; + } + return ''; + }; + + return ( +
+ {collapsed ? ( + + ) : ( + ehSetting.map((setting, index) => { + return ( + + {setting.label}{' '} + {!setting.optional && ( + + + + )} + + } + action={ +
+ ) => + setting.stateHandler( + e.target.value, + setEhConfig as PeerSetter + ) + } + /> + {setting.tips && ( + + )} +
+ } + /> + ); + }) + )} +
+ {!collapsed && ( + + )} +
+ + +
+
+
+ ); +}; + +export default EventhubsConfig; diff --git a/ui/components/PeerForms/Eventhubs/EventhubGroupConfig.tsx b/ui/components/PeerForms/Eventhubs/EventhubGroupConfig.tsx new file mode 100644 index 0000000000..830c907abd --- /dev/null +++ b/ui/components/PeerForms/Eventhubs/EventhubGroupConfig.tsx @@ -0,0 +1,84 @@ +'use client'; +import { PeerSetter } from '@/app/dto/PeersDTO'; +import { blankEventhubSetting } from '@/app/peers/create/[peerType]/helpers/eh'; +import { EventHubConfig, EventHubGroupConfig } from '@/grpc_generated/peers'; +import { Button } from '@/lib/Button'; +import { Icon } from '@/lib/Icon'; +import { Label } from '@/lib/Label'; +import { useEffect, useState } from 'react'; +import { ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; +import EventhubsConfig from './EventhubConfig'; +interface EventhubsProps { + groupConfig: EventHubGroupConfig; + setter: PeerSetter; +} + +const EventhubsForm = ({ groupConfig, setter }: EventhubsProps) => { + const [currConfigForms, setCurrConfigForms] = useState< + (EventHubConfig & { id: number })[] + >([]); + + const handleAddNamespace = () => { + setCurrConfigForms([ + ...currConfigForms, + { ...blankEventhubSetting, id: currConfigForms.length }, + ]); + }; + const handleDeleteNamespace = (id: number) => { + setCurrConfigForms((prev) => prev.filter((_, index) => index !== id)); + }; + + useEffect(() => { + // construct a map of namespace to eventhub config + const eventhubs = currConfigForms.reduce((acc, curr) => { + return { + ...acc, + [curr.namespace]: curr, + }; + }, {}); + setter((prev) => { + return { + ...prev, + eventhubs, + }; + }); + }, [currConfigForms, setter]); + + return ( +
+ + {currConfigForms.map((ehConfig) => { + return ( + handleDeleteNamespace(ehConfig.id)} + /> + ); + })} + + +
+ ); +}; + +export default EventhubsForm; diff --git a/ui/components/PeerForms/Eventhubs/schema.ts b/ui/components/PeerForms/Eventhubs/schema.ts new file mode 100644 index 0000000000..ce90e1f940 --- /dev/null +++ b/ui/components/PeerForms/Eventhubs/schema.ts @@ -0,0 +1,50 @@ +import * as z from 'zod'; + +export const ehSchema = z.object({ + namespace: z + .string({ + required_error: 'Namespace is required', + invalid_type_error: 'Namespace must be a string', + }) + .min(1, { message: 'Namespace cannot be empty' }) + .max(255, { message: 'Namespace cannot be longer than 255 characters' }), + subscriptionId: z + .string({ + required_error: 'Subscription ID is required', + invalid_type_error: 'Subscription ID must be a string', + }) + .min(1, { message: 'Subscription ID cannot be empty' }) + .max(255, { + message: 'Subscription ID cannot be longer than 255 characters', + }), + resourceGroup: z + .string({ + required_error: 'Resource Group is required', + invalid_type_error: 'Resource Group must be a string', + }) + .min(1, { message: 'Resource Group cannot be empty' }) + .max(255, { + message: 'Resource Group cannot be longer than 255 characters', + }), + location: z + .string({ + required_error: 'Location is required', + invalid_type_error: 'Location must be a string', + }) + .min(1, { message: 'Location cannot be empty' }) + .max(255, { message: 'Location cannot be longer than 255 characters' }), + partitionCount: z + .number({ + required_error: 'Partition Count is required', + invalid_type_error: 'Partition Count must be a number', + }) + .int({ message: 'Partition Count must be an integer' }) + .min(1, { message: 'Partition count must be at least 1' }), + messageRetentionInDays: z + .number({ + required_error: 'Message Retention (Days) is required', + invalid_type_error: 'Message Retention (Days) must be a number', + }) + .int({ message: 'Message Retention (Days) must be an integer' }) + .min(1, { message: 'Message retention (days) must be at least 1' }), +}); diff --git a/ui/components/PeerForms/PubSubConfig.tsx b/ui/components/PeerForms/PubSubConfig.tsx index 089f9eb0f7..46985ab0ec 100644 --- a/ui/components/PeerForms/PubSubConfig.tsx +++ b/ui/components/PeerForms/PubSubConfig.tsx @@ -52,16 +52,17 @@ export default function PubSubForm(props: PSProps) { return ( <> - Creating a service account file - + diff --git a/ui/components/SelectSource.tsx b/ui/components/SelectSource.tsx index 4459d3643c..ac30d37c65 100644 --- a/ui/components/SelectSource.tsx +++ b/ui/components/SelectSource.tsx @@ -36,6 +36,7 @@ export default function SelectSource({ value === 'S3' || value === 'CLICKHOUSE' || value === 'KAFKA' || + value === 'EVENTHUBS' || value === 'PUBSUB') ) .map((value) => ({ label: value, value })); From d7798476e70dc2a216a5a40b43535ea38ecf1d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Fri, 5 Apr 2024 18:23:28 +0000 Subject: [PATCH 47/48] RenameTablesConnector (#1572) --- flow/activities/flowable.go | 23 ++++------------------- flow/connectors/core.go | 23 ++++++++++++++++------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/flow/activities/flowable.go b/flow/activities/flowable.go index 766243d8ee..e1795e3253 100644 --- a/flow/activities/flowable.go +++ b/flow/activities/flowable.go @@ -149,7 +149,7 @@ func (a *FlowableActivity) CreateNormalizedTable( ) (*protos.SetupNormalizedTableBatchOutput, error) { logger := activity.GetLogger(ctx) ctx = context.WithValue(ctx, shared.FlowNameKey, config.FlowName) - conn, err := connectors.GetConnectorAs[connectors.NormalizedTablesConnector](ctx, config.PeerConnectionConfig) + conn, err := connectors.GetAs[connectors.NormalizedTablesConnector](ctx, config.PeerConnectionConfig) if err != nil { if err == connectors.ErrUnsupportedFunctionality { logger.Info("Connector does not implement normalized tables") @@ -972,34 +972,19 @@ func (a *FlowableActivity) RenameTables(ctx context.Context, config *protos.Rena *protos.RenameTablesOutput, error, ) { ctx = context.WithValue(ctx, shared.FlowNameKey, config.FlowJobName) - dstConn, err := connectors.GetCDCSyncConnector(ctx, config.Peer) + conn, err := connectors.GetAs[connectors.RenameTablesConnector](ctx, config.Peer) if err != nil { a.Alerter.LogFlowError(ctx, config.FlowJobName, err) return nil, fmt.Errorf("failed to get connector: %w", err) } - defer connectors.CloseConnector(ctx, dstConn) + defer connectors.CloseConnector(ctx, conn) shutdown := utils.HeartbeatRoutine(ctx, func() string { return "renaming tables for job" }) defer shutdown() - if config.Peer.Type == protos.DBType_SNOWFLAKE { - sfConn, ok := dstConn.(*connsnowflake.SnowflakeConnector) - if !ok { - a.Alerter.LogFlowError(ctx, config.FlowJobName, err) - return nil, errors.New("failed to cast connector to snowflake connector") - } - return sfConn.RenameTables(ctx, config) - } else if config.Peer.Type == protos.DBType_BIGQUERY { - bqConn, ok := dstConn.(*connbigquery.BigQueryConnector) - if !ok { - a.Alerter.LogFlowError(ctx, config.FlowJobName, err) - return nil, errors.New("failed to cast connector to bigquery connector") - } - return bqConn.RenameTables(ctx, config) - } - return nil, errors.New("rename tables is only supported on snowflake and bigquery") + return conn.RenameTables(ctx, config) } func (a *FlowableActivity) CreateTablesFromExisting(ctx context.Context, req *protos.CreateTablesFromExistingInput) ( diff --git a/flow/connectors/core.go b/flow/connectors/core.go index 1a0f5d95f2..12d87d0c4e 100644 --- a/flow/connectors/core.go +++ b/flow/connectors/core.go @@ -186,6 +186,12 @@ type QRepConsolidateConnector interface { CleanupQRepFlow(ctx context.Context, config *protos.QRepConfig) error } +type RenameTablesConnector interface { + Connector + + RenameTables(context.Context, *protos.RenameTablesInput) (*protos.RenameTablesOutput, error) +} + func GetConnector(ctx context.Context, config *protos.Peer) (Connector, error) { switch inner := config.Config.(type) { case *protos.Peer_PostgresConfig: @@ -213,7 +219,7 @@ func GetConnector(ctx context.Context, config *protos.Peer) (Connector, error) { } } -func GetConnectorAs[T Connector](ctx context.Context, config *protos.Peer) (T, error) { +func GetAs[T Connector](ctx context.Context, config *protos.Peer) (T, error) { var none T conn, err := GetConnector(ctx, config) if err != nil { @@ -228,27 +234,27 @@ func GetConnectorAs[T Connector](ctx context.Context, config *protos.Peer) (T, e } func GetCDCPullConnector(ctx context.Context, config *protos.Peer) (CDCPullConnector, error) { - return GetConnectorAs[CDCPullConnector](ctx, config) + return GetAs[CDCPullConnector](ctx, config) } func GetCDCSyncConnector(ctx context.Context, config *protos.Peer) (CDCSyncConnector, error) { - return GetConnectorAs[CDCSyncConnector](ctx, config) + return GetAs[CDCSyncConnector](ctx, config) } func GetCDCNormalizeConnector(ctx context.Context, config *protos.Peer) (CDCNormalizeConnector, error) { - return GetConnectorAs[CDCNormalizeConnector](ctx, config) + return GetAs[CDCNormalizeConnector](ctx, config) } func GetQRepPullConnector(ctx context.Context, config *protos.Peer) (QRepPullConnector, error) { - return GetConnectorAs[QRepPullConnector](ctx, config) + return GetAs[QRepPullConnector](ctx, config) } func GetQRepSyncConnector(ctx context.Context, config *protos.Peer) (QRepSyncConnector, error) { - return GetConnectorAs[QRepSyncConnector](ctx, config) + return GetAs[QRepSyncConnector](ctx, config) } func GetQRepConsolidateConnector(ctx context.Context, config *protos.Peer) (QRepConsolidateConnector, error) { - return GetConnectorAs[QRepConsolidateConnector](ctx, config) + return GetAs[QRepConsolidateConnector](ctx, config) } func CloseConnector(ctx context.Context, conn Connector) { @@ -296,6 +302,9 @@ var ( _ QRepConsolidateConnector = &connsnowflake.SnowflakeConnector{} _ QRepConsolidateConnector = &connclickhouse.ClickhouseConnector{} + _ RenameTablesConnector = &connsnowflake.SnowflakeConnector{} + _ RenameTablesConnector = &connbigquery.BigQueryConnector{} + _ ValidationConnector = &connsnowflake.SnowflakeConnector{} _ ValidationConnector = &connclickhouse.ClickhouseConnector{} _ ValidationConnector = &connbigquery.BigQueryConnector{} From 93c1adf26d68b01b89c36a407f17600454291d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Fri, 5 Apr 2024 19:40:25 +0000 Subject: [PATCH 48/48] Use Selector in BoundSelector to wait in parallel (#683) BoundSelector is only used by table cloning Selector does some juggling so that Select waits on all futures, changing BoundSelector to use Selector avoids pathological cases Imagine parallelism is 4. The time to clone tables is as follows: 15m 1m 2m 3m 4m 5m Currently, cloning will take 20m (waits for 15m at 4m, then immediately adds 4m & 5m) Optimally, cloning would take 15m. 4m would start after 1m & another minute later 5m would start --- flow/concurrency/bound_selector.go | 48 ++++++++++++-------------- flow/e2e/postgres/peer_flow_pg_test.go | 36 +++++++++++++++++++ flow/e2e/postgres/qrep_flow_pg_test.go | 6 ++-- flow/e2e/test_utils.go | 5 +-- flow/workflows/snapshot_flow.go | 2 +- 5 files changed, 62 insertions(+), 35 deletions(-) diff --git a/flow/concurrency/bound_selector.go b/flow/concurrency/bound_selector.go index 35ea84412d..18f291cd84 100644 --- a/flow/concurrency/bound_selector.go +++ b/flow/concurrency/bound_selector.go @@ -7,48 +7,44 @@ import ( ) type BoundSelector struct { - futures []workflow.Future - ferrors []error - limit int + selector workflow.Selector + ferrors []error + limit int + count int } -func NewBoundSelector(limit int) *BoundSelector { +func NewBoundSelector(ctx workflow.Context, limit int) *BoundSelector { return &BoundSelector{ - limit: limit, + limit: limit, + selector: workflow.NewSelector(ctx), } } -func (s *BoundSelector) SpawnChild(chCtx workflow.Context, w interface{}, args ...interface{}) { - if len(s.futures) >= s.limit { - s.waitOne(chCtx) +func (s *BoundSelector) SpawnChild(ctx workflow.Context, w interface{}, args ...interface{}) { + if s.count >= s.limit { + s.waitOne(ctx) } - future := workflow.ExecuteChildWorkflow(chCtx, w, args...) - s.futures = append(s.futures, future) + future := workflow.ExecuteChildWorkflow(ctx, w, args...) + s.selector.AddFuture(future, func(f workflow.Future) { + if err := f.Get(ctx, nil); err != nil { + s.ferrors = append(s.ferrors, err) + } + }) + s.count += 1 } func (s *BoundSelector) waitOne(ctx workflow.Context) { - if len(s.futures) == 0 { - return - } - - f := s.futures[0] - s.futures = s.futures[1:] - - err := f.Get(ctx, nil) - if err != nil { - s.ferrors = append(s.ferrors, err) + if s.count > 0 { + s.selector.Select(ctx) + s.count -= 1 } } func (s *BoundSelector) Wait(ctx workflow.Context) error { - for len(s.futures) > 0 { + for s.count > 0 { s.waitOne(ctx) } - if len(s.ferrors) > 0 { - return errors.Join(s.ferrors...) - } - - return nil + return errors.Join(s.ferrors...) } diff --git a/flow/e2e/postgres/peer_flow_pg_test.go b/flow/e2e/postgres/peer_flow_pg_test.go index 74413a949b..fac0a270cb 100644 --- a/flow/e2e/postgres/peer_flow_pg_test.go +++ b/flow/e2e/postgres/peer_flow_pg_test.go @@ -804,6 +804,42 @@ func (s PeerFlowE2ETestSuitePG) Test_Supported_Mixed_Case_Table() { e2e.RequireEnvCanceled(s.t, env) } +func (s PeerFlowE2ETestSuitePG) Test_Multiple_Parallel_Initial() { + tableMapping := make([]*protos.TableMapping, 5) + for i := range tableMapping { + srcTable := fmt.Sprintf("test_multi_init_%d", i) + dstTable := srcTable + "_dst" + s.setupSourceTable(srcTable, (i+1)*101) + tableMapping[i] = &protos.TableMapping{ + SourceTableIdentifier: s.attachSchemaSuffix(srcTable), + DestinationTableIdentifier: s.attachSchemaSuffix(dstTable), + } + } + + connectionGen := e2e.FlowConnectionGenerationConfig{ + FlowJobName: s.attachSuffix("test_multi_init"), + } + config := &protos.FlowConnectionConfigs{ + DoInitialSnapshot: true, + InitialSnapshotOnly: true, + FlowJobName: connectionGen.FlowJobName, + Destination: s.peer, + TableMappings: tableMapping, + Source: e2e.GeneratePostgresPeer(), + CdcStagingPath: "", + SnapshotMaxParallelWorkers: 4, + SnapshotNumTablesInParallel: 3, + } + + tc := e2e.NewTemporalClient(s.t) + env := e2e.ExecutePeerflow(tc, peerflow.CDCFlowWorkflow, config, nil) + e2e.SetupCDCFlowStatusQuery(s.t, env, connectionGen) + e2e.EnvWaitForFinished(s.t, env, 3*time.Minute) + for _, tm := range config.TableMappings { + require.NoError(s.t, s.comparePGTables(tm.SourceTableIdentifier, tm.DestinationTableIdentifier, "id,address,asset_id")) + } +} + func (s PeerFlowE2ETestSuitePG) Test_ContinueAsNew() { srcTableName := s.attachSchemaSuffix("test_continueasnew") dstTableName := s.attachSchemaSuffix("test_continueasnew_dst") diff --git a/flow/e2e/postgres/qrep_flow_pg_test.go b/flow/e2e/postgres/qrep_flow_pg_test.go index 962efea901..5e738228f2 100644 --- a/flow/e2e/postgres/qrep_flow_pg_test.go +++ b/flow/e2e/postgres/qrep_flow_pg_test.go @@ -25,12 +25,10 @@ func TestPeerFlowE2ETestSuitePG(t *testing.T) { } func (s PeerFlowE2ETestSuitePG) setupSourceTable(tableName string, rowCount int) { - err := e2e.CreateTableForQRep(s.Conn(), s.suffix, tableName) - require.NoError(s.t, err) + require.NoError(s.t, e2e.CreateTableForQRep(s.Conn(), s.suffix, tableName)) if rowCount > 0 { - err = e2e.PopulateSourceTable(s.Conn(), s.suffix, tableName, rowCount) - require.NoError(s.t, err) + require.NoError(s.t, e2e.PopulateSourceTable(s.Conn(), s.suffix, tableName, rowCount)) } } diff --git a/flow/e2e/test_utils.go b/flow/e2e/test_utils.go index a5eb73bee0..74e24ac2d4 100644 --- a/flow/e2e/test_utils.go +++ b/flow/e2e/test_utils.go @@ -286,11 +286,8 @@ func CreateTableForQRep(conn *pgx.Conn, suffix string, tableName string) error { CREATE TABLE e2e_test_%s.%s ( %s );`, suffix, tableName, tblFieldStr)) - if err != nil { - return err - } - return nil + return err } func generate20MBJson() ([]byte, error) { diff --git a/flow/workflows/snapshot_flow.go b/flow/workflows/snapshot_flow.go index 43105695c3..8c88440035 100644 --- a/flow/workflows/snapshot_flow.go +++ b/flow/workflows/snapshot_flow.go @@ -209,7 +209,7 @@ func (s *SnapshotFlowExecution) cloneTables( cloneTablesInput.snapshotName) } - boundSelector := concurrency.NewBoundSelector(cloneTablesInput.maxParallelClones) + boundSelector := concurrency.NewBoundSelector(ctx, cloneTablesInput.maxParallelClones) defaultPartitionCol := "ctid" if !cloneTablesInput.supportsTIDScans {