diff --git a/backend/go.mod b/backend/go.mod index 38406e5..ff93bfa 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -9,6 +9,7 @@ require ( github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/gofrs/uuid v4.4.0+incompatible github.com/golang-jwt/jwt/v5 v5.2.1 + github.com/google/generative-ai-go v0.19.0 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.7.2 github.com/joho/godotenv v1.5.1 @@ -17,12 +18,28 @@ require ( github.com/rabbitmq/amqp091-go v1.10.0 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 - golang.org/x/crypto v0.31.0 + golang.org/x/crypto v0.36.0 + google.golang.org/api v0.186.0 ) require ( + cloud.google.com/go v0.115.0 // indirect + cloud.google.com/go/ai v0.8.0 // indirect + cloud.google.com/go/auth v0.6.0 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect + cloud.google.com/go/longrunning v0.5.7 // indirect github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.7.0 // 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.5 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect @@ -41,11 +58,24 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/subosito/gotenv v1.6.0 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect + go.opentelemetry.io/otel v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/trace v1.26.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect + google.golang.org/grpc v1.64.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/backend/go.sum b/backend/go.sum index 1c61c53..95e37d6 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -1,5 +1,22 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= +cloud.google.com/go/ai v0.8.0 h1:rXUEz8Wp2OlrM8r1bfmpF2+VKqc1VJpafE3HgzRnD/w= +cloud.google.com/go/ai v0.8.0/go.mod h1:t3Dfk4cM61sytiggo2UyGsDVW3RF1qGZaUKDrZFyqkE= +cloud.google.com/go/auth v0.6.0 h1:5x+d6b5zdezZ7gmLWD1m/xNjnaQ2YDhmIz/HH3doy1g= +cloud.google.com/go/auth v0.6.0/go.mod h1:b4acV+jLQDyjwm4OXHYjNvRi4jvGBzHWJRtJcy+2P4g= +cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= +cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuAKilhU= +cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/danielgtaylor/huma/v2 v2.28.0 h1:W+hIT52MigO73edJNJWXU896uC99xSBWpKoE2PRyybM= github.com/danielgtaylor/huma/v2 v2.28.0/go.mod h1:67KO0zmYEkR+LVUs8uqrcvf44G1wXiMIu94LV/cH2Ek= @@ -9,6 +26,12 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -17,16 +40,52 @@ github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8= github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/generative-ai-go v0.19.0 h1:R71szggh8wHMCUlEMsW2A/3T+5LdEIkiaHSYgSpUgdg= +github.com/google/generative-ai-go v0.19.0/go.mod h1:JYolL13VG7j79kM5BtHz4qwONHkeJQzOCkKXnpqtS/E= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= +github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= @@ -67,6 +126,7 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pressly/goose/v3 v3.24.1 h1:bZmxRco2uy5uu5Ng1MMVEfYsFlrMJI+e/VMXHQ3C4LY= github.com/pressly/goose/v3 v3.24.1/go.mod h1:rEWreU9uVtt0DHCyLzF9gRcWiiTF/V+528DV+4DORug= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= @@ -94,27 +154,107 @@ github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +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.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +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/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= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +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= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.186.0 h1:n2OPp+PPXX0Axh4GuSsL5QL8xQCTb2oDwyzPnQvqUug= +google.golang.org/api v0.186.0/go.mod h1:hvRbBmgoje49RV3xqVXrmP6w93n6ehGgIVPYrGtBFFc= +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/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/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= +google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +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.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -124,6 +264,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= diff --git a/backend/internal/api/chat.go b/backend/internal/api/chat.go new file mode 100644 index 0000000..9d06b15 --- /dev/null +++ b/backend/internal/api/chat.go @@ -0,0 +1,142 @@ +package api + +import ( + "context" + "net/http" + + "github.com/danielgtaylor/huma/v2" + "github.com/forfarm/backend/internal/services" + "github.com/go-chi/chi/v5" + "github.com/google/generative-ai-go/genai" +) + +func (a *api) registerChatRoutes(_ chi.Router, apiInstance huma.API) { + tags := []string{"chat"} + + huma.Register(apiInstance, huma.Operation{ + OperationID: "chatWithAssistantContextual", + Method: http.MethodPost, + Path: "/chat/specific", + Tags: tags, + Summary: "Send a message to the assistant with farm/crop context", + Description: "Allows users to interact with the AI chatbot, providing farm/crop context.", + }, a.chatHandler) + + huma.Register(apiInstance, huma.Operation{ + OperationID: "chatWithAssistantGeneral", + Method: http.MethodPost, + Path: "/chat", + Tags: tags, + Summary: "Send a message to the general farming assistant", + Description: "Allows users to interact with the AI chatbot without specific farm/crop context.", + }, a.generalChatHandler) +} + +type HistoryItem struct { + Role string `json:"role" example:"user" enum:"user,model" doc:"Role of the sender (user or model)"` + Text string `json:"text" doc:"The content of the message"` +} + +type ChatInput struct { + Header string `header:"Authorization" required:"true" example:"Bearer token"` + Body struct { + Message string `json:"message" required:"true" doc:"The user's message to the assistant"` + FarmID string `json:"farmId,omitempty" doc:"Optional UUID of the farm context"` + CropID string `json:"cropId,omitempty" doc:"Optional UUID of the crop context"` + History []HistoryItem `json:"history,omitempty" doc:"Previous turns in the conversation"` + } +} + +type ChatOutput struct { + Body struct { + Response string `json:"response" doc:"The assistant's response message"` + } +} + +type GeneralChatInput struct { + Header string `header:"Authorization" required:"true" example:"Bearer token"` + Body struct { + Message string `json:"message" required:"true" doc:"The user's message to the assistant"` + History []HistoryItem `json:"history,omitempty" doc:"Previous turns in the conversation"` + } +} + +type GeneralChatOutput = ChatOutput + +// convertInputHistory converts the API HistoryItem slice to genai.Content slice. +func convertInputHistory(apiHistory []HistoryItem) []*genai.Content { + if apiHistory == nil { + return nil + } + genaiHistory := make([]*genai.Content, 0, len(apiHistory)) + for _, item := range apiHistory { + if (item.Role == "user" || item.Role == "model") && item.Text != "" { + content := &genai.Content{ + Role: item.Role, + Parts: []genai.Part{genai.Text(item.Text)}, + } + genaiHistory = append(genaiHistory, content) + } + } + return genaiHistory +} + +func (a *api) chatHandler(ctx context.Context, input *ChatInput) (*ChatOutput, error) { + userID, err := a.getUserIDFromHeader(input.Header) + if err != nil { + return nil, huma.Error401Unauthorized("Authentication failed", err) + } + if a.chatService == nil { + a.logger.Error("Chat service is not initialized") + return nil, huma.Error500InternalServerError("Chat service is not available") + } + + genaiHistory := convertInputHistory(input.Body.History) + + serviceInput := services.GenerateResponseInput{ + UserID: userID, + Message: input.Body.Message, + FarmID: input.Body.FarmID, + CropID: input.Body.CropID, + History: genaiHistory, + } + + botResponse, err := a.chatService.GenerateResponse(ctx, serviceInput) + if err != nil { + a.logger.Error("Failed to get response from chat service (contextual)", "userId", userID, "farmId", input.Body.FarmID, "cropId", input.Body.CropID, "error", err) + return nil, huma.Error500InternalServerError("Failed to get response from assistant") + } + + resp := &ChatOutput{} + resp.Body.Response = botResponse + return resp, nil +} + +func (a *api) generalChatHandler(ctx context.Context, input *GeneralChatInput) (*GeneralChatOutput, error) { + userID, err := a.getUserIDFromHeader(input.Header) + if err != nil { + return nil, huma.Error401Unauthorized("Authentication failed", err) + } + if a.chatService == nil { + a.logger.Error("Chat service is not initialized") + return nil, huma.Error500InternalServerError("Chat service is not available") + } + + genaiHistory := convertInputHistory(input.Body.History) + + serviceInput := services.GenerateResponseInput{ + UserID: userID, + Message: input.Body.Message, + History: genaiHistory, + } + + botResponse, err := a.chatService.GenerateResponse(ctx, serviceInput) + if err != nil { + a.logger.Error("Failed to get response from chat service (general)", "userId", userID, "error", err) + return nil, huma.Error500InternalServerError("Failed to get response from assistant") + } + + resp := &GeneralChatOutput{} + resp.Body.Response = botResponse + return resp, nil +} diff --git a/backend/internal/api/crop.go b/backend/internal/api/crop.go index 477c360..fe4cd3f 100644 --- a/backend/internal/api/crop.go +++ b/backend/internal/api/crop.go @@ -15,10 +15,8 @@ import ( func (a *api) registerCropRoutes(_ chi.Router, api huma.API) { tags := []string{"crop"} - prefix := "/crop" - // Register GET /crop huma.Register(api, huma.Operation{ OperationID: "getAllCroplands", Method: http.MethodGet, @@ -26,7 +24,6 @@ func (a *api) registerCropRoutes(_ chi.Router, api huma.API) { Tags: tags, }, a.getAllCroplandsHandler) - // Register GET /crop/{uuid} huma.Register(api, huma.Operation{ OperationID: "getCroplandByID", Method: http.MethodGet, @@ -34,7 +31,6 @@ func (a *api) registerCropRoutes(_ chi.Router, api huma.API) { Tags: tags, }, a.getCroplandByIDHandler) - // Register GET /crop/farm/{farm_id} huma.Register(api, huma.Operation{ OperationID: "getAllCroplandsByFarmID", Method: http.MethodGet, @@ -42,15 +38,23 @@ func (a *api) registerCropRoutes(_ chi.Router, api huma.API) { Tags: tags, }, a.getAllCroplandsByFarmIDHandler) - // Register POST /crop (Create or Update) huma.Register(api, huma.Operation{ - OperationID: "createOrUpdateCropland", + OperationID: "createCropland", Method: http.MethodPost, Path: prefix, Tags: tags, - }, a.createOrUpdateCroplandHandler) + }, a.createCroplandHandler) + + huma.Register(api, huma.Operation{ + OperationID: "updateCropland", + Method: http.MethodPut, + Path: prefix + "/{uuid}", + Tags: tags, + }, a.updateCroplandHandler) } +// --- Common Output Structs --- + type GetCroplandsOutput struct { Body struct { Croplands []domain.Cropland `json:"croplands"` @@ -63,22 +67,45 @@ type GetCroplandByIDOutput struct { } } -type CreateOrUpdateCroplandInput struct { +// --- Create Structs --- + +type CreateCroplandInput struct { Header string `header:"Authorization" required:"true" example:"Bearer token"` Body struct { - UUID string `json:"uuid,omitempty"` - Name string `json:"name"` - Status string `json:"status"` + Name string `json:"name" required:"true"` + Status string `json:"status" required:"true"` Priority int `json:"priority"` LandSize float64 `json:"landSize"` - GrowthStage string `json:"growthStage"` - PlantID string `json:"plantId"` - FarmID string `json:"farmId"` + GrowthStage string `json:"growthStage" required:"true"` + PlantID string `json:"plantId" required:"true" example:"a1b2c3d4-e5f6-7890-1234-567890abcdef"` + FarmID string `json:"farmId" required:"true" example:"b2c3d4e5-f6a7-8901-2345-67890abcdef0"` GeoFeature json.RawMessage `json:"geoFeature,omitempty"` } } -type CreateOrUpdateCroplandOutput struct { +type CreateCroplandOutput struct { + Body struct { + Cropland domain.Cropland `json:"cropland"` + } +} + +// --- Update Structs --- + +type UpdateCroplandInput struct { + Header string `header:"Authorization" required:"true" example:"Bearer token"` + UUID string `path:"uuid" required:"true" example:"c3d4e5f6-a7b8-9012-3456-7890abcdef01"` + Body struct { + Name string `json:"name" required:"true"` + Status string `json:"status" required:"true"` + Priority int `json:"priority"` + LandSize float64 `json:"landSize"` + GrowthStage string `json:"growthStage" required:"true"` + PlantID string `json:"plantId" required:"true" example:"a1b2c3d4-e5f6-7890-1234-567890abcdef"` + GeoFeature json.RawMessage `json:"geoFeature,omitempty"` + } +} + +type UpdateCroplandOutput struct { Body struct { Cropland domain.Cropland `json:"cropland"` } @@ -90,8 +117,7 @@ func (a *api) getAllCroplandsHandler(ctx context.Context, input *struct { Header string `header:"Authorization" required:"true" example:"Bearer token"` }) (*GetCroplandsOutput, error) { // Note: This currently fetches ALL croplands. Might need owner filtering later. - // For now, ensure authentication happens. - _, err := a.getUserIDFromHeader(input.Header) // Verify token + _, err := a.getUserIDFromHeader(input.Header) if err != nil { return nil, huma.Error401Unauthorized("Authentication failed", err) } @@ -112,7 +138,7 @@ func (a *api) getCroplandByIDHandler(ctx context.Context, input *struct { Header string `header:"Authorization" required:"true" example:"Bearer token"` UUID string `path:"uuid" example:"550e8400-e29b-41d4-a716-446655440000"` }) (*GetCroplandByIDOutput, error) { - userID, err := a.getUserIDFromHeader(input.Header) // Verify token and get user ID + userID, err := a.getUserIDFromHeader(input.Header) if err != nil { return nil, huma.Error401Unauthorized("Authentication failed", err) } @@ -120,15 +146,15 @@ func (a *api) getCroplandByIDHandler(ctx context.Context, input *struct { resp := &GetCroplandByIDOutput{} if input.UUID == "" { - return nil, huma.Error400BadRequest("UUID parameter is required") + return nil, huma.Error400BadRequest("UUID path parameter is required") } - _, err = uuid.FromString(input.UUID) + croplandUUID, err := uuid.FromString(input.UUID) if err != nil { return nil, huma.Error400BadRequest("Invalid UUID format") } - cropland, err := a.cropRepo.GetByID(ctx, input.UUID) + cropland, err := a.cropRepo.GetByID(ctx, croplandUUID.String()) if err != nil { if errors.Is(err, domain.ErrNotFound) || errors.Is(err, sql.ErrNoRows) { a.logger.Warn("Cropland not found", "croplandId", input.UUID, "requestingUserId", userID) @@ -138,12 +164,10 @@ func (a *api) getCroplandByIDHandler(ctx context.Context, input *struct { return nil, huma.Error500InternalServerError("Failed to retrieve cropland") } - // Authorization check: User must own the farm this cropland belongs to - farm, err := a.farmRepo.GetByID(ctx, cropland.FarmID) // Fetch the farm + farm, err := a.farmRepo.GetByID(ctx, cropland.FarmID) if err != nil { if errors.Is(err, domain.ErrNotFound) || errors.Is(err, sql.ErrNoRows) { a.logger.Error("Farm associated with cropland not found", "farmId", cropland.FarmID, "croplandId", input.UUID) - // This indicates a data integrity issue if the cropland exists but farm doesn't return nil, huma.Error404NotFound("Associated farm not found for cropland") } a.logger.Error("Failed to fetch farm for cropland authorization", "farmId", cropland.FarmID, "error", err) @@ -171,7 +195,7 @@ func (a *api) getAllCroplandsByFarmIDHandler(ctx context.Context, input *struct resp := &GetCroplandsOutput{} if input.FarmID == "" { - return nil, huma.Error400BadRequest("farm_id parameter is required") + return nil, huma.Error400BadRequest("farmId path parameter is required") } farmUUID, err := uuid.FromString(input.FarmID) @@ -179,7 +203,6 @@ func (a *api) getAllCroplandsByFarmIDHandler(ctx context.Context, input *struct return nil, huma.Error400BadRequest("Invalid farmId format") } - // Authorization check: User must own the farm they are requesting crops for farm, err := a.farmRepo.GetByID(ctx, farmUUID.String()) if err != nil { if errors.Is(err, domain.ErrNotFound) || errors.Is(err, sql.ErrNoRows) { @@ -208,83 +231,41 @@ func (a *api) getAllCroplandsByFarmIDHandler(ctx context.Context, input *struct return resp, nil } -func (a *api) createOrUpdateCroplandHandler(ctx context.Context, input *CreateOrUpdateCroplandInput) (*CreateOrUpdateCroplandOutput, error) { +func (a *api) createCroplandHandler(ctx context.Context, input *CreateCroplandInput) (*CreateCroplandOutput, error) { userID, err := a.getUserIDFromHeader(input.Header) if err != nil { return nil, huma.Error401Unauthorized("Authentication failed", err) } - resp := &CreateOrUpdateCroplandOutput{} + resp := &CreateCroplandOutput{} - // --- Input Validation --- - if input.Body.Name == "" { - return nil, huma.Error400BadRequest("name is required") - } - if input.Body.Status == "" { - return nil, huma.Error400BadRequest("status is required") - } - if input.Body.GrowthStage == "" { - return nil, huma.Error400BadRequest("growthStage is required") - } - if input.Body.PlantID == "" { - return nil, huma.Error400BadRequest("plantId is required") - } - if input.Body.FarmID == "" { - return nil, huma.Error400BadRequest("farmId is required") - } - - // Validate UUID formats - if input.Body.UUID != "" { - if _, err := uuid.FromString(input.Body.UUID); err != nil { - return nil, huma.Error400BadRequest("invalid cropland UUID format") - } - } if _, err := uuid.FromString(input.Body.PlantID); err != nil { return nil, huma.Error400BadRequest("invalid plantId UUID format") } farmUUID, err := uuid.FromString(input.Body.FarmID) if err != nil { - return nil, huma.Error400BadRequest("invalid farm_id UUID format") + return nil, huma.Error400BadRequest("invalid farmId UUID format") } - // Validate JSON format if GeoFeature is provided if input.Body.GeoFeature != nil && !json.Valid(input.Body.GeoFeature) { return nil, huma.Error400BadRequest("invalid JSON format for geoFeature") } - // --- Authorization Check --- - // User must own the farm they are adding/updating a crop for farm, err := a.farmRepo.GetByID(ctx, farmUUID.String()) if err != nil { if errors.Is(err, domain.ErrNotFound) || errors.Is(err, sql.ErrNoRows) { - a.logger.Warn("Attempt to create/update crop for non-existent farm", "farmId", input.Body.FarmID, "requestingUserId", userID) + a.logger.Warn("Attempt to create crop for non-existent farm", "farmId", input.Body.FarmID, "requestingUserId", userID) return nil, huma.Error404NotFound("Target farm not found") } - a.logger.Error("Failed to fetch farm for create/update cropland authorization", "farmId", input.Body.FarmID, "error", err) + a.logger.Error("Failed to fetch farm for create cropland authorization", "farmId", input.Body.FarmID, "error", err) return nil, huma.Error500InternalServerError("Failed to verify ownership") } if farm.OwnerID != userID { - a.logger.Warn("Unauthorized attempt to create/update crop on farm", "farmId", input.Body.FarmID, "requestingUserId", userID, "farmOwnerId", farm.OwnerID) - return nil, huma.Error403Forbidden("You are not authorized to modify crops on this farm") + a.logger.Warn("Unauthorized attempt to create crop on farm", "farmId", input.Body.FarmID, "requestingUserId", userID, "farmOwnerId", farm.OwnerID) + return nil, huma.Error403Forbidden("You are not authorized to add crops to this farm") } - // If updating, ensure the user also owns the existing cropland (redundant if farm check passes, but good practice) - if input.Body.UUID != "" { - existingCrop, err := a.cropRepo.GetByID(ctx, input.Body.UUID) - if err != nil && !errors.Is(err, domain.ErrNotFound) && !errors.Is(err, sql.ErrNoRows) { // Ignore not found for creation - a.logger.Error("Failed to get existing cropland for update authorization check", "croplandId", input.Body.UUID, "error", err) - return nil, huma.Error500InternalServerError("Failed to verify existing cropland") - } - // If cropland exists and its FarmID doesn't match the input/authorized FarmID, deny. - if err == nil && existingCrop.FarmID != farmUUID.String() { - a.logger.Warn("Attempt to update cropland belonging to a different farm", "croplandId", input.Body.UUID, "inputFarmId", input.Body.FarmID, "actualFarmId", existingCrop.FarmID) - return nil, huma.Error403Forbidden("Cropland does not belong to the specified farm") - } - } - - // --- Prepare and Save Cropland --- cropland := &domain.Cropland{ - UUID: input.Body.UUID, Name: input.Body.Name, Status: input.Body.Status, Priority: input.Body.Priority, @@ -295,15 +276,84 @@ func (a *api) createOrUpdateCroplandHandler(ctx context.Context, input *CreateOr GeoFeature: input.Body.GeoFeature, } - // Use the repository's CreateOrUpdate which handles assigning UUID if needed err = a.cropRepo.CreateOrUpdate(ctx, cropland) if err != nil { - a.logger.Error("Failed to save cropland to database", "farm_id", input.Body.FarmID, "plantId", input.Body.PlantID, "error", err) + a.logger.Error("Failed to create cropland in database", "farmId", input.Body.FarmID, "plantId", input.Body.PlantID, "error", err) return nil, huma.Error500InternalServerError("Failed to save cropland") } - a.logger.Info("Cropland created/updated successfully", "croplandId", cropland.UUID, "farmId", cropland.FarmID) + a.logger.Info("Cropland created successfully", "croplandId", cropland.UUID, "farmId", cropland.FarmID) resp.Body.Cropland = *cropland return resp, nil } + +func (a *api) updateCroplandHandler(ctx context.Context, input *UpdateCroplandInput) (*UpdateCroplandOutput, error) { + userID, err := a.getUserIDFromHeader(input.Header) + if err != nil { + return nil, huma.Error401Unauthorized("Authentication failed", err) + } + + resp := &UpdateCroplandOutput{} + + croplandUUID, err := uuid.FromString(input.UUID) + if err != nil { + return nil, huma.Error400BadRequest("Invalid cropland UUID format in path") + } + + if _, err := uuid.FromString(input.Body.PlantID); err != nil { + return nil, huma.Error400BadRequest("invalid plantId UUID format in body") + } + + if input.Body.GeoFeature != nil && !json.Valid(input.Body.GeoFeature) { + return nil, huma.Error400BadRequest("invalid JSON format for geoFeature") + } + + existingCrop, err := a.cropRepo.GetByID(ctx, croplandUUID.String()) + if err != nil { + if errors.Is(err, domain.ErrNotFound) || errors.Is(err, sql.ErrNoRows) { + a.logger.Warn("Attempt to update non-existent cropland", "croplandId", input.UUID, "requestingUserId", userID) + return nil, huma.Error404NotFound("Cropland not found") + } + a.logger.Error("Failed to get existing cropland for update", "croplandId", input.UUID, "error", err) + return nil, huma.Error500InternalServerError("Failed to retrieve cropland for update") + } + + farm, err := a.farmRepo.GetByID(ctx, existingCrop.FarmID) + if err != nil { + if errors.Is(err, domain.ErrNotFound) || errors.Is(err, sql.ErrNoRows) { + a.logger.Error("Farm associated with existing cropland not found during update", "farmId", existingCrop.FarmID, "croplandId", input.UUID) + return nil, huma.Error500InternalServerError("Associated farm data inconsistent") + } + a.logger.Error("Failed to fetch farm for update cropland authorization", "farmId", existingCrop.FarmID, "error", err) + return nil, huma.Error500InternalServerError("Failed to verify ownership for update") + } + if farm.OwnerID != userID { + a.logger.Warn("Unauthorized attempt to update crop on farm", "croplandId", input.UUID, "farmId", existingCrop.FarmID, "requestingUserId", userID, "farmOwnerId", farm.OwnerID) + return nil, huma.Error403Forbidden("You are not authorized to modify this cropland") + } + + updatedCropland := &domain.Cropland{ + UUID: existingCrop.UUID, + FarmID: existingCrop.FarmID, + Name: input.Body.Name, + Status: input.Body.Status, + Priority: input.Body.Priority, + LandSize: input.Body.LandSize, + GrowthStage: input.Body.GrowthStage, + PlantID: input.Body.PlantID, + GeoFeature: input.Body.GeoFeature, + CreatedAt: existingCrop.CreatedAt, + } + + err = a.cropRepo.CreateOrUpdate(ctx, updatedCropland) + if err != nil { + a.logger.Error("Failed to update cropland in database", "croplandId", updatedCropland.UUID, "error", err) + return nil, huma.Error500InternalServerError("Failed to update cropland") + } + + a.logger.Info("Cropland updated successfully", "croplandId", updatedCropland.UUID, "farmId", updatedCropland.FarmID) + + resp.Body.Cropland = *updatedCropland + return resp, nil +} diff --git a/backend/internal/api/user.go b/backend/internal/api/user.go index 8dd914e..87e1fb1 100644 --- a/backend/internal/api/user.go +++ b/backend/internal/api/user.go @@ -11,6 +11,8 @@ import ( "github.com/forfarm/backend/internal/domain" "github.com/forfarm/backend/internal/utilities" "github.com/go-chi/chi/v5" + validation "github.com/go-ozzo/ozzo-validation/v4" + "github.com/jackc/pgx/v5" ) func (a *api) registerUserRoutes(_ chi.Router, api huma.API) { @@ -29,13 +31,25 @@ type getSelfDataInput struct { Authorization string `header:"Authorization" required:"true" example:"Bearer token"` } -// getSelfDataOutput uses domain.User which now has camelCase tags type getSelfDataOutput struct { Body struct { User domain.User `json:"user"` } } +type UpdateSelfDataInput struct { + Authorization string `header:"Authorization" required:"true" example:"Bearer token"` + Body struct { + Username *string `json:"username,omitempty"` + } +} + +type UpdateSelfDataOutput struct { + Body struct { + User domain.User `json:"user"` + } +} + func (a *api) getSelfData(ctx context.Context, input *getSelfDataInput) (*getSelfDataOutput, error) { resp := &getSelfDataOutput{} @@ -71,3 +85,70 @@ func (a *api) getSelfData(ctx context.Context, input *getSelfDataInput) (*getSel resp.Body.User = user return resp, nil } + +func (a *api) updateSelfData(ctx context.Context, input *UpdateSelfDataInput) (*UpdateSelfDataOutput, error) { + userID, err := a.getUserIDFromHeader(input.Authorization) + if err != nil { + return nil, huma.Error401Unauthorized("Authentication failed", err) + } + + user, err := a.userRepo.GetByUUID(ctx, userID) + if err != nil { + if errors.Is(err, domain.ErrNotFound) || errors.Is(err, pgx.ErrNoRows) { + a.logger.Warn("Attempt to update non-existent user", "user_uuid", userID) + return nil, huma.Error404NotFound("User not found") + } + a.logger.Error("Failed to get user for update", "user_uuid", userID, "error", err) + return nil, huma.Error500InternalServerError("Failed to retrieve user for update") + } + + updated := false + if input.Body.Username != nil { + trimmedUsername := strings.TrimSpace(*input.Body.Username) + if trimmedUsername != user.Username { + err := validation.Validate(trimmedUsername, + validation.Required.Error("username cannot be empty if provided"), + validation.Length(3, 30).Error("username must be between 3 and 30 characters"), + ) + if err != nil { + return nil, huma.Error422UnprocessableEntity("Invalid username", err) + } + user.Username = trimmedUsername + updated = true + } + } + // Check other field here la + + if !updated { + a.logger.Info("No changes detected for user update", "user_uuid", userID) + return &UpdateSelfDataOutput{Body: struct { + User domain.User `json:"user"` + }{User: user}}, nil + } + + // Validate the *entire* user object after updates (optional but good practice) + // if err := user.Validate(); err != nil { + // return nil, huma.Error422UnprocessableEntity("Validation failed after update", err) + // } + + // Save updated user + err = a.userRepo.CreateOrUpdate(ctx, &user) + if err != nil { + a.logger.Error("Failed to update user in database", "user_uuid", userID, "error", err) + return nil, huma.Error500InternalServerError("Failed to save user profile") + } + + a.logger.Info("User profile updated successfully", "user_uuid", userID) + + updatedUser, fetchErr := a.userRepo.GetByUUID(ctx, userID) + if fetchErr != nil { + a.logger.Error("Failed to fetch user data after update", "user_uuid", userID, "error", fetchErr) + return &UpdateSelfDataOutput{Body: struct { + User domain.User `json:"user"` + }{User: user}}, nil + } + + return &UpdateSelfDataOutput{Body: struct { + User domain.User `json:"user"` + }{User: updatedUser}}, nil +} diff --git a/backend/internal/cmd/api.go b/backend/internal/cmd/api.go index ed03441..400c6ac 100644 --- a/backend/internal/cmd/api.go +++ b/backend/internal/cmd/api.go @@ -68,18 +68,21 @@ func APICmd(ctx context.Context) *cobra.Command { }() logger.Info("Farm Analytics Projection started") - weatherFetcher := api.GetWeatherFetcher() // Get fetcher instance from API setup + apiInstance := api.NewAPI(ctx, logger, pool, eventBus, analyticsRepo, inventoryRepo, croplandRepo, farmRepo) + + weatherFetcher := apiInstance.GetWeatherFetcher() weatherInterval, err := time.ParseDuration(config.WEATHER_FETCH_INTERVAL) if err != nil { logger.Warn("Invalid WEATHER_FETCH_INTERVAL, using default 15m", "value", config.WEATHER_FETCH_INTERVAL, "error", err) weatherInterval = 15 * time.Minute } - weatherUpdater := workers.NewWeatherUpdater(farmRepo, weatherFetcher, eventBus, logger, weatherInterval) - weatherUpdater.Start(ctx) // Pass the main context + weatherUpdater, err := workers.NewWeatherUpdater(farmRepo, weatherFetcher, eventBus, logger, weatherInterval) + if err != nil { + logger.Error("failed to create WeatherUpdater", "error", err) + } + weatherUpdater.Start(ctx) logger.Info("Weather Updater worker started", "interval", weatherInterval) - apiInstance := api.NewAPI(ctx, logger, pool, eventBus, analyticsRepo, inventoryRepo, croplandRepo, farmRepo) // Pass new repo - server := apiInstance.Server(port) serverErrChan := make(chan error, 1) @@ -87,7 +90,7 @@ func APICmd(ctx context.Context) *cobra.Command { logger.Info("starting API server", "port", port) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Error("API server failed", "error", err) - serverErrChan <- err // Send error to channel + serverErrChan <- err } close(serverErrChan) }() @@ -98,11 +101,10 @@ func APICmd(ctx context.Context) *cobra.Command { case <-ctx.Done(): logger.Info("Shutdown signal received, initiating graceful shutdown...") - shutdownCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second) // 15-second grace period + shutdownCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() - weatherUpdater.Stop() // Signal and wait - + weatherUpdater.Stop() if err := server.Shutdown(shutdownCtx); err != nil { logger.Error("HTTP server graceful shutdown failed", "error", err) } else { diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 9b9dbb2..bb7f232 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -20,6 +20,7 @@ var ( OPENWEATHER_API_KEY string OPENWEATHER_CACHE_TTL string WEATHER_FETCH_INTERVAL string + GEMINI_API_KEY string ) func Load() { @@ -36,6 +37,7 @@ func Load() { viper.SetDefault("OPENWEATHER_API_KEY", "openweather_api_key") viper.SetDefault("OPENWEATHER_CACHE_TTL", "15m") viper.SetDefault("WEATHER_FETCH_INTERVAL", "15m") + viper.SetDefault("GEMINI_API_KEY", "gemini_api_key") viper.SetConfigFile(".env") viper.AddConfigPath("../../.") @@ -59,4 +61,5 @@ func Load() { OPENWEATHER_API_KEY = viper.GetString("OPENWEATHER_API_KEY") OPENWEATHER_CACHE_TTL = viper.GetString("OPENWEATHER_CACHE_TTL") WEATHER_FETCH_INTERVAL = viper.GetString("WEATHER_FETCH_INTERVAL") + GEMINI_API_KEY = viper.GetString("GEMINI_API_KEY") } diff --git a/backend/internal/domain/farm.go b/backend/internal/domain/farm.go index c2da327..4b929b6 100644 --- a/backend/internal/domain/farm.go +++ b/backend/internal/domain/farm.go @@ -32,6 +32,7 @@ func (f *Farm) Validate() error { type FarmRepository interface { GetByID(context.Context, string) (*Farm, error) GetByOwnerID(context.Context, string) ([]Farm, error) + GetAll(context.Context) ([]Farm, error) CreateOrUpdate(context.Context, *Farm) error Delete(context.Context, string) error SetEventPublisher(EventPublisher) diff --git a/backend/internal/domain/plant.go b/backend/internal/domain/plant.go index 289bca7..3a70696 100644 --- a/backend/internal/domain/plant.go +++ b/backend/internal/domain/plant.go @@ -45,6 +45,7 @@ func (p *Plant) Validate() error { type PlantRepository interface { GetByUUID(context.Context, string) (Plant, error) GetAll(context.Context) ([]Plant, error) + GetByName(context.Context, string) (Plant, error) Create(context.Context, *Plant) error Update(context.Context, *Plant) error Delete(context.Context, string) error diff --git a/backend/internal/event/projection.go b/backend/internal/event/projection.go index a5d57f1..1834d0b 100644 --- a/backend/internal/event/projection.go +++ b/backend/internal/event/projection.go @@ -1,4 +1,3 @@ -// backend/internal/event/projection.go package event import ( @@ -35,11 +34,10 @@ func NewFarmAnalyticsProjection( func (p *FarmAnalyticsProjection) Start(ctx context.Context) error { eventTypes := []string{ - "farm.created", "farm.updated", "farm.deleted", // Farm lifecycle - "weather.updated", // Weather updates - "cropland.created", "cropland.updated", "cropland.deleted", // Crop changes trigger count recalc - "inventory.item.created", "inventory.item.updated", "inventory.item.deleted", // Inventory changes trigger timestamp update - // Add other events that might influence FarmAnalytics, e.g., "pest.detected", "yield.recorded" + "farm.created", "farm.updated", "farm.deleted", + "weather.updated", + "cropland.created", "cropland.updated", "cropland.deleted", + "inventory.item.created", "inventory.item.updated", "inventory.item.deleted", } p.logger.Info("FarmAnalyticsProjection starting, subscribing to events", "types", eventTypes) @@ -49,8 +47,6 @@ func (p *FarmAnalyticsProjection) Start(ctx context.Context) error { if err := p.eventSubscriber.Subscribe(ctx, eventType, p.handleEvent); err != nil { p.logger.Error("Failed to subscribe to event type", "type", eventType, "error", err) errs = append(errs, fmt.Errorf("failed to subscribe to %s: %w", eventType, err)) - // TODO: Decide if we should continue subscribing or fail hard - // return errors.Join(errs...) // Fail hard } else { p.logger.Info("Successfully subscribed to event type", "type", eventType) } @@ -65,33 +61,30 @@ func (p *FarmAnalyticsProjection) Start(ctx context.Context) error { } func (p *FarmAnalyticsProjection) handleEvent(event domain.Event) error { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) // 10-second timeout + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() p.logger.Debug("Handling event in FarmAnalyticsProjection", "type", event.Type, "aggregate_id", event.AggregateID, "event_id", event.ID) - farmID := event.AggregateID // Assume AggregateID is the Farm UUID for relevant events + farmID := event.AggregateID - // Special case: inventory events might use UserID as AggregateID. - // Need a way to map UserID to FarmID if necessary, or adjust event publishing. - // For now, we assume farmID can be derived or is directly in the payload for inventory events. - - if farmID == "" { + // Try to get farmID from payload if AggregateID is empty or potentially not the farmID (e.g., user events) + if farmID == "" || event.Type == "inventory.item.created" || event.Type == "inventory.item.updated" || event.Type == "inventory.item.deleted" || event.Type == "cropland.created" || event.Type == "cropland.updated" || event.Type == "cropland.deleted" { payloadMap, ok := event.Payload.(map[string]interface{}) if ok { if idVal, ok := payloadMap["farm_id"].(string); ok && idVal != "" { farmID = idVal - } else if idVal, ok := payloadMap["user_id"].(string); ok && idVal != "" { - // !! WARNING: Need mapping from user_id to farm_id here !! - // This is a temp - requires adding userRepo or similar lookup - p.logger.Warn("Inventory event received without direct farm_id, cannot update stats", "event_id", event.ID, "user_id", idVal) - // Skip inventory stats update if farm_id is missing + } else if event.Type != "farm.deleted" && event.Type != "farm.created" { + p.logger.Warn("Could not determine farm_id from event payload or AggregateID", "event_type", event.Type, "event_id", event.ID, "aggregate_id", event.AggregateID) return nil } + } else if event.Type != "farm.deleted" && event.Type != "farm.created" { + p.logger.Error("Event payload is not a map, cannot extract farm_id", "event_type", event.Type, "event_id", event.ID) + return nil } } - if farmID == "" && event.Type != "farm.deleted" { // farm.deleted uses AggregateID which is the farmID being deleted + if farmID == "" && event.Type != "farm.deleted" { p.logger.Error("Cannot process event, missing farm_id", "event_type", event.Type, "event_id", event.ID, "aggregate_id", event.AggregateID) return nil } @@ -99,22 +92,21 @@ func (p *FarmAnalyticsProjection) handleEvent(event domain.Event) error { var err error switch event.Type { case "farm.created", "farm.updated": - // Need to get the full Farm domain object from the payload var farmData domain.Farm - jsonData, _ := json.Marshal(event.Payload) // Convert payload map back to JSON + jsonData, _ := json.Marshal(event.Payload) if err = json.Unmarshal(jsonData, &farmData); err != nil { p.logger.Error("Failed to unmarshal farm data from event payload", "event_id", event.ID, "error", err) - // Nack or Ack based on error strategy? Ack for now. return nil } - // Ensure UUID is set from AggregateID if missing in payload itself if farmData.UUID == "" { farmData.UUID = event.AggregateID } + + p.logger.Info("Processing farm event", "event_type", event.Type, "farm_id", farmData.UUID, "owner_id", farmData.OwnerID) err = p.repository.CreateOrUpdateFarmBaseData(ctx, &farmData) case "farm.deleted": - farmID = event.AggregateID // Use AggregateID directly for delete + farmID = event.AggregateID if farmID == "" { p.logger.Error("Cannot process farm.deleted event, missing farm_id in AggregateID", "event_id", event.ID) return nil @@ -122,12 +114,11 @@ func (p *FarmAnalyticsProjection) handleEvent(event domain.Event) error { err = p.repository.DeleteFarmAnalytics(ctx, farmID) case "weather.updated": - // Extract weather data from payload var weatherData domain.WeatherData jsonData, _ := json.Marshal(event.Payload) if err = json.Unmarshal(jsonData, &weatherData); err != nil { p.logger.Error("Failed to unmarshal weather data from event payload", "event_id", event.ID, "error", err) - return nil // Acknowledge bad data + return nil } err = p.repository.UpdateFarmAnalyticsWeather(ctx, farmID, &weatherData) @@ -146,8 +137,6 @@ func (p *FarmAnalyticsProjection) handleEvent(event domain.Event) error { err = p.repository.UpdateFarmAnalyticsCropStats(ctx, farmID) case "inventory.item.created", "inventory.item.updated", "inventory.item.deleted": - // farmID needs to be looked up or present in payload - // For now, we only touch the timestamp if farmID != "" { err = p.repository.UpdateFarmAnalyticsInventoryStats(ctx, farmID) } else { @@ -162,7 +151,6 @@ func (p *FarmAnalyticsProjection) handleEvent(event domain.Event) error { if err != nil { p.logger.Error("Failed to update farm analytics", "event_type", event.Type, "farm_id", farmID, "error", err) - // Decide whether to return the error (potentially causing requeue) or nil (ack) return nil } diff --git a/backend/internal/repository/postgres_cropland.go b/backend/internal/repository/postgres_cropland.go index 7f6e3a7..5c6e55d 100644 --- a/backend/internal/repository/postgres_cropland.go +++ b/backend/internal/repository/postgres_cropland.go @@ -124,20 +124,19 @@ func (p *postgresCroplandRepository) CreateOrUpdate(ctx context.Context, c *doma if c.GeoFeature != nil { _ = json.Unmarshal(c.GeoFeature, &geoFeatureMap) } - payload := map[string]interface{}{ - "crop_id": c.UUID, - "name": c.Name, - "status": c.Status, - "priority": c.Priority, - "land_size": c.LandSize, - "growth_stage": c.GrowthStage, - "plant_id": c.PlantID, - "farm_id": c.FarmID, - "geo_feature": geoFeatureMap, - "created_at": c.CreatedAt, - "updated_at": c.UpdatedAt, - "event_type": eventType, + "uuid": c.UUID, + "name": c.Name, + "status": c.Status, + "priority": c.Priority, + "landSize": c.LandSize, + "growthStage": c.GrowthStage, + "plantId": c.PlantID, + "farmId": c.FarmID, + "geoFeature": geoFeatureMap, + "createdAt": c.CreatedAt, + "updatedAt": c.UpdatedAt, + "event_type": eventType, } event := domain.Event{ diff --git a/backend/internal/repository/postgres_farm.go b/backend/internal/repository/postgres_farm.go index ba72476..7f05dc5 100644 --- a/backend/internal/repository/postgres_farm.go +++ b/backend/internal/repository/postgres_farm.go @@ -2,11 +2,13 @@ package repository import ( "context" + "errors" "strings" "time" "github.com/forfarm/backend/internal/domain" "github.com/google/uuid" + "github.com/jackc/pgx/v5" ) type postgresFarmRepository struct { @@ -94,11 +96,52 @@ func (p *postgresFarmRepository) fetchCroplandsByFarmIDs(ctx context.Context, fa return croplandsByFarmID, nil } +func (p *postgresFarmRepository) GetAll(ctx context.Context) ([]domain.Farm, error) { + // Query to select all farms, ordered by creation date for consistency + query := ` + SELECT uuid, name, lat, lon, farm_type, total_size, created_at, updated_at, owner_id + FROM farms + ORDER BY created_at DESC` + + // Use the existing fetch method without specific arguments for filtering + farms, err := p.fetch(ctx, query) + if err != nil { + return nil, err + } + if len(farms) == 0 { + return []domain.Farm{}, nil // Return empty slice, not nil + } + + // --- Fetch associated crops (optional but good for consistency) --- + farmIDs := make([]string, 0, len(farms)) + farmMap := make(map[string]*domain.Farm, len(farms)) + for i := range farms { + farmIDs = append(farmIDs, farms[i].UUID) + farmMap[farms[i].UUID] = &farms[i] + } + + croplandsByFarmID, err := p.fetchCroplandsByFarmIDs(ctx, farmIDs) + if err != nil { + // Log the warning but return the farms fetched so far + // Depending on requirements, you might want to return the error instead + println("Warning: Failed to fetch associated croplands during GetAll:", err.Error()) + } else { + for farmID, croplands := range croplandsByFarmID { + if farm, ok := farmMap[farmID]; ok { + farm.Crops = croplands + } + } + } + // --- End Fetch associated crops --- + + return farms, nil +} + func (p *postgresFarmRepository) GetByID(ctx context.Context, farmId string) (*domain.Farm, error) { query := ` - SELECT uuid, name, lat, lon, farm_type, total_size, created_at, updated_at, owner_id - FROM farms - WHERE uuid = $1` + SELECT uuid, name, lat, lon, farm_type, total_size, created_at, updated_at, owner_id + FROM farms + WHERE uuid = $1` var f domain.Farm err := p.conn.QueryRow(ctx, query, farmId).Scan( &f.UUID, @@ -112,8 +155,21 @@ func (p *postgresFarmRepository) GetByID(ctx context.Context, farmId string) (*d &f.OwnerID, ) if err != nil { - return nil, err + if errors.Is(err, pgx.ErrNoRows) { // Check for pgx specific error + return nil, domain.ErrNotFound + } + return nil, err // Return other errors } + + // Fetch associated crops (optional, depends if GetByID needs them) + cropsMap, err := p.fetchCroplandsByFarmIDs(ctx, []string{f.UUID}) + if err != nil { + println("Warning: Failed to fetch croplands for GetByID:", err.Error()) + // Decide whether to return the farm without crops or return the error + } else if crops, ok := cropsMap[f.UUID]; ok { + f.Crops = crops + } + return &f, nil } @@ -192,14 +248,16 @@ func (p *postgresFarmRepository) CreateOrUpdate(ctx context.Context, f *domain.F Timestamp: time.Now(), AggregateID: f.UUID, Payload: map[string]interface{}{ - "farm_id": f.UUID, - "name": f.Name, - "location": map[string]float64{"lat": f.Lat, "lon": f.Lon}, - "farm_type": f.FarmType, - "total_size": f.TotalSize, - "owner_id": f.OwnerID, - "created_at": f.CreatedAt, - "updated_at": f.UpdatedAt, + "uuid": f.UUID, + "name": f.Name, + "lat": f.Lat, + "lon": f.Lon, + "location": map[string]float64{"lat": f.Lat, "lon": f.Lon}, + "farmType": f.FarmType, + "totalSize": f.TotalSize, + "ownerId": f.OwnerID, + "createdAt": f.CreatedAt, + "updatedAt": f.UpdatedAt, }, } diff --git a/backend/internal/repository/postgres_farm_analytics.go b/backend/internal/repository/postgres_farm_analytics.go index 4b234e5..977162b 100644 --- a/backend/internal/repository/postgres_farm_analytics.go +++ b/backend/internal/repository/postgres_farm_analytics.go @@ -59,7 +59,7 @@ func (r *postgresFarmAnalyticsRepository) GetFarmAnalytics(ctx context.Context, &analytics.OwnerID, &farmType, &totalSize, - &analytics.Latitude, // Scan directly into the struct fields + &analytics.Latitude, &analytics.Longitude, &weatherJSON, &inventoryJSON, @@ -228,16 +228,16 @@ func (r *postgresFarmAnalyticsRepository) GetCropAnalytics(ctx context.Context, func (r *postgresFarmAnalyticsRepository) CreateOrUpdateFarmBaseData(ctx context.Context, farm *domain.Farm) error { query := ` - INSERT INTO farm_analytics (farm_id, farm_name, owner_id, farm_type, total_size, lat, lon, last_updated) + INSERT INTO farm_analytics (farm_id, farm_name, owner_id, farm_type, total_size, latitude, longitude, analytics_last_updated) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ON CONFLICT (farm_id) DO UPDATE SET farm_name = EXCLUDED.farm_name, owner_id = EXCLUDED.owner_id, farm_type = EXCLUDED.farm_type, total_size = EXCLUDED.total_size, - lat = EXCLUDED.lat, - lon = EXCLUDED.lon, - last_updated = EXCLUDED.last_updated;` + latitude = EXCLUDED.latitude, + longitude = EXCLUDED.longitude, + analytics_last_updated = EXCLUDED.analytics_last_updated;` _, err := r.conn.Exec(ctx, query, farm.UUID, @@ -259,158 +259,100 @@ func (r *postgresFarmAnalyticsRepository) CreateOrUpdateFarmBaseData(ctx context func (r *postgresFarmAnalyticsRepository) UpdateFarmAnalyticsWeather(ctx context.Context, farmID string, weatherData *domain.WeatherData) error { if weatherData == nil { - return fmt.Errorf("weather data cannot be nil") + return errors.New("weather data cannot be nil for update") } - - weatherJSON, err := json.Marshal(weatherData) - if err != nil { - r.logger.Error("Failed to marshal weather data for analytics update", "farm_id", farmID, "error", err) - return fmt.Errorf("failed to marshal weather data: %w", err) - } - query := ` - UPDATE farm_analytics - SET weather_data = $1, - last_updated = $2 - WHERE farm_id = $3;` + UPDATE public.farm_analytics SET + weather_temp_celsius = $2, + weather_humidity = $3, + weather_description = $4, + weather_icon = $5, + weather_wind_speed = $6, + weather_rain_1h = $7, + weather_observed_at = $8, + weather_last_updated = NOW(), -- Use current time for the update time + analytics_last_updated = NOW() + WHERE farm_id = $1` - cmdTag, err := r.conn.Exec(ctx, query, weatherJSON, time.Now().UTC(), farmID) + _, err := r.conn.Exec(ctx, query, + farmID, + weatherData.TempCelsius, + weatherData.Humidity, + weatherData.Description, + weatherData.Icon, + weatherData.WindSpeed, + weatherData.RainVolume1h, + weatherData.ObservedAt, + ) if err != nil { - r.logger.Error("Failed to update farm analytics weather data", "farm_id", farmID, "error", err) - return fmt.Errorf("database update failed for weather data: %w", err) + r.logger.Error("Error updating farm weather analytics", "farm_id", farmID, "error", err) + return fmt.Errorf("failed to update weather analytics for farm %s: %w", farmID, err) } - if cmdTag.RowsAffected() == 0 { - r.logger.Warn("No farm analytics record found to update weather data", "farm_id", farmID) - // Optionally, create the base record here if it should always exist - return domain.ErrNotFound // Or handle as appropriate - } - - r.logger.Debug("Updated farm analytics weather data", "farm_id", farmID) + r.logger.Debug("Updated farm weather analytics", "farm_id", farmID) return nil } // UpdateFarmAnalyticsCropStats needs to query the croplands table for the farm func (r *postgresFarmAnalyticsRepository) UpdateFarmAnalyticsCropStats(ctx context.Context, farmID string) error { + countQuery := ` + SELECT + COUNT(*), + COUNT(*) FILTER (WHERE lower(status) = 'growing') + FROM public.croplands + WHERE farm_id = $1 + ` var totalCount, growingCount int - - // Query to count total and growing crops for the farm - query := ` - SELECT - COUNT(*), - COUNT(*) FILTER (WHERE status = 'growing') -- Case-insensitive comparison if needed: LOWER(status) = 'growing' - FROM croplands - WHERE farm_id = $1;` - - err := r.conn.QueryRow(ctx, query, farmID).Scan(&totalCount, &growingCount) + err := r.conn.QueryRow(ctx, countQuery, farmID).Scan(&totalCount, &growingCount) if err != nil { - // Log error but don't fail the projection if stats can't be calculated temporarily - r.logger.Error("Failed to calculate crop stats for analytics", "farm_id", farmID, "error", err) - return fmt.Errorf("failed to calculate crop stats: %w", err) + if !errors.Is(err, pgx.ErrNoRows) { + r.logger.Error("Error calculating crop counts", "farm_id", farmID, "error", err) + return fmt.Errorf("failed to calculate crop stats for farm %s: %w", farmID, err) + } } - // Construct the JSONB object for crop_data - cropInfo := map[string]interface{}{ - "totalCount": totalCount, - "growingCount": growingCount, - "lastUpdated": time.Now().UTC(), // Timestamp of this calculation - } - cropJSON, err := json.Marshal(cropInfo) - if err != nil { - r.logger.Error("Failed to marshal crop stats data", "farm_id", farmID, "error", err) - return fmt.Errorf("failed to marshal crop stats: %w", err) - } - - // Update the farm_analytics table updateQuery := ` - UPDATE farm_analytics - SET crop_data = $1, - last_updated = $2 -- Also update the main last_updated timestamp - WHERE farm_id = $3;` + UPDATE public.farm_analytics SET + crop_total_count = $2, + crop_growing_count = $3, + crop_last_updated = NOW(), + analytics_last_updated = NOW() + WHERE farm_id = $1` - cmdTag, err := r.conn.Exec(ctx, updateQuery, cropJSON, time.Now().UTC(), farmID) + cmdTag, err := r.conn.Exec(ctx, updateQuery, farmID, totalCount, growingCount) if err != nil { - r.logger.Error("Failed to update farm analytics crop stats", "farm_id", farmID, "error", err) - return fmt.Errorf("database update failed for crop stats: %w", err) + r.logger.Error("Error updating farm crop stats", "farm_id", farmID, "error", err) + return fmt.Errorf("failed to update crop stats for farm %s: %w", farmID, err) } if cmdTag.RowsAffected() == 0 { r.logger.Warn("No farm analytics record found to update crop stats", "farm_id", farmID) - // Optionally, create the base record here - } else { - r.logger.Debug("Updated farm analytics crop stats", "farm_id", farmID, "total", totalCount, "growing", growingCount) + // Optionally, create the base record here if it should always exist + return r.CreateOrUpdateFarmBaseData(ctx, &domain.Farm{UUID: farmID /* Fetch other details */}) } + + r.logger.Debug("Updated farm crop stats", "farm_id", farmID, "total", totalCount, "growing", growingCount) return nil } // UpdateFarmAnalyticsInventoryStats needs to query inventory_items func (r *postgresFarmAnalyticsRepository) UpdateFarmAnalyticsInventoryStats(ctx context.Context, farmID string) error { - var totalItems, lowStockCount int - var lastUpdated sql.NullTime - - // Query to get inventory stats for the user owning the farm - // NOTE: This assumes inventory is linked by user_id, and we need the user_id for the farm owner. - // Step 1: Get Owner ID from farm_analytics table - var ownerID string - ownerQuery := `SELECT owner_id FROM farm_analytics WHERE farm_id = $1` - err := r.conn.QueryRow(ctx, ownerQuery, farmID).Scan(&ownerID) - if err != nil { - if errors.Is(err, sql.ErrNoRows) || errors.Is(err, pgx.ErrNoRows) { - r.logger.Warn("Cannot update inventory stats, farm analytics record not found", "farm_id", farmID) - return nil // Or return ErrNotFound if critical - } - r.logger.Error("Failed to get owner ID for inventory stats update", "farm_id", farmID, "error", err) - return fmt.Errorf("failed to get owner ID: %w", err) - } - - // Step 2: Query inventory based on owner ID query := ` - SELECT - COUNT(*), - COUNT(*) FILTER (WHERE status_id = (SELECT id FROM inventory_status WHERE name = 'Low Stock')), -- Assumes 'Low Stock' status name - MAX(updated_at) -- Get the latest update timestamp from inventory items - FROM inventory_items - WHERE user_id = $1;` + UPDATE public.farm_analytics SET + -- inventory_total_items = (SELECT COUNT(*) FROM ... WHERE farm_id = $1), -- Example future logic + -- inventory_low_stock_count = (SELECT COUNT(*) FROM ... WHERE farm_id = $1 AND status = 'low'), -- Example + inventory_last_updated = NOW(), + analytics_last_updated = NOW() + WHERE farm_id = $1` - err = r.conn.QueryRow(ctx, query, ownerID).Scan(&totalItems, &lowStockCount, &lastUpdated) + cmdTag, err := r.conn.Exec(ctx, query, farmID) if err != nil { - // Log error but don't fail the projection if stats can't be calculated temporarily - r.logger.Error("Failed to calculate inventory stats for analytics", "farm_id", farmID, "owner_id", ownerID, "error", err) - return fmt.Errorf("failed to calculate inventory stats: %w", err) - } - - // Construct the JSONB object for inventory_data - inventoryInfo := map[string]interface{}{ - "totalItems": totalItems, - "lowStockCount": lowStockCount, - "lastUpdated": nil, // Initialize as nil - } - // Only set lastUpdated if the MAX(updated_at) query returned a valid time - if lastUpdated.Valid { - inventoryInfo["lastUpdated"] = lastUpdated.Time.UTC() - } - - inventoryJSON, err := json.Marshal(inventoryInfo) - if err != nil { - r.logger.Error("Failed to marshal inventory stats data", "farm_id", farmID, "error", err) - return fmt.Errorf("failed to marshal inventory stats: %w", err) - } - - // Update the farm_analytics table - updateQuery := ` - UPDATE farm_analytics - SET inventory_data = $1, - last_updated = $2 -- Also update the main last_updated timestamp - WHERE farm_id = $3;` - - cmdTag, err := r.conn.Exec(ctx, updateQuery, inventoryJSON, time.Now().UTC(), farmID) - if err != nil { - r.logger.Error("Failed to update farm analytics inventory stats", "farm_id", farmID, "error", err) - return fmt.Errorf("database update failed for inventory stats: %w", err) + r.logger.Error("Error touching inventory timestamp in farm analytics", "farm_id", farmID, "error", err) + return fmt.Errorf("failed to update inventory stats timestamp for farm %s: %w", farmID, err) } if cmdTag.RowsAffected() == 0 { - r.logger.Warn("No farm analytics record found to update inventory stats", "farm_id", farmID) - } else { - r.logger.Debug("Updated farm analytics inventory stats", "farm_id", farmID, "total", totalItems, "lowStock", lowStockCount) + r.logger.Warn("No farm analytics record found to update inventory timestamp", "farm_id", farmID) } + + r.logger.Debug("Updated farm inventory timestamp", "farm_id", farmID) return nil } @@ -432,20 +374,18 @@ func (r *postgresFarmAnalyticsRepository) DeleteFarmAnalytics(ctx context.Contex func (r *postgresFarmAnalyticsRepository) UpdateFarmOverallStatus(ctx context.Context, farmID string, status string) error { query := ` - UPDATE farm_analytics - SET overall_status = $1, - last_updated = $2 - WHERE farm_id = $3;` + UPDATE public.farm_analytics SET + overall_status = $2, + analytics_last_updated = NOW() + WHERE farm_id = $1` - cmdTag, err := r.conn.Exec(ctx, query, status, time.Now().UTC(), farmID) + cmdTag, err := r.conn.Exec(ctx, query, farmID, status) if err != nil { - r.logger.Error("Failed to update farm overall status", "farm_id", farmID, "status", status, "error", err) - return fmt.Errorf("database update failed for overall status: %w", err) + r.logger.Error("Error updating farm overall status", "farm_id", farmID, "status", status, "error", err) + return fmt.Errorf("failed to update overall status for farm %s: %w", farmID, err) } if cmdTag.RowsAffected() == 0 { r.logger.Warn("No farm analytics record found to update overall status", "farm_id", farmID) - // Optionally, create the base record here if needed - return domain.ErrNotFound } r.logger.Debug("Updated farm overall status", "farm_id", farmID, "status", status) return nil diff --git a/backend/internal/repository/postgres_inventory.go b/backend/internal/repository/postgres_inventory.go index c0e1287..f5ef4bf 100644 --- a/backend/internal/repository/postgres_inventory.go +++ b/backend/internal/repository/postgres_inventory.go @@ -268,15 +268,15 @@ func (p *postgresInventoryRepository) CreateOrUpdate(ctx context.Context, item * } payload := map[string]interface{}{ - "item_id": item.ID, - "user_id": item.UserID, // Include user ID for potential farm lookup in projection - "name": item.Name, - "category_id": item.CategoryID, - "quantity": item.Quantity, - "unit_id": item.UnitID, - "status_id": item.StatusID, - "date_added": item.DateAdded, - "updated_at": item.UpdatedAt, + "id": item.ID, + "userId": item.UserID, // Include user ID for potential farm lookup in projection + "name": item.Name, + "categoryId": item.CategoryID, + "quantity": item.Quantity, + "unitId": item.UnitID, + "statusId": item.StatusID, + "dateAdded": item.DateAdded, + "updatedAt": item.UpdatedAt, // NO farm_id easily available here without extra lookup } diff --git a/backend/internal/repository/postgres_plant.go b/backend/internal/repository/postgres_plant.go index 963c31a..bb4eb38 100644 --- a/backend/internal/repository/postgres_plant.go +++ b/backend/internal/repository/postgres_plant.go @@ -51,6 +51,15 @@ func (p *postgresPlantRepository) GetByUUID(ctx context.Context, uuid string) (d return plants[0], nil } +func (p *postgresPlantRepository) GetByName(ctx context.Context, name string) (domain.Plant, error) { + query := `SELECT * FROM plants WHERE name = $1` + plants, err := p.fetch(ctx, query, name) + if err != nil || len(plants) == 0 { + return domain.Plant{}, domain.ErrNotFound + } + return plants[0], nil +} + func (p *postgresPlantRepository) GetAll(ctx context.Context) ([]domain.Plant, error) { query := `SELECT * FROM plants` return p.fetch(ctx, query) diff --git a/backend/internal/services/analytics_service.go b/backend/internal/services/analytics_service.go index d412dc8..fa79dfa 100644 --- a/backend/internal/services/analytics_service.go +++ b/backend/internal/services/analytics_service.go @@ -7,41 +7,31 @@ import ( "github.com/forfarm/backend/internal/domain" ) -// AnalyticsService provides methods for calculating or deriving analytics data. -// For now, it contains dummy implementations. type AnalyticsService struct { - // Add dependencies like repositories if needed for real logic later } -// NewAnalyticsService creates a new AnalyticsService. func NewAnalyticsService() *AnalyticsService { return &AnalyticsService{} } -// CalculatePlantHealth provides a dummy health status. -// TODO: Implement real health calculation based on status, weather, events, etc. func (s *AnalyticsService) CalculatePlantHealth(status string, growthStage string) string { - // Simple dummy logic switch status { case "Problem", "Diseased", "Infested": return "warning" case "Fallow", "Harvested": - return "n/a" // Or maybe 'good' if fallow is considered healthy state + return "n/a" default: - // Slightly randomize for demo purposes - if rand.Intn(10) < 2 { // 20% chance of warning even if status is 'growing' + // 20% chance of warning even if status is 'growing' + if rand.Intn(10) < 2 { return "warning" } return "good" } } -// SuggestNextAction provides a dummy next action based on growth stage. -// TODO: Implement real suggestion logic based on stage, weather, history, plant type etc. func (s *AnalyticsService) SuggestNextAction(growthStage string, lastUpdated time.Time) (action *string, dueDate *time.Time) { - // Default action nextActionStr := "Monitor crop health" - nextDueDate := time.Now().Add(24 * time.Hour) // Check tomorrow + nextDueDate := time.Now().Add(24 * time.Hour) switch growthStage { case "Planned", "Planting": @@ -58,30 +48,27 @@ func (s *AnalyticsService) SuggestNextAction(growthStage string, lastUpdated tim nextDueDate = time.Now().Add(48 * time.Hour) case "Fruiting", "Ripening": nextActionStr = "Monitor fruit development and prepare for harvest" - nextDueDate = time.Now().Add(7 * 24 * time.Hour) // Check in a week + nextDueDate = time.Now().Add(7 * 24 * time.Hour) case "Harvesting": nextActionStr = "Proceed with harvest" nextDueDate = time.Now().Add(24 * time.Hour) } - // Only return if the suggestion is "newer" than the last update to avoid constant same suggestion - // This is basic logic, real implementation would be more complex - if nextDueDate.After(lastUpdated.Add(1 * time.Hour)) { // Only suggest if due date is >1hr after last update + // Only suggest if due date is >1hr after last update + if nextDueDate.After(lastUpdated.Add(1 * time.Hour)) { return &nextActionStr, &nextDueDate } - return nil, nil // No immediate action needed or suggestion is old + return nil, nil } -// GetNutrientLevels provides dummy nutrient levels. -// TODO: Implement real nutrient level fetching (e.g., from soil sensors, lab results events). func (s *AnalyticsService) GetNutrientLevels(cropID string) *struct { Nitrogen *float64 `json:"nitrogen,omitempty"` Phosphorus *float64 `json:"phosphorus,omitempty"` Potassium *float64 `json:"potassium,omitempty"` } { - // Return dummy data or nil if unavailable - if rand.Intn(10) < 7 { // 70% chance of having dummy data + // 70% chance of having dummy data + if rand.Intn(10) < 7 { n := float64(50 + rand.Intn(40)) // 50-89 p := float64(40 + rand.Intn(40)) // 40-79 k := float64(45 + rand.Intn(40)) // 45-84 @@ -95,26 +82,20 @@ func (s *AnalyticsService) GetNutrientLevels(cropID string) *struct { Potassium: &k, } } - return nil // Simulate data not available + return nil } -// GetEnvironmentalData attempts to retrieve relevant environmental data. -// TODO: Enhance this - Could query specific weather events for the crop location/timeframe. -// Currently relies on potentially stale FarmAnalytics weather. func (s *AnalyticsService) GetEnvironmentalData(farmAnalytics *domain.FarmAnalytics) (temp, humidity, wind, rain, sunlight, soilMoisture *float64) { - // Initialize with nil temp, humidity, wind, rain, sunlight, soilMoisture = nil, nil, nil, nil, nil, nil - // Try to get from FarmAnalytics if farmAnalytics != nil && farmAnalytics.Weather != nil { temp = farmAnalytics.Weather.TempCelsius humidity = farmAnalytics.Weather.Humidity wind = farmAnalytics.Weather.WindSpeed rain = farmAnalytics.Weather.RainVolume1h - // Note: Sunlight and SoilMoisture are not typically in basic WeatherData } - // Provide dummy values ONLY if still nil (ensures real data isn't overwritten) + // Provide dummy values only if data is missing if temp == nil { t := float64(18 + rand.Intn(15)) // 18-32 C temp = &t @@ -128,7 +109,6 @@ func (s *AnalyticsService) GetEnvironmentalData(farmAnalytics *domain.FarmAnalyt wind = &w } if rain == nil { - // Simulate less frequent rain r := 0.0 if rand.Intn(10) < 2 { // 20% chance of rain r = float64(rand.Intn(5)) // 0-4 mm @@ -144,5 +124,5 @@ func (s *AnalyticsService) GetEnvironmentalData(farmAnalytics *domain.FarmAnalyt soilMoisture = &sm } - return // Named return values + return } diff --git a/backend/internal/services/chat_service.go b/backend/internal/services/chat_service.go new file mode 100644 index 0000000..b3d0af6 --- /dev/null +++ b/backend/internal/services/chat_service.go @@ -0,0 +1,445 @@ +package services + +import ( + "context" + "errors" + "fmt" + "log/slog" + "math/rand" + "strings" + "time" + + "github.com/forfarm/backend/internal/config" + "github.com/forfarm/backend/internal/domain" + "github.com/google/generative-ai-go/genai" + "google.golang.org/api/option" +) + +type ChatService struct { + client *genai.Client + logger *slog.Logger + analyticsRepo domain.AnalyticsRepository + farmRepo domain.FarmRepository + cropRepo domain.CroplandRepository + inventoryRepo domain.InventoryRepository + plantRepo domain.PlantRepository +} + +func NewChatService( + logger *slog.Logger, + analyticsRepo domain.AnalyticsRepository, + farmRepo domain.FarmRepository, + cropRepo domain.CroplandRepository, + inventoryRepo domain.InventoryRepository, + plantRepo domain.PlantRepository, +) (*ChatService, error) { + if config.GEMINI_API_KEY == "" { + logger.Warn("GEMINI_API_KEY not set, ChatService will not function.") + return &ChatService{client: nil, logger: logger}, nil + } + + ctx := context.Background() + client, err := genai.NewClient(ctx, option.WithAPIKey(config.GEMINI_API_KEY)) + if err != nil { + logger.Error("Failed to create Gemini client", "error", err) + return nil, fmt.Errorf("error creating genai client: %w", err) + } + + logger.Info("Gemini client initialized successfully") + return &ChatService{ + client: client, + logger: logger, + analyticsRepo: analyticsRepo, + farmRepo: farmRepo, + cropRepo: cropRepo, + inventoryRepo: inventoryRepo, + plantRepo: plantRepo, + }, nil +} + +type GenerateResponseInput struct { + UserID string + Message string + FarmID string + CropID string + History []*genai.Content +} + +// --- Context Building Helpers --- + +func (s *ChatService) buildCropContextString(ctx context.Context, cropID, userID string) (string, error) { + var contextBuilder strings.Builder + contextBuilder.WriteString("## Current Crop & Plant Context ##\n") + + cropAnalytics, err := s.analyticsRepo.GetCropAnalytics(ctx, cropID) + if err != nil { + if errors.Is(err, domain.ErrNotFound) { + s.logger.Warn("Crop analytics not found for context", "cropId", cropID) + return "", fmt.Errorf("crop not found") + } + s.logger.Error("Failed to fetch crop analytics context", "cropId", cropID, "error", err) + contextBuilder.WriteString(fmt.Sprintf("Error fetching crop details for ID %s.\n", cropID)) + return "", fmt.Errorf("failed to fetch crop details") + } + + farm, err := s.farmRepo.GetByID(ctx, cropAnalytics.FarmID) + if err != nil || farm.OwnerID != userID { + s.logger.Warn("Ownership check failed for crop context", "cropId", cropID, "farmId", cropAnalytics.FarmID, "userId", userID) + return "", fmt.Errorf("unauthorized access to crop data") + } + + fmt.Fprintf(&contextBuilder, "Crop Name: %s (ID: %s)\n", cropAnalytics.CropName, cropAnalytics.CropID) + fmt.Fprintf(&contextBuilder, "Farm: %s (ID: %s)\n", farm.Name, cropAnalytics.FarmID) + fmt.Fprintf(&contextBuilder, "Plant: %s (Variety: %s)\n", cropAnalytics.PlantName, safeString(cropAnalytics.Variety)) + fmt.Fprintf(&contextBuilder, "Status: %s\n", cropAnalytics.CurrentStatus) + fmt.Fprintf(&contextBuilder, "Growth Stage: %s\n", cropAnalytics.GrowthStage) + fmt.Fprintf(&contextBuilder, "Land Size: %.2f ha\n", cropAnalytics.LandSize) + fmt.Fprintf(&contextBuilder, "Growth Progress: %d%%\n", cropAnalytics.GrowthProgress) + if cropAnalytics.PlantHealth != nil { + fmt.Fprintf(&contextBuilder, "Health Status: %s\n", *cropAnalytics.PlantHealth) + } + if cropAnalytics.Temperature != nil { + fmt.Fprintf(&contextBuilder, "Temperature: %.1f°C\n", *cropAnalytics.Temperature) + } + if cropAnalytics.Humidity != nil { + fmt.Fprintf(&contextBuilder, "Humidity: %.0f%%\n", *cropAnalytics.Humidity) + } + if cropAnalytics.SoilMoisture != nil { + fmt.Fprintf(&contextBuilder, "Soil Moisture: %.0f%%\n", *cropAnalytics.SoilMoisture) + } + if cropAnalytics.Rainfall != nil { + fmt.Fprintf(&contextBuilder, "Rainfall (1h): %.1f mm\n", *cropAnalytics.Rainfall) + } + if cropAnalytics.WindSpeed != nil { + fmt.Fprintf(&contextBuilder, "Wind Speed: %.1f m/s\n", *cropAnalytics.WindSpeed) + } + if cropAnalytics.Sunlight != nil { + fmt.Fprintf(&contextBuilder, "Sunlight Exposure: %.0f%%\n", *cropAnalytics.Sunlight) + } + if cropAnalytics.NutrientLevels != nil { + contextBuilder.WriteString("Nutrients: ") + nutrients := []string{} + if cropAnalytics.NutrientLevels.Nitrogen != nil { + nutrients = append(nutrients, fmt.Sprintf("N=%.0f%%", *cropAnalytics.NutrientLevels.Nitrogen)) + } + if cropAnalytics.NutrientLevels.Phosphorus != nil { + nutrients = append(nutrients, fmt.Sprintf("P=%.0f%%", *cropAnalytics.NutrientLevels.Phosphorus)) + } + if cropAnalytics.NutrientLevels.Potassium != nil { + nutrients = append(nutrients, fmt.Sprintf("K=%.0f%%", *cropAnalytics.NutrientLevels.Potassium)) + } + if len(nutrients) > 0 { + contextBuilder.WriteString(strings.Join(nutrients, ", ")) + } else { + contextBuilder.WriteString("Not Available") + } + contextBuilder.WriteString("\n") + } + if cropAnalytics.NextAction != nil { + dueStr := "" + if cropAnalytics.NextActionDue != nil { + dueStr = fmt.Sprintf(" (Due: %s)", cropAnalytics.NextActionDue.Format(time.RFC1123)) + } + fmt.Fprintf(&contextBuilder, "Suggested Next Action: %s%s\n", *cropAnalytics.NextAction, dueStr) + } + contextBuilder.WriteString("\n") + + contextBuilder.WriteString("Plant Details:\n") + plant, err := s.plantRepo.GetByName(ctx, cropAnalytics.PlantName) + if err != nil { + s.logger.Warn("Could not fetch plant details for context", "plantId", cropAnalytics.PlantName, "error", err) + fmt.Fprintf(&contextBuilder, " - Could not retrieve plant details.\n") + } else { + fmt.Fprintf(&contextBuilder, " - Type: %s (Variety: %s)\n", plant.Name, safeString(plant.Variety)) + if plant.DaysToMaturity != nil { + fmt.Fprintf(&contextBuilder, " - Days to Maturity: ~%d\n", *plant.DaysToMaturity) + } + if plant.OptimalTemp != nil { + fmt.Fprintf(&contextBuilder, " - Optimal Temp: %.1f°C\n", *plant.OptimalTemp) + } + if plant.WaterNeeds != nil { + fmt.Fprintf(&contextBuilder, " - Water Needs: %.1f (units unspecified)\n", *plant.WaterNeeds) + } + if plant.PHValue != nil { + fmt.Fprintf(&contextBuilder, " - Soil pH: %.1f\n", *plant.PHValue) + } + if plant.RowSpacing != nil { + fmt.Fprintf(&contextBuilder, " - Row Spacing: %.1f (units unspecified)\n", *plant.RowSpacing) + } + if plant.PlantingDepth != nil { + fmt.Fprintf(&contextBuilder, " - Planting Depth: %.1f (units unspecified)\n", *plant.PlantingDepth) + } + } + + contextBuilder.WriteString("\n") + + inventoryContext, _ := s.buildInventoryContextString(ctx, userID) + contextBuilder.WriteString(inventoryContext) + + return contextBuilder.String(), nil +} + +func (s *ChatService) buildFarmContextString(ctx context.Context, farmID, userID string) (string, error) { + var contextBuilder strings.Builder + contextBuilder.WriteString("## Current Farm Context ##\n") + + farmAnalytics, err := s.analyticsRepo.GetFarmAnalytics(ctx, farmID) + if err != nil || farmAnalytics.OwnerID != userID { + if errors.Is(err, domain.ErrNotFound) || farmAnalytics == nil || farmAnalytics.OwnerID != userID { + s.logger.Warn("Farm analytics not found or ownership mismatch for context", "farmId", farmID, "userId", userID) + return "", fmt.Errorf("farm not found or access denied") + } + s.logger.Error("Failed to fetch farm analytics context", "farmId", farmID, "error", err) + return "", fmt.Errorf("failed to fetch farm details") + } + + fmt.Fprintf(&contextBuilder, "Farm Name: %s (ID: %s)\n", farmAnalytics.FarmName, farmAnalytics.FarmID) + if farmAnalytics.FarmType != nil { + fmt.Fprintf(&contextBuilder, "Type: %s\n", *farmAnalytics.FarmType) + } + if farmAnalytics.TotalSize != nil { + fmt.Fprintf(&contextBuilder, "Size: %s\n", *farmAnalytics.TotalSize) + } + fmt.Fprintf(&contextBuilder, "Location: Lat %.4f, Lon %.4f\n", farmAnalytics.Latitude, farmAnalytics.Longitude) + if farmAnalytics.OverallStatus != nil { + fmt.Fprintf(&contextBuilder, "Overall Status: %s\n", *farmAnalytics.OverallStatus) + } + if farmAnalytics.Weather != nil { + contextBuilder.WriteString("Weather:\n") + if farmAnalytics.Weather.TempCelsius != nil { + fmt.Fprintf(&contextBuilder, " - Temp: %.1f°C\n", *farmAnalytics.Weather.TempCelsius) + } + if farmAnalytics.Weather.Humidity != nil { + fmt.Fprintf(&contextBuilder, " - Humidity: %.0f%%\n", *farmAnalytics.Weather.Humidity) + } + if farmAnalytics.Weather.Description != nil { + fmt.Fprintf(&contextBuilder, " - Condition: %s\n", *farmAnalytics.Weather.Description) + } + if farmAnalytics.Weather.WindSpeed != nil { + fmt.Fprintf(&contextBuilder, " - Wind: %.1f m/s\n", *farmAnalytics.Weather.WindSpeed) + } + if farmAnalytics.Weather.RainVolume1h != nil { + fmt.Fprintf(&contextBuilder, " - Rain (1h): %.1f mm\n", *farmAnalytics.Weather.RainVolume1h) + } + if farmAnalytics.Weather.WeatherLastUpdated != nil { + fmt.Fprintf(&contextBuilder, " - Last Updated: %s\n", farmAnalytics.Weather.WeatherLastUpdated.Format(time.RFC1123)) + } + } + + crops, err := s.cropRepo.GetByFarmID(ctx, farmID) + if err == nil && len(crops) > 0 { + contextBuilder.WriteString("Crops on Farm:\n") + for i, crop := range crops { + if i >= 5 { + fmt.Fprintf(&contextBuilder, " - ... and %d more\n", len(crops)-5) + break + } + fmt.Fprintf(&contextBuilder, " - %s (Status: %s, Stage: %s)\n", crop.Name, crop.Status, crop.GrowthStage) + } + } else if err != nil { + s.logger.Warn("Failed to fetch crops for farm context", "farmId", farmID, "error", err) + } + + contextBuilder.WriteString("\n") + inventoryContext, _ := s.buildInventoryContextString(ctx, userID) + contextBuilder.WriteString(inventoryContext) + + return contextBuilder.String(), nil +} + +func (s *ChatService) buildInventoryContextString(ctx context.Context, userID string) (string, error) { + var contextBuilder strings.Builder + contextBuilder.WriteString("## Inventory Summary ##\n") + + filter := domain.InventoryFilter{UserID: userID} + sort := domain.InventorySort{Field: "name", Direction: "asc"} + items, err := s.inventoryRepo.GetByUserID(ctx, userID, filter, sort) + if err != nil { + s.logger.Warn("Failed to fetch inventory for context", "userId", userID, "error", err) + fmt.Fprintf(&contextBuilder, "Could not retrieve inventory details.\n") + return contextBuilder.String(), err + } + + if len(items) == 0 { + fmt.Fprintf(&contextBuilder, "No inventory items found.\n") + return contextBuilder.String(), nil + } + + lowStockCount := 0 + fmt.Fprintf(&contextBuilder, "Items (%d total):\n", len(items)) + limit := 10 + for i, item := range items { + if i >= limit { + fmt.Fprintf(&contextBuilder, "- ... and %d more\n", len(items)-limit) + break + } + statusName := item.Status.Name + if statusName == "" && item.StatusID != 0 { + statusName = fmt.Sprintf("StatusID %d", item.StatusID) + } + unitName := item.Unit.Name + if unitName == "" && item.UnitID != 0 { + unitName = fmt.Sprintf("UnitID %d", item.UnitID) + } + + fmt.Fprintf(&contextBuilder, "- %s: %.2f %s (Status: %s)\n", item.Name, item.Quantity, unitName, statusName) + if strings.Contains(strings.ToLower(statusName), "low") { + lowStockCount++ + } + } + if lowStockCount > 0 { + fmt.Fprintf(&contextBuilder, "Note: %d item(s) are low on stock.\n", lowStockCount) + } + + return contextBuilder.String(), nil +} + +func (s *ChatService) buildGeneralContextString(ctx context.Context, userID string) (string, error) { + var contextBuilder strings.Builder + contextBuilder.WriteString("## General Farming Context ##\n") + + farms, err := s.farmRepo.GetByOwnerID(ctx, userID) + if err == nil && len(farms) > 0 { + contextBuilder.WriteString("Your Farms:\n") + for i, farm := range farms { + if i >= 5 { + fmt.Fprintf(&contextBuilder, "- ... and %d more\n", len(farms)-5) + break + } + fmt.Fprintf(&contextBuilder, "- %s (Type: %s, Size: %s)\n", farm.Name, farm.FarmType, farm.TotalSize) + } + } else if err != nil { + s.logger.Warn("Failed to fetch farms for general context", "userId", userID, "error", err) + } else { + contextBuilder.WriteString("No farms found for your account.\n") + } + contextBuilder.WriteString("\n") + + inventoryContext, _ := s.buildInventoryContextString(ctx, userID) + contextBuilder.WriteString(inventoryContext) + + return contextBuilder.String(), nil +} + +func (s *ChatService) GenerateResponse(ctx context.Context, input GenerateResponseInput) (string, error) { + var contextString string + var contextErr error + startTime := time.Now() + + if input.CropID != "" { + s.logger.Debug("Building context for CROP", "cropId", input.CropID) + contextString, contextErr = s.buildCropContextString(ctx, input.CropID, input.UserID) + } else if input.FarmID != "" { + s.logger.Debug("Building context for FARM", "farmId", input.FarmID) + contextString, contextErr = s.buildFarmContextString(ctx, input.FarmID, input.UserID) + } else { + s.logger.Debug("Building GENERAL context", "userId", input.UserID) + contextString, contextErr = s.buildGeneralContextString(ctx, input.UserID) + } + + newsContext, _ := s.retrieveDummyNews(ctx) + weatherOutlook, _ := s.retrieveDummyWeatherOutlook(ctx, input.FarmID) + + fullContext := strings.Builder{} + fullContext.WriteString(contextString) + if contextErr != nil { + s.logger.Warn("Error building primary context string", "error", contextErr, "userId", input.UserID, "farmId", input.FarmID, "cropId", input.CropID) + fullContext.WriteString(fmt.Sprintf("Warning: Could not retrieve specific data (%s).\n\n", contextErr)) + } + fullContext.WriteString(newsContext) + fullContext.WriteString(weatherOutlook) + + contextDuration := time.Since(startTime) + s.logger.Debug("Context retrieval duration", "duration", contextDuration) + + model := s.client.GenerativeModel("gemini-1.5-flash") + systemInstruction := `You are ForFarm Assistant, an expert AI specialized in agriculture and farming practices. + Your goal is to provide helpful, accurate, and concise advice to farmers using the ForFarm platform. + Use the provided context data about the user's specific farm, crops, or inventory when available to tailor your response. + If context is provided, prioritize answering based on that context. + If no specific context is available or relevant, provide general best-practice farming advice. + Focus on actionable recommendations where appropriate. + Keep responses focused on farming, agriculture, crop management, pest control, soil health, weather impacts, and inventory management.` + model.SystemInstruction = &genai.Content{Parts: []genai.Part{genai.Text(systemInstruction)}} + fullPrompt := fmt.Sprintf("%s\nUser Question: %s", strings.TrimSpace(fullContext.String()), input.Message) + + session := model.StartChat() + session.History = input.History + + s.logger.Info("Sending message to LLM", "userId", input.UserID, "historyLength", len(session.History), "contextLength", len(fullContext.String())) + + resp, err := session.SendMessage(ctx, genai.Text(fullPrompt)) + llmDuration := time.Since(startTime) - contextDuration + s.logger.Debug("LLM response duration", "duration", llmDuration) + + if err != nil { + s.logger.Error("Error sending message to Gemini", "error", err) + return "Sorry, I encountered an error while generating a response.", fmt.Errorf("LLM communication failed: %w", err) + } + + var responseText strings.Builder + if len(resp.Candidates) > 0 && resp.Candidates[0].Content != nil { + for _, part := range resp.Candidates[0].Content.Parts { + if txt, ok := part.(genai.Text); ok { + responseText.WriteString(string(txt)) + } + } + } + + if responseText.Len() == 0 { + s.logger.Warn("Received no valid text content from Gemini", "finishReason", resp.Candidates[0].FinishReason) + if resp.Candidates[0].FinishReason != genai.FinishReasonStop { + return fmt.Sprintf("My response generation was interrupted (%s). Could you please try rephrasing?", resp.Candidates[0].FinishReason), nil + } + return "I apologize, I couldn't generate a response for that request.", nil + } + + s.logger.Info("Successfully generated chat response", "userId", input.UserID, "responseLength", responseText.Len()) + return responseText.String(), nil +} + +// Simulates fetching news with artificial delay and random selection +func (s *ChatService) retrieveDummyNews(ctx context.Context) (string, error) { + s.logger.Debug("Retrieving dummy news context") + time.Sleep(50 * time.Millisecond) + if rand.Intn(10) > 2 { + newsItems := []string{ + "Global wheat prices show slight increase.", + "New organic pest control method using beneficial nematodes gaining traction.", + "Research highlights drought-resistant corn variety performance.", + "Government announces new subsidies for sustainable farming practices.", + } + return fmt.Sprintf("## Recent Agricultural News ##\n- %s\n\n", newsItems[rand.Intn(len(newsItems))]), nil + } + return "", nil +} + +// Simulates fetching weather forecast with artificial delay and random selection +func (s *ChatService) retrieveDummyWeatherOutlook(ctx context.Context, farmID string) (string, error) { + s.logger.Debug("Retrieving dummy weather outlook context", "farmId", farmID) + time.Sleep(80 * time.Millisecond) + forecasts := []string{ + "Clear skies expected for the next 3 days.", + "Chance of scattered showers tomorrow afternoon.", + "Temperature expected to rise towards the weekend.", + "Slightly higher winds predicted for Thursday.", + } + return fmt.Sprintf("## Weather Outlook ##\n- %s\n\n", forecasts[rand.Intn(len(forecasts))]), nil +} + +func safeString(s *string) string { + if s == nil { + return "N/A" + } + return *s +} + +func (s *ChatService) Close() { + if s.client != nil { + if err := s.client.Close(); err != nil { + s.logger.Error("Failed to close Gemini client", "error", err) + } else { + s.logger.Info("Gemini client closed.") + } + } +} diff --git a/backend/internal/services/weather/openweathermap_fetcher.go b/backend/internal/services/weather/openweathermap_fetcher.go index 6b5b676..6297564 100644 --- a/backend/internal/services/weather/openweathermap_fetcher.go +++ b/backend/internal/services/weather/openweathermap_fetcher.go @@ -1,4 +1,3 @@ -// backend/internal/services/weather/openweathermap_fetcher.go package weather import ( @@ -14,45 +13,57 @@ import ( "github.com/forfarm/backend/internal/domain" ) -const openWeatherMapOneCallAPIURL = "https://api.openweathermap.org/data/3.0/onecall" +const openWeatherMapCurrentAPIURL = "https://api.openweathermap.org/data/2.5/weather" -type openWeatherMapOneCallResponse struct { - Lat float64 `json:"lat"` - Lon float64 `json:"lon"` - Timezone string `json:"timezone"` - TimezoneOffset int `json:"timezone_offset"` - Current *struct { - Dt int64 `json:"dt"` // Current time, Unix, UTC - Sunrise int64 `json:"sunrise"` - Sunset int64 `json:"sunset"` - Temp float64 `json:"temp"` // Kelvin by default, 'units=metric' for Celsius - FeelsLike float64 `json:"feels_like"` // Kelvin by default - Pressure int `json:"pressure"` // hPa - Humidity int `json:"humidity"` // % - DewPoint float64 `json:"dew_point"` - Uvi float64 `json:"uvi"` - Clouds int `json:"clouds"` // % - Visibility int `json:"visibility"` // meters - WindSpeed float64 `json:"wind_speed"` // meter/sec by default - WindDeg int `json:"wind_deg"` - WindGust float64 `json:"wind_gust,omitempty"` - Rain *struct { - OneH float64 `json:"1h"` // Rain volume for the last 1 hour, mm - } `json:"rain,omitempty"` - Snow *struct { - OneH float64 `json:"1h"` // Snow volume for the last 1 hour, mm - } `json:"snow,omitempty"` - Weather []struct { - ID int `json:"id"` - Main string `json:"main"` - Description string `json:"description"` - Icon string `json:"icon"` - } `json:"weather"` - } `json:"current,omitempty"` - // Minutely []... - // Hourly []... - // Daily []... - // Alerts []... +type openWeatherMapCurrentResponse struct { + Coord struct { + Lon float64 `json:"lon"` + Lat float64 `json:"lat"` + } `json:"coord"` + Weather []struct { + ID int `json:"id"` + Main string `json:"main"` + Description string `json:"description"` + Icon string `json:"icon"` + } `json:"weather"` + Base string `json:"base"` + Main *struct { + Temp float64 `json:"temp"` + FeelsLike float64 `json:"feels_like"` + TempMin float64 `json:"temp_min"` + TempMax float64 `json:"temp_max"` + Pressure int `json:"pressure"` + Humidity int `json:"humidity"` + SeaLevel int `json:"sea_level,omitempty"` + GrndLevel int `json:"grnd_level,omitempty"` + } `json:"main"` + Visibility int `json:"visibility"` + Wind *struct { + Speed float64 `json:"speed"` + Deg int `json:"deg"` + Gust float64 `json:"gust,omitempty"` + } `json:"wind"` + Rain *struct { + OneH float64 `json:"1h"` + } `json:"rain,omitempty"` + Snow *struct { + OneH float64 `json:"1h"` + } `json:"snow,omitempty"` + Clouds *struct { + All int `json:"all"` + } `json:"clouds"` + Dt int64 `json:"dt"` + Sys *struct { + Type int `json:"type,omitempty"` + ID int `json:"id,omitempty"` + Country string `json:"country"` + Sunrise int64 `json:"sunrise"` + Sunset int64 `json:"sunset"` + } `json:"sys"` + Timezone int `json:"timezone"` + ID int `json:"id"` + Name string `json:"name"` + Cod int `json:"cod"` } type OpenWeatherMapFetcher struct { @@ -80,11 +91,10 @@ func (f *OpenWeatherMapFetcher) GetCurrentWeatherByCoords(ctx context.Context, l queryParams.Set("lat", fmt.Sprintf("%.4f", lat)) queryParams.Set("lon", fmt.Sprintf("%.4f", lon)) queryParams.Set("appid", f.apiKey) - queryParams.Set("units", "metric") // Request Celsius and m/s - queryParams.Set("exclude", "minutely,hourly,daily,alerts") // Exclude parts we don't need now + queryParams.Set("units", "metric") - fullURL := fmt.Sprintf("%s?%s", openWeatherMapOneCallAPIURL, queryParams.Encode()) - f.logger.Debug("Fetching weather from OpenWeatherMap OneCall API", "url", fullURL) + fullURL := fmt.Sprintf("%s?%s", openWeatherMapCurrentAPIURL, queryParams.Encode()) + f.logger.Debug("Fetching weather from OpenWeatherMap Current API", "url", fullURL) req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, nil) if err != nil { @@ -100,7 +110,6 @@ func (f *OpenWeatherMapFetcher) GetCurrentWeatherByCoords(ctx context.Context, l defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - // TODO: Read resp.Body to get error message from OpenWeatherMap bodyBytes, _ := io.ReadAll(resp.Body) f.logger.Error("OpenWeatherMap API returned non-OK status", "url", fullURL, @@ -109,46 +118,60 @@ func (f *OpenWeatherMapFetcher) GetCurrentWeatherByCoords(ctx context.Context, l return nil, fmt.Errorf("weather API request failed with status: %s", resp.Status) } - var owmResp openWeatherMapOneCallResponse + var owmResp openWeatherMapCurrentResponse if err := json.NewDecoder(resp.Body).Decode(&owmResp); err != nil { - f.logger.Error("Failed to decode OpenWeatherMap OneCall response", "error", err) + f.logger.Error("Failed to decode OpenWeatherMap Current response", "error", err) return nil, fmt.Errorf("failed to decode weather response: %w", err) } - if owmResp.Current == nil { - f.logger.Warn("OpenWeatherMap OneCall response missing 'current' weather data", "lat", lat, "lon", lon) - return nil, fmt.Errorf("current weather data not found in API response") - } - current := owmResp.Current + // --- Data Mapping from openWeatherMapCurrentResponse to domain.WeatherData --- - if len(current.Weather) == 0 { - f.logger.Warn("OpenWeatherMap response missing weather description details", "lat", lat, "lon", lon) - return nil, fmt.Errorf("weather data description not found in response") + if owmResp.Main == nil { + f.logger.Error("OpenWeatherMap Current response missing 'main' data block", "lat", lat, "lon", lon) + return nil, fmt.Errorf("main weather data block not found in API response") } - // Create domain object using pointers for optional fields - weatherData := &domain.WeatherData{} // Initialize empty struct first + weatherData := &domain.WeatherData{} - // Assign values using pointers, checking for nil where appropriate - weatherData.TempCelsius = ¤t.Temp - humidityFloat := float64(current.Humidity) + weatherData.TempCelsius = &owmResp.Main.Temp + humidityFloat := float64(owmResp.Main.Humidity) weatherData.Humidity = &humidityFloat - weatherData.Description = ¤t.Weather[0].Description - weatherData.Icon = ¤t.Weather[0].Icon - weatherData.WindSpeed = ¤t.WindSpeed - if current.Rain != nil { - weatherData.RainVolume1h = ¤t.Rain.OneH + + if len(owmResp.Weather) > 0 { + weatherData.Description = &owmResp.Weather[0].Description + weatherData.Icon = &owmResp.Weather[0].Icon + } else { + f.logger.Warn("OpenWeatherMap Current response missing 'weather' description details", "lat", lat, "lon", lon) } - observedTime := time.Unix(current.Dt, 0).UTC() + + if owmResp.Wind != nil { + weatherData.WindSpeed = &owmResp.Wind.Speed + } else { + f.logger.Warn("OpenWeatherMap Current response missing 'wind' data block", "lat", lat, "lon", lon) + } + + if owmResp.Rain != nil { + weatherData.RainVolume1h = &owmResp.Rain.OneH + } + + observedTime := time.Unix(owmResp.Dt, 0).UTC() weatherData.ObservedAt = &observedTime now := time.Now().UTC() weatherData.WeatherLastUpdated = &now - f.logger.Debug("Successfully fetched weather data", + logTemp := "nil" + if weatherData.TempCelsius != nil { + logTemp = fmt.Sprintf("%.2f", *weatherData.TempCelsius) + } + logDesc := "nil" + if weatherData.Description != nil { + logDesc = *weatherData.Description + } + f.logger.Debug("Successfully fetched and mapped weather data", "lat", lat, "lon", lon, - "temp", *weatherData.TempCelsius, - "description", *weatherData.Description) + "temp", logTemp, + "description", logDesc) return weatherData, nil } diff --git a/backend/internal/workers/weather_updater.go b/backend/internal/workers/weather_updater.go index 1b48880..42d843e 100644 --- a/backend/internal/workers/weather_updater.go +++ b/backend/internal/workers/weather_updater.go @@ -3,6 +3,7 @@ package workers import ( "context" + "fmt" "log/slog" "sync" "time" @@ -27,13 +28,23 @@ func NewWeatherUpdater( eventPublisher domain.EventPublisher, logger *slog.Logger, fetchInterval time.Duration, -) *WeatherUpdater { +) (*WeatherUpdater, error) { if logger == nil { logger = slog.Default() } if fetchInterval <= 0 { - fetchInterval = 15 * time.Minute + fetchInterval = 60 * time.Minute } + if farmRepo == nil { + return nil, fmt.Errorf("farmRepo cannot be nil") + } + if weatherFetcher == nil { + return nil, fmt.Errorf("weatherFetcher cannot be nil") + } + if eventPublisher == nil { + return nil, fmt.Errorf("eventPublisher cannot be nil") + } + return &WeatherUpdater{ farmRepo: farmRepo, weatherFetcher: weatherFetcher, @@ -41,7 +52,7 @@ func NewWeatherUpdater( logger: logger, fetchInterval: fetchInterval, stopChan: make(chan struct{}), - } + }, nil } func (w *WeatherUpdater) Start(ctx context.Context) { @@ -75,20 +86,22 @@ func (w *WeatherUpdater) Start(ctx context.Context) { func (w *WeatherUpdater) Stop() { w.logger.Info("Attempting to stop Weather Updater worker...") - close(w.stopChan) - w.wg.Wait() + select { + case <-w.stopChan: + default: + close(w.stopChan) + } + w.wg.Wait() // Wait for the goroutine to finish w.logger.Info("Weather Updater worker stopped") } func (w *WeatherUpdater) fetchAndUpdateAllFarms(ctx context.Context) { - // Use a background context for the repository call if the main context might cancel prematurely - // repoCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // Example timeout - // defer cancel() + repoCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // Use separate context for DB query + defer cancel() - // TODO: Need a GetAllFarms method in the FarmRepository or a way to efficiently get all farm locations. - farms, err := w.farmRepo.GetByOwnerID(ctx, "") // !! REPLACE with a proper GetAll method !! + farms, err := w.farmRepo.GetAll(repoCtx) // <-- Changed method call if err != nil { - w.logger.Error("Failed to get farms for weather update", "error", err) + w.logger.Error("Failed to get all farms for weather update", "error", err) return } if len(farms) == 0 { @@ -96,12 +109,15 @@ func (w *WeatherUpdater) fetchAndUpdateAllFarms(ctx context.Context) { return } - w.logger.Info("Found farms for weather update", "count", len(farms)) + w.logger.Info("Processing farms for weather update", "count", len(farms)) var fetchWg sync.WaitGroup fetchCtx, cancelFetches := context.WithCancel(ctx) defer cancelFetches() + concurrencyLimit := 5 + sem := make(chan struct{}, concurrencyLimit) + for _, farm := range farms { if farm.Lat == 0 && farm.Lon == 0 { w.logger.Warn("Skipping farm with zero coordinates", "farm_id", farm.UUID, "farm_name", farm.Name) @@ -109,10 +125,14 @@ func (w *WeatherUpdater) fetchAndUpdateAllFarms(ctx context.Context) { } fetchWg.Add(1) + sem <- struct{}{} go func(f domain.Farm) { defer fetchWg.Done() + defer func() { <-sem }() + select { case <-fetchCtx.Done(): + w.logger.Info("Weather fetch cancelled for farm", "farm_id", f.UUID, "reason", fetchCtx.Err()) return default: w.fetchAndPublishWeather(fetchCtx, f) @@ -121,7 +141,7 @@ func (w *WeatherUpdater) fetchAndUpdateAllFarms(ctx context.Context) { } fetchWg.Wait() - w.logger.Info("Finished weather fetch cycle for farms", "count", len(farms)) + w.logger.Debug("Finished weather fetch cycle for farms", "count", len(farms)) // Use Debug for cycle completion } func (w *WeatherUpdater) fetchAndPublishWeather(ctx context.Context, farm domain.Farm) { @@ -136,17 +156,17 @@ func (w *WeatherUpdater) fetchAndPublishWeather(ctx context.Context, farm domain } payloadMap := map[string]interface{}{ - "farm_id": farm.UUID, - "lat": farm.Lat, - "lon": farm.Lon, - "temp_celsius": weatherData.TempCelsius, - "humidity": weatherData.Humidity, - "description": weatherData.Description, - "icon": weatherData.Icon, - "wind_speed": weatherData.WindSpeed, - "rain_volume_1h": weatherData.RainVolume1h, - "observed_at": weatherData.ObservedAt, - "weather_last_updated": weatherData.WeatherLastUpdated, + "farm_id": farm.UUID, + "lat": farm.Lat, + "lon": farm.Lon, + "tempCelsius": weatherData.TempCelsius, + "humidity": weatherData.Humidity, + "description": weatherData.Description, + "icon": weatherData.Icon, + "windSpeed": weatherData.WindSpeed, + "rainVolume1h": weatherData.RainVolume1h, + "observedAt": weatherData.ObservedAt, + "weatherLastUpdated": weatherData.WeatherLastUpdated, } event := domain.Event{ diff --git a/frontend/api/authentication.ts b/frontend/api/authentication.ts index 4ff06b4..b11ef74 100644 --- a/frontend/api/authentication.ts +++ b/frontend/api/authentication.ts @@ -17,8 +17,8 @@ export interface RegisterResponse { export async function registerUser(email: string, password: string): Promise { try { const response = await axiosInstance.post("/auth/register", { - Email: email, - Password: password, + email: email, + password: password, }); return response.data; } catch (error: any) { @@ -35,8 +35,8 @@ export async function registerUser(email: string, password: string): Promise { try { const response = await axiosInstance.post("/auth/login", { - Email: email, - Password: password, + email: email, + password: password, }); return response.data; } catch (error: any) { diff --git a/frontend/api/chat.ts b/frontend/api/chat.ts new file mode 100644 index 0000000..c7207a9 --- /dev/null +++ b/frontend/api/chat.ts @@ -0,0 +1,73 @@ +import axiosInstance from "./config"; + +interface HistoryItem { + role: "user" | "model" | "assistant"; + text: string; +} + +interface ChatResponse { + response: string; + // Include history if backend returns it, otherwise frontend manages it +} + +// Map frontend 'assistant' role to backend 'model' role if needed +const mapRoleForApi = (role: "user" | "assistant"): "user" | "model" => { + return role === "assistant" ? "model" : role; +}; + +/** + * Sends a chat message to the backend. + * Determines the endpoint based on the presence of farmId and cropId. + * + * @param message The user's message. + * @param history The conversation history. + * @param farmId Optional farm ID for context. + * @param cropId Optional crop ID for context. + * @returns The assistant's response. + */ +export async function sendChatMessage( + message: string, + history: HistoryItem[], + farmId?: string | null, + cropId?: string | null +): Promise { + const endpoint = farmId || cropId ? "/chat/specific" : "/chat"; // Use /chatbot if no IDs + const apiHistory = history.map((item) => ({ + role: mapRoleForApi(item.role as "user" | "assistant"), + text: item.text, + })); + + const payload: { + message: string; + farmId?: string; + cropId?: string; + history: { role: "user" | "model"; text: string }[]; + } = { + message, + history: apiHistory, + }; + + // Only include IDs if calling the contextual endpoint + if (farmId || cropId) { + if (farmId) payload.farmId = farmId; + if (cropId) payload.cropId = cropId; + } + + console.log(`Sending chat message to ${endpoint} with payload:`, payload); + + try { + const response = await axiosInstance.post(endpoint, payload); + console.log("Received chat response:", response.data); + return response.data; + } catch (error) { + console.error(`Error sending chat message to ${endpoint}:`, error); + // Provide a user-friendly error message + const errorMessage = + (error as any).response?.data?.message || + "Sorry, I couldn't connect to the assistant right now. Please try again later."; + // Throw an error with a useful message or return a specific error structure + // throw new Error(errorMessage); + // Or return an error response structure: + return { response: errorMessage }; + } +} diff --git a/frontend/api/crop.ts b/frontend/api/crop.ts index a8eafe8..35cb357 100644 --- a/frontend/api/crop.ts +++ b/frontend/api/crop.ts @@ -1,5 +1,5 @@ +// frontend/api/crop.ts import axiosInstance from "./config"; -// Use refactored types import type { Cropland, CropAnalytics } from "@/types"; export interface CropResponse { @@ -7,30 +7,72 @@ export interface CropResponse { } /** - * Fetch all Croplands for a specific FarmID. Returns CropResponse. + * Fetch all Croplands for a specific FarmID. */ export async function getCropsByFarmId(farmId: string): Promise { - // Assuming backend returns { "croplands": [...] } - return axiosInstance.get(`/crop/farm/${farmId}`).then((res) => res.data); + return axiosInstance.get<{ croplands: Cropland[] }>(`/crop/farm/${farmId}`).then((res) => res.data); } /** - * Fetch a specific Cropland by its ID. Returns Cropland. + * Fetch a specific Cropland by its ID. */ export async function getCropById(cropId: string): Promise { - // Assuming backend returns { "cropland": ... } - return axiosInstance.get(`/crop/${cropId}`).then((res) => res.data); - // If backend returns object directly: return axiosInstance.get(`/crop/${cropId}`).then((res) => res.data); + const response = await axiosInstance.get<{ cropland: Cropland }>(`/crop/${cropId}`); + return response.data.cropland; } /** - * Create a new crop (Cropland). Sends camelCase data matching backend tags. Returns Cropland. + * Create a new crop (Cropland). */ -export async function createCrop(data: Partial>): Promise { +export async function createCrop(data: { + name: string; + status: string; + priority?: number; + landSize?: number; + growthStage: string; + plantId: string; + farmId: string; + geoFeature?: unknown | null; +}): Promise { if (!data.farmId) { throw new Error("farmId is required to create a crop."); } - // Payload uses camelCase keys matching backend JSON tags + + const payload = { + name: data.name, + status: data.status, + priority: data.priority ?? 0, + landSize: data.landSize ?? 0, + growthStage: data.growthStage, + plantId: data.plantId, + farmId: data.farmId, + geoFeature: data.geoFeature, + }; + + const response = await axiosInstance.post<{ cropland: Cropland }>(`/crop`, payload); + return response.data.cropland; +} + +/** + * Update an existing cropland by its ID. + * Note: farmId cannot be changed via this endpoint + */ +export async function updateCrop( + cropId: string, + data: { + name: string; + status: string; + priority: number; + landSize: number; + growthStage: string; + plantId: string; + geoFeature: unknown | null; + } +): Promise { + if (!cropId) { + throw new Error("cropId is required to update a crop."); + } + const payload = { name: data.name, status: data.status, @@ -38,17 +80,36 @@ export async function createCrop(data: Partial(`/crop`, payload).then((res) => res.data.cropland); // Assuming backend wraps in { "cropland": ... } - // If backend returns object directly: return axiosInstance.post(`/crop`, payload).then((res) => res.data); + + const response = await axiosInstance.put<{ cropland: Cropland }>(`/crop/${cropId}`, payload); + return response.data.cropland; } /** - * Fetch analytics data for a specific crop by its ID. Returns CropAnalytics. + * Delete a specific cropland by its ID. */ -export async function fetchCropAnalytics(cropId: string): Promise { - // Assuming backend returns { body: { ... } } structure from Huma - return axiosInstance.get(`/analytics/crop/${cropId}`).then((res) => res.data); +export async function deleteCrop(cropId: string): Promise<{ message: string } | void> { + const response = await axiosInstance.delete(`/crop/${cropId}`); + if (response.status === 204) { + return; + } + return response.data as { message: string }; +} + +/** + * Fetch analytics data for a specific crop by its ID. + */ +export async function fetchCropAnalytics(cropId: string): Promise { + try { + const response = await axiosInstance.get(`/analytics/crop/${cropId}`); + return response.data; + } catch (error: any) { + console.error("Error fetching crop analytics:", error); + if (error.response?.status === 404) { + return null; + } + throw error; + } } diff --git a/frontend/api/profile.ts b/frontend/api/profile.ts new file mode 100644 index 0000000..adcce02 --- /dev/null +++ b/frontend/api/profile.ts @@ -0,0 +1,29 @@ +import axiosInstance from "./config"; +import type { User } from "@/types"; + +export interface UpdateUserProfileInput { + username?: string; + // email?: string; + // avatar?: string; +} + +/** + * Updates the current user's profile information. + * Sends a PUT request to the /user/me endpoint. + * @param data - An object containing the fields to update. + * @returns The updated user data from the backend. + */ +export async function updateUserProfile(data: UpdateUserProfileInput): Promise { + try { + // Backend expects { user: ... } in the response body + const response = await axiosInstance.put<{ user: User }>("/user/me", data); + return response.data.user; + } catch (error) { + console.error("Error updating user profile:", error); + throw new Error( + (error as any).response?.data?.detail || + (error as any).response?.data?.message || + "Failed to update profile. Please try again." + ); + } +} diff --git a/frontend/app/(sidebar)/chatbot/page.tsx b/frontend/app/(sidebar)/chatbot/page.tsx index a73b48f..900b2ba 100644 --- a/frontend/app/(sidebar)/chatbot/page.tsx +++ b/frontend/app/(sidebar)/chatbot/page.tsx @@ -2,204 +2,69 @@ import { useState, useRef, useEffect } from "react"; import { useRouter } from "next/navigation"; -import { - ChevronLeft, - Send, - Clock, - X, - Leaf, - MessageSquare, - History, - PanelRightClose, - PanelRightOpen, - Search, - Sparkles, -} from "lucide-react"; +import { Send, MessageSquare, Sparkles, Loader2, User, Bot } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ScrollArea } from "@/components/ui/scroll-area"; -import { Avatar } from "@/components/ui/avatar"; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { Badge } from "@/components/ui/badge"; -import { Card } from "@/components/ui/card"; -import { Separator } from "@/components/ui/separator"; -import type { Farm, Crop } from "@/types"; +import { Avatar, AvatarFallback } from "@/components/ui/avatar"; // Assuming Avatar is in ui folder +import { sendChatMessage } from "@/api/chat"; // Import the API function -// Mock data for farms and crops -const mockFarms: Farm[] = [ - { - id: "farm1", - name: "Green Valley Farm", - location: "California", - type: "Organic", - createdAt: new Date("2023-01-15"), - area: "120 acres", - crops: 8, - weather: { - temperature: 24, - humidity: 65, - rainfall: "2mm", - sunlight: 80, - }, - }, - { - id: "farm2", - name: "Sunrise Fields", - location: "Iowa", - type: "Conventional", - createdAt: new Date("2022-11-05"), - area: "350 acres", - crops: 5, - weather: { - temperature: 22, - humidity: 58, - rainfall: "0mm", - sunlight: 90, - }, - }, -]; - -const mockCrops: Crop[] = [ - { - id: "crop1", - farmId: "farm1", - name: "Organic Tomatoes", - plantedDate: new Date("2023-03-10"), - status: "Growing", - variety: "Roma", - area: "15 acres", - healthScore: 92, - progress: 65, - }, - { - id: "crop2", - farmId: "farm1", - name: "Sweet Corn", - plantedDate: new Date("2023-04-05"), - status: "Growing", - variety: "Golden Bantam", - area: "25 acres", - healthScore: 88, - progress: 45, - }, - { - id: "crop3", - farmId: "farm2", - name: "Soybeans", - plantedDate: new Date("2023-05-15"), - status: "Growing", - variety: "Pioneer", - area: "120 acres", - healthScore: 95, - progress: 30, - }, -]; - -// Mock chat history +// Interface for chat messages interface ChatMessage { id: string; + role: "user" | "assistant"; // Changed sender to role content: string; - sender: "user" | "bot"; timestamp: Date; - relatedTo?: { - type: "farm" | "crop"; - id: string; - name: string; - }; } -const mockChatHistory: ChatMessage[] = [ - { - id: "msg1", - content: "When should I harvest my tomatoes?", - sender: "user", - timestamp: new Date("2023-07-15T10:30:00"), - relatedTo: { - type: "crop", - id: "crop1", - name: "Organic Tomatoes", - }, - }, - { - id: "msg2", - content: - "Based on the current growth stage of your Roma tomatoes, they should be ready for harvest in approximately 2-3 weeks. The ideal time to harvest is when they've developed their full red color but are still firm to the touch. Keep monitoring the soil moisture levels as consistent watering during the final ripening stage is crucial for flavor development.", - sender: "bot", - timestamp: new Date("2023-07-15T10:30:30"), - }, - { - id: "msg3", - content: "What's the best fertilizer for corn?", - sender: "user", - timestamp: new Date("2023-07-16T14:22:00"), - relatedTo: { - type: "crop", - id: "crop2", - name: "Sweet Corn", - }, - }, - { - id: "msg4", - content: - "For your Sweet Corn at Green Valley Farm, I recommend a nitrogen-rich fertilizer with an NPK ratio of approximately 16-4-8. Corn is a heavy nitrogen feeder, especially during its growth phase. Apply the fertilizer when the plants are knee-high and again when they begin to tassel. Based on your soil analysis, consider supplementing with sulfur to address the slight deficiency detected in your last soil test.", - sender: "bot", - timestamp: new Date("2023-07-16T14:22:45"), - }, -]; - -// Recommended prompts +// Recommended prompts (keep or adjust as needed) const recommendedPrompts = [ { id: "prompt1", - text: "When should I water my crops?", - category: "Irrigation", + text: "What are common signs of nutrient deficiency in plants?", + category: "Plant Health", }, { id: "prompt2", - text: "How can I improve soil health?", + text: "How can I improve soil drainage?", category: "Soil Management", }, { id: "prompt3", - text: "What pests might affect my crops this season?", + text: "Explain integrated pest management (IPM).", category: "Pest Control", }, { id: "prompt4", - text: "Recommend a crop rotation plan", + text: "What are the benefits of crop rotation?", category: "Planning", }, { id: "prompt5", - text: "How to maximize yield for my current crops?", - category: "Optimization", + text: "Tell me about sustainable farming practices.", + category: "Sustainability", }, { id: "prompt6", - text: "What's the best time to harvest?", - category: "Harvesting", + text: "How does weather affect crop yield?", + category: "Weather", }, ]; -export default function ChatbotPage() { +export default function GeneralChatbotPage() { const [messages, setMessages] = useState([]); const [inputValue, setInputValue] = useState(""); - const [isHistoryOpen, setIsHistoryOpen] = useState(false); - const [selectedFarm, setSelectedFarm] = useState(null); - const [selectedCrop, setSelectedCrop] = useState(null); - const [isLoading, setIsLoading] = useState(false); + const [isLoading, setIsLoading] = useState(false); // Loading state for API call const messagesEndRef = useRef(null); - const router = useRouter(); // Initialize with a welcome message useEffect(() => { setMessages([ { - id: "welcome", + id: `assistant-${Date.now()}`, + role: "assistant", content: - "👋 Hello! I'm ForFarm Assistant, your farming AI companion. How can I help you today? You can ask me about crop management, pest control, weather impacts, or select a specific farm or crop to get tailored advice.", - sender: "bot", + "👋 Hello! I'm ForFarm Assistant, your general farming AI companion. Ask me anything about agriculture, crops, soil, weather, or best practices!", timestamp: new Date(), }, ]); @@ -210,483 +75,181 @@ export default function ChatbotPage() { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages]); - // Filter crops based on selected farm - const filteredCrops = selectedFarm ? mockCrops.filter((crop) => crop.farmId === selectedFarm) : mockCrops; - // Handle sending a message - const handleSendMessage = (content: string = inputValue) => { - if (!content.trim()) return; + const handleSendMessage = async (content: string = inputValue) => { + if (!content.trim() || isLoading) return; - // Create user message const userMessage: ChatMessage = { id: `user-${Date.now()}`, + role: "user", content, - sender: "user", timestamp: new Date(), - ...(selectedFarm || selectedCrop - ? { - relatedTo: { - type: selectedCrop ? "crop" : "farm", - id: selectedCrop || selectedFarm || "", - name: selectedCrop - ? mockCrops.find((c) => c.id === selectedCrop)?.name || "" - : mockFarms.find((f) => f.id === selectedFarm)?.name || "", - }, - } - : {}), }; setMessages((prev) => [...prev, userMessage]); setInputValue(""); setIsLoading(true); - // Simulate bot response after a delay - setTimeout(() => { - const botResponse: ChatMessage = { - id: `bot-${Date.now()}`, - content: generateBotResponse(content, selectedFarm, selectedCrop), - sender: "bot", + // Prepare history for the API call + const apiHistory = messages + .filter((msg) => msg.role === "user" || msg.role === "assistant") + .map((msg) => ({ role: msg.role, text: msg.content })); + + try { + // Call the API function *without* farmId and cropId + const response = await sendChatMessage(userMessage.content, apiHistory); + + const assistantMessage: ChatMessage = { + id: `assistant-${Date.now()}`, + role: "assistant", + content: response.response, timestamp: new Date(), }; - - setMessages((prev) => [...prev, botResponse]); + setMessages((prev) => [...prev, assistantMessage]); + } catch (error) { + console.error("Error sending general chat message:", error); + const errorMessage: ChatMessage = { + id: `error-${Date.now()}`, + role: "assistant", + content: `Sorry, I encountered an issue. ${(error as Error).message || "Please try again later."}`, + timestamp: new Date(), + }; + setMessages((prev) => [...prev, errorMessage]); + } finally { setIsLoading(false); - }, 1500); - }; - - // Generate a bot response based on the user's message and selected farm/crop - const generateBotResponse = (message: string, farmId: string | null, cropId: string | null): string => { - const lowerMessage = message.toLowerCase(); - - // Get farm and crop details if selected - const farm = farmId ? mockFarms.find((f) => f.id === farmId) : null; - const crop = cropId ? mockCrops.find((c) => c.id === cropId) : null; - - // Personalize response based on selected farm/crop - let contextPrefix = ""; - if (crop) { - contextPrefix = `For your ${crop.name} (${crop.variety}) at ${farm?.name || "your farm"}, `; - } else if (farm) { - contextPrefix = `For ${farm.name}, `; } - - // Generate response based on message content - if (lowerMessage.includes("water") || lowerMessage.includes("irrigation")) { - return `${contextPrefix}I recommend watering deeply but infrequently to encourage strong root growth. Based on the current weather conditions${ - farm ? ` in ${farm.location}` : "" - } (${farm?.weather?.rainfall || "minimal"} rainfall recently), you should water ${ - crop ? `your ${crop.name}` : "your crops" - } approximately 2-3 times per week, ensuring the soil remains moist but not waterlogged.`; - } else if (lowerMessage.includes("fertiliz") || lowerMessage.includes("nutrient")) { - return `${contextPrefix}a balanced NPK fertilizer with a ratio of 10-10-10 would be suitable for general application. ${ - crop - ? `For ${crop.name} specifically, consider increasing ${ - crop.name.toLowerCase().includes("tomato") - ? "potassium" - : crop.name.toLowerCase().includes("corn") - ? "nitrogen" - : "phosphorus" - } for optimal growth during the current ${ - crop.progress && crop.progress < 30 ? "early" : crop.progress && crop.progress < 70 ? "middle" : "late" - } growth stage.` - : "" - }`; - } else if (lowerMessage.includes("pest") || lowerMessage.includes("insect") || lowerMessage.includes("disease")) { - return `${contextPrefix}monitor for ${ - crop - ? crop.name.toLowerCase().includes("tomato") - ? "tomato hornworms, aphids, and early blight" - : crop.name.toLowerCase().includes("corn") - ? "corn borers, rootworms, and rust" - : "common agricultural pests" - : "common agricultural pests like aphids, beetles, and fungal diseases" - }. I recommend implementing integrated pest management (IPM) practices, including regular scouting, beneficial insects, and targeted treatments only when necessary.`; - } else if (lowerMessage.includes("harvest") || lowerMessage.includes("yield")) { - return `${contextPrefix}${ - crop - ? `your ${crop.name} should be ready to harvest in approximately ${Math.max( - 1, - Math.round((100 - (crop.progress || 50)) / 10) - )} weeks based on the current growth stage. Look for ${ - crop.name.toLowerCase().includes("tomato") - ? "firm, fully colored fruits" - : crop.name.toLowerCase().includes("corn") - ? "full ears with dried silk and plump kernels" - : "signs of maturity specific to this crop type" - }` - : "harvest timing depends on the specific crops you're growing, but generally you should look for visual cues of ripeness and maturity" - }.`; - } else if (lowerMessage.includes("soil") || lowerMessage.includes("compost")) { - return `${contextPrefix}improving soil health is crucial for sustainable farming. I recommend regular soil testing, adding organic matter through compost or cover crops, practicing crop rotation, and minimizing soil disturbance. ${ - farm - ? `Based on the soil type common in ${farm.location}, you might also consider adding ${ - farm.location.includes("California") ? "gypsum to improve drainage" : "lime to adjust pH levels" - }.` - : "" - }`; - } else if (lowerMessage.includes("weather") || lowerMessage.includes("forecast") || lowerMessage.includes("rain")) { - return `${contextPrefix}${ - farm - ? `the current conditions show temperature at ${farm.weather?.temperature}°C with ${farm.weather?.humidity}% humidity. There's been ${farm.weather?.rainfall} of rainfall recently, and sunlight levels are at ${farm.weather?.sunlight}% of optimal.` - : "I recommend checking your local agricultural weather service for the most accurate forecast for your specific location." - } ${ - crop - ? `For your ${crop.name}, ${ - farm?.weather?.rainfall === "0mm" - ? "the dry conditions mean you should increase irrigation" - : "the recent rainfall means you can reduce irrigation temporarily" - }.` - : "" - }`; - } else { - return `${contextPrefix}I understand you're asking about "${message}". To provide the most helpful advice, could you provide more specific details about your farming goals or challenges? I'm here to help with crop management, pest control, irrigation strategies, and more.`; - } - }; - - // Handle selecting a farm - const handleFarmSelect = (farmId: string) => { - setSelectedFarm(farmId); - setSelectedCrop(null); // Reset crop selection when farm changes - }; - - // Handle selecting a crop - const handleCropSelect = (cropId: string) => { - setSelectedCrop(cropId); }; // Handle clicking a recommended prompt const handlePromptClick = (promptText: string) => { setInputValue(promptText); - handleSendMessage(promptText); - }; - - // Handle loading a chat history item - const handleLoadChatHistory = (messageId: string) => { - // Find the message in history - const historyItem = mockChatHistory.find((msg) => msg.id === messageId); - if (!historyItem) return; - - // Set related farm/crop if available - if (historyItem.relatedTo) { - if (historyItem.relatedTo.type === "farm") { - setSelectedFarm(historyItem.relatedTo.id); - setSelectedCrop(null); - } else if (historyItem.relatedTo.type === "crop") { - const crop = mockCrops.find((c) => c.id === historyItem.relatedTo?.id); - if (crop) { - setSelectedFarm(crop.farmId); - setSelectedCrop(historyItem.relatedTo.id); - } - } - } - - // Load the conversation - const conversation = mockChatHistory.filter( - (msg) => - msg.id === messageId || - (msg.timestamp >= historyItem.timestamp && msg.timestamp <= new Date(historyItem.timestamp.getTime() + 60000)) - ); - - setMessages(conversation); - setIsHistoryOpen(false); + // Directly send message after setting input + // The handleSendMessage function will pick up the new inputValue + // No need to call handleSendMessage here if the button triggers submit or calls it + // Let's assume the button just sets the input and the user clicks send + // OR: uncomment the line below if the button should send immediately + // handleSendMessage(promptText); }; return ( -
- {/* Header */} -
-
-
- -
- -

ForFarm Assistant

-
-
- -
+
+ {/* Header (Optional - can be simplified as it's part of the main layout) */} +
+ +

General Farming Assistant

- {/* Main content */} -
- {/* Chat area */} -
- {/* Farm/Crop selector */} -
-
-
- - -
-
- - -
-
-
- - {/* Messages */} - -
- {messages.map((message) => ( -
-
- {message.relatedTo && ( -
- - {message.relatedTo.type === "farm" ? "🏡 " : "🌱 "} - {message.relatedTo.name} - -
- )} -
{message.content}
-
- {message.timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} -
-
-
- ))} - {isLoading && ( -
-
-
-
-
-
- - ForFarm Assistant is typing... - -
-
-
+ {/* Chat Area */} + +
+ {messages.map((message, i) => ( +
+ {message.role === "assistant" && ( + + + + + + )} +
+

{message.content}

+

+ {message.timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} +

+
+ {message.role === "user" && ( + + + + + )} -
- - - {/* Recommended prompts */} -
-

- - Recommended Questions -

-
- {recommendedPrompts.map((prompt) => ( - - ))} -
-
- - {/* Input area */} -
-
- setInputValue(e.target.value)} - placeholder="Ask about your farm or crops..." - className="flex-1" - onKeyDown={(e) => { - if (e.key === "Enter" && !e.shiftKey) { - e.preventDefault(); - handleSendMessage(); - } - }} - /> - -
-
-
- - {/* Chat history sidebar */} - {isHistoryOpen && ( -
-
-

- - Chat History -

- -
- -
-
- - + ))} + {isLoading && ( +
+ + + + + +
+
+
+
+
+ Assistant is thinking... +
+ )} +
+
+ - - - - Recent - - - By Farm - - - By Crop - - + {/* Recommended prompts */} +
+

+ + Try asking... +

+
+ {recommendedPrompts.slice(0, 5).map( + ( + prompt // Limit displayed prompts + ) => ( + + ) + )} +
+
- - -
- {mockChatHistory - .filter((msg) => msg.sender === "user") - .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()) - .map((message) => ( - handleLoadChatHistory(message.id)}> -
- -
- {message.relatedTo?.name.substring(0, 2) || "Me"} -
-
-
-
-

- {message.relatedTo ? message.relatedTo.name : "General Question"} -

-

- - {message.timestamp.toLocaleDateString()} -

-
-

- {message.content} -

-
-
-
- ))} -
-
- - -
- {mockFarms.map((farm) => ( -
-

{farm.name}

-
- {mockChatHistory - .filter( - (msg) => - msg.sender === "user" && msg.relatedTo?.type === "farm" && msg.relatedTo.id === farm.id - ) - .map((message) => ( - handleLoadChatHistory(message.id)}> -

{message.content}

-

- {message.timestamp.toLocaleDateString()} -

-
- ))} -
- -
- ))} -
-
- - -
- {mockCrops.map((crop) => ( -
-

- - {crop.name} - - ({mockFarms.find((f) => f.id === crop.farmId)?.name}) - -

-
- {mockChatHistory - .filter( - (msg) => - msg.sender === "user" && msg.relatedTo?.type === "crop" && msg.relatedTo.id === crop.id - ) - .map((message) => ( - handleLoadChatHistory(message.id)}> -

{message.content}

-

- {message.timestamp.toLocaleDateString()} -

-
- ))} -
- -
- ))} -
-
-
-
-
- )} + {/* Input area */} +
+
{ + e.preventDefault(); + handleSendMessage(); + }} + className="flex gap-2 max-w-4xl mx-auto"> + setInputValue(e.target.value)} + placeholder="Ask the farming assistant..." + className="flex-1 h-11" + disabled={isLoading} + onKeyDown={(e) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + handleSendMessage(); + } + }} + /> + +
); diff --git a/frontend/app/(sidebar)/farms/[farmId]/crop-dialog.tsx b/frontend/app/(sidebar)/farms/[farmId]/crop-dialog.tsx index bf1d5b6..2bf491c 100644 --- a/frontend/app/(sidebar)/farms/[farmId]/crop-dialog.tsx +++ b/frontend/app/(sidebar)/farms/[farmId]/crop-dialog.tsx @@ -36,16 +36,17 @@ import GoogleMapWithDrawing, { type ShapeData } from "@/components/google-map-wi interface CropDialogProps { open: boolean; onOpenChange: (open: boolean) => void; - onSubmit: (data: Partial) => Promise; + onSubmit: (data: Partial>) => Promise; isSubmitting: boolean; + initialData?: Cropland | null; + isEditing?: boolean; } -export function CropDialog({ open, onOpenChange, onSubmit, isSubmitting }: CropDialogProps) { +export function CropDialog({ open, onOpenChange, onSubmit, isSubmitting, initialData, isEditing }: CropDialogProps) { // --- State --- const [selectedPlantUUID, setSelectedPlantUUID] = useState(null); - // State to hold the structured GeoFeature data const [geoFeature, setGeoFeature] = useState(null); - const [calculatedArea, setCalculatedArea] = useState(null); // Keep for display + const [calculatedArea, setCalculatedArea] = useState(null); // --- Load Google Maps Geometry Library --- const geometryLib = useMapsLibrary("geometry"); @@ -63,6 +64,7 @@ export function CropDialog({ open, onOpenChange, onSubmit, isSubmitting }: CropD refetchOnWindowFocus: false, }); const plants = useMemo(() => plantData?.plants || [], [plantData]); + const selectedPlant = useMemo(() => { return plants.find((p) => p.uuid === selectedPlantUUID); }, [plants, selectedPlantUUID]); @@ -71,10 +73,14 @@ export function CropDialog({ open, onOpenChange, onSubmit, isSubmitting }: CropD useEffect(() => { if (!open) { setSelectedPlantUUID(null); - setGeoFeature(null); // Reset geoFeature state + setGeoFeature(null); setCalculatedArea(null); + } else if (initialData) { + setSelectedPlantUUID(initialData.plantId); + setGeoFeature(initialData.geoFeature ?? null); + setCalculatedArea(initialData.landSize ?? null); } - }, [open]); + }, [open, initialData]); // --- Map Interaction Handler --- const handleShapeDrawn = useCallback( @@ -169,9 +175,13 @@ export function CropDialog({ open, onOpenChange, onSubmit, isSubmitting }: CropD - Create New Cropland + + {isEditing ? "Edit Cropland" : "Create New Cropland"} + - Select a plant and draw the cropland boundary or mark its location on the map. + {isEditing + ? "Update the cropland details and location." + : "Select a plant and draw the cropland boundary or mark its location on the map."} diff --git a/frontend/app/(sidebar)/farms/[farmId]/crops/[cropId]/chatbot-dialog.tsx b/frontend/app/(sidebar)/farms/[farmId]/crops/[cropId]/chatbot-dialog.tsx index 72873b0..8b71474 100644 --- a/frontend/app/(sidebar)/farms/[farmId]/crops/[cropId]/chatbot-dialog.tsx +++ b/frontend/app/(sidebar)/farms/[farmId]/crops/[cropId]/chatbot-dialog.tsx @@ -1,16 +1,21 @@ "use client"; -import { useState } from "react"; +import { useState, useEffect, useRef } from "react"; import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; -import { Send } from "lucide-react"; +import { Send, Bot, Loader2, User } from "lucide-react"; import { VisuallyHidden } from "@radix-ui/react-visually-hidden"; +import { useParams } from "next/navigation"; +import { sendChatMessage } from "@/api/chat"; +import { Avatar, AvatarFallback } from "@/components/ui/avatar"; interface Message { + id: string; role: "user" | "assistant"; content: string; + timestamp: Date; } interface ChatbotDialogProps { @@ -20,52 +25,158 @@ interface ChatbotDialogProps { } export function ChatbotDialog({ open, onOpenChange, cropName }: ChatbotDialogProps) { - const [messages, setMessages] = useState([ - { - role: "assistant", - content: `Hello! I'm your farming assistant. How can I help you with your ${cropName} today?`, - }, - ]); + const params = useParams<{ farmId: string; cropId: string }>(); + const { farmId, cropId } = params; + + const [messages, setMessages] = useState([]); const [input, setInput] = useState(""); + const [isLoading, setIsLoading] = useState(false); // Loading state for API call + const messagesEndRef = useRef(null); - const handleSend = () => { - if (!input.trim()) return; + // Initialize with a welcome message when dialog opens + useEffect(() => { + if (open) { + setMessages([ + { + id: `assistant-${Date.now()}`, + role: "assistant", + content: `Hello! How can I help you with ${cropName} (Crop ID: ${cropId}) today?`, + timestamp: new Date(), + }, + ]); + // Reset input when opening + setInput(""); + setIsLoading(false); + } + }, [open, cropName, cropId]); // Add dependencies - const newMessages: Message[] = [ - ...messages, - { role: "user", content: input }, - { role: "assistant", content: `Here's some information about ${cropName}: [AI response placeholder]` }, - ]; - setMessages(newMessages); + // Scroll to bottom of messages + useEffect(() => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + }, [messages, isLoading]); // Add isLoading to scroll when loading appears/disappears + + const handleSend = async () => { + const messageText = input.trim(); + if (!messageText || isLoading) return; + + const userMessage: Message = { + id: `user-${Date.now()}`, + role: "user", + content: messageText, + timestamp: new Date(), + }; + + // Add user message immediately and clear input, set loading + setMessages((prev) => [...prev, userMessage]); setInput(""); + setIsLoading(true); // Show loading indicator *now* + + // Prepare history for API call (use messages *before* adding the placeholder) + const apiHistory = [...messages, userMessage] // Include the just-added user message + .map((msg) => ({ role: msg.role, text: msg.content })); + + try { + // Call the API function with context + const response = await sendChatMessage( + userMessage.content, + apiHistory, + farmId, // Pass farmId + cropId // Pass cropId + ); + + const assistantMessage: Message = { + id: `assistant-${Date.now()}`, + role: "assistant", + content: response.response, + timestamp: new Date(), + }; + // Replace loading state with the actual response + setMessages((prev) => [...prev, assistantMessage]); + } catch (error) { + console.error("Error sending chat message:", error); + const errorMessage: Message = { + id: `error-${Date.now()}`, + role: "assistant", + content: `Sorry, something went wrong. ${(error as Error).message || "Please try again."}`, + timestamp: new Date(), + }; + // Replace loading state with the error message + setMessages((prev) => [...prev, errorMessage]); + } finally { + setIsLoading(false); // Hide loading indicator + } }; return ( - Farming Assistant Chat + Farming Assistant Chat for {cropName}
-

Farming Assistant

-

Ask questions about your {cropName}

+

+ + Farming Assistant +

+

Ask about {cropName}

- {messages.map((message, i) => ( -
+ {messages.map( + ( + message // Render existing messages + ) => (
- {message.content} + key={message.id} + className={`flex items-start gap-3 ${message.role === "user" ? "justify-end" : ""}`}> + {message.role === "assistant" && ( + + + + + + )} +
+

{message.content}

+

+ {message.timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} +

+
+ {message.role === "user" && ( + + + + + + )} +
+ ) + )} + {/* Conditional Loading Indicator */} + {isLoading && ( +
+ + + + + +
+ + Assistant is thinking...
- ))} + )} +
@@ -76,9 +187,22 @@ export function ChatbotDialog({ open, onOpenChange, cropName }: ChatbotDialogPro handleSend(); }} className="flex gap-2"> - setInput(e.target.value)} /> -
diff --git a/frontend/app/(sidebar)/farms/[farmId]/crops/[cropId]/page.tsx b/frontend/app/(sidebar)/farms/[farmId]/crops/[cropId]/page.tsx index 461928b..92a75a9 100644 --- a/frontend/app/(sidebar)/farms/[farmId]/crops/[cropId]/page.tsx +++ b/frontend/app/(sidebar)/farms/[farmId]/crops/[cropId]/page.tsx @@ -2,7 +2,7 @@ import React, { useMemo, useState } from "react"; import { useRouter, useParams } from "next/navigation"; -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { ArrowLeft, LineChart, @@ -11,7 +11,6 @@ import { Sun, ThermometerSun, Timer, - ListCollapse, Leaf, CloudRain, Wind, @@ -22,6 +21,7 @@ import { LeafIcon, History, Bot, + MoreHorizontal, } from "lucide-react"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; @@ -35,16 +35,42 @@ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import type { Cropland, CropAnalytics, Farm } from "@/types"; import { getFarm } from "@/api/farm"; import { getPlants, PlantResponse } from "@/api/plant"; -import { getCropById, fetchCropAnalytics } from "@/api/crop"; +// Import the updated API functions +import { getCropById, fetchCropAnalytics, deleteCrop, updateCrop } from "@/api/crop"; import GoogleMapWithDrawing from "@/components/google-map-with-drawing"; +import { toast } from "sonner"; +import { CropDialog } from "../../crop-dialog"; // Assuming CropDialog is in the parent directory +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog"; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, +} from "@/components/ui/dropdown-menu"; + +// Define the expected shape of data coming from CropDialog for update +// Excludes fields not sent in the PUT request body (uuid, farmId, createdAt, updatedAt) +type CropUpdateData = Omit; export default function CropDetailPage() { const router = useRouter(); const params = useParams<{ farmId: string; cropId: string }>(); const { farmId, cropId } = params; + const queryClient = useQueryClient(); const [isChatOpen, setIsChatOpen] = useState(false); const [isAnalyticsOpen, setIsAnalyticsOpen] = useState(false); + const [isEditCropOpen, setIsEditCropOpen] = useState(false); + const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); // --- Fetch Farm Data --- const { data: farm, isLoading: isLoadingFarm } = useQuery({ @@ -64,7 +90,7 @@ export default function CropDetailPage() { queryKey: ["crop", cropId], queryFn: () => getCropById(cropId), enabled: !!cropId, - staleTime: 60 * 1000, + staleTime: 60 * 1000, // Refetch more often than farm/plants }); // --- Fetch All Plants Data --- @@ -76,7 +102,7 @@ export default function CropDetailPage() { } = useQuery({ queryKey: ["plants"], queryFn: getPlants, - staleTime: 1000 * 60 * 60, + staleTime: 1000 * 60 * 60, // Plants data is relatively static refetchOnWindowFocus: false, }); @@ -88,7 +114,7 @@ export default function CropDetailPage() { // --- Fetch Crop Analytics Data --- const { - data: analytics, // Type is CropAnalytics | null + data: analytics, isLoading: isLoadingAnalytics, isError: isErrorAnalytics, error: errorAnalytics, @@ -99,9 +125,66 @@ export default function CropDetailPage() { staleTime: 5 * 60 * 1000, }); + // --- Delete Crop Mutation --- + const deleteMutation = useMutation({ + mutationFn: () => deleteCrop(cropId), // Uses DELETE /crop/{cropId} + onSuccess: () => { + toast.success(`Crop "${cropland?.name}" deleted successfully.`); + queryClient.invalidateQueries({ queryKey: ["crops", farmId] }); + queryClient.invalidateQueries({ queryKey: ["farm", farmId] }); + queryClient.removeQueries({ queryKey: ["crop", cropId] }); + queryClient.removeQueries({ queryKey: ["cropAnalytics", cropId] }); + router.push(`/farms/${farmId}`); + }, + onError: (error) => { + console.error("Failed to delete crop:", error); + toast.error(`Failed to delete crop: ${(error as Error).message}`); + }, + onSettled: () => { + setIsDeleteDialogOpen(false); + }, + }); + + // --- Update Crop Mutation --- + // Updated to use the new updateCrop signature: updateCrop(cropId, payload) + const updateMutation = useMutation({ + // dataFromDialog should contain the fields needed for the PUT request body + mutationFn: async (dataFromDialog: CropUpdateData) => { + if (!cropId) { + throw new Error("Crop ID is missing for update."); + } + // Prepare the payload matching the UpdateCroplandInput body structure + // Ensure all required fields for the PUT endpoint are present + const updatePayload = { + name: dataFromDialog.name, + status: dataFromDialog.status, + priority: dataFromDialog.priority ?? 0, // Use default or ensure it comes from dialog + landSize: dataFromDialog.landSize ?? 0, // Use default or ensure it comes from dialog + growthStage: dataFromDialog.growthStage, + plantId: dataFromDialog.plantId, + geoFeature: dataFromDialog.geoFeature, + }; + // Call the API function with cropId and the prepared payload + return updateCrop(cropId, updatePayload); + }, + onSuccess: (updatedCrop) => { + toast.success(`Crop "${updatedCrop.name}" updated successfully.`); + // Invalidate queries to refetch data + queryClient.invalidateQueries({ queryKey: ["crop", cropId] }); + queryClient.invalidateQueries({ queryKey: ["crops", farmId] }); // Update list on farm page if name changed + queryClient.invalidateQueries({ queryKey: ["farm", farmId] }); // Update farm details if needed + queryClient.invalidateQueries({ queryKey: ["cropAnalytics", cropId] }); + setIsEditCropOpen(false); // Close the edit dialog + }, + onError: (error) => { + console.error("Failed to update crop:", error); + toast.error(`Failed to update crop: ${(error as Error).message}`); + }, + }); + // --- Combined Loading and Error States --- const isLoading = isLoadingFarm || isLoadingCropland || isLoadingPlants || isLoadingAnalytics; - const isError = isErrorCropland || isErrorPlants || isErrorAnalytics; // Prioritize crop/analytics errors + const isError = isErrorCropland || isErrorPlants || isErrorAnalytics; const error = errorCropland || errorPlants || errorAnalytics; // --- Loading State --- @@ -117,6 +200,9 @@ export default function CropDetailPage() { // --- Error State --- if (isError || !cropland) { console.error("Error loading crop details:", error); + const errorMessage = isErrorCropland + ? `Crop with ID ${cropId} not found or could not be loaded.` + : (error as Error)?.message || "An unexpected error occurred."; return (
); @@ -144,8 +226,11 @@ export default function CropDetailPage() { good: "text-green-500 bg-green-50 dark:bg-green-900 border-green-200", warning: "text-yellow-500 bg-yellow-50 dark:bg-yellow-900 border-yellow-200", critical: "text-red-500 bg-red-50 dark:bg-red-900 border-red-200", + unknown: "text-gray-500 bg-gray-50 dark:bg-gray-900 border-gray-200", // Added for safety }; - const healthStatus = analytics?.plantHealth || "good"; + // Use a safe default if analytics or plantHealth is missing + const healthStatus = (analytics?.plantHealth as keyof typeof healthColors) || "unknown"; + const healthColorClass = healthColors[healthStatus] || healthColors.unknown; const quickActions = [ { @@ -154,6 +239,7 @@ export default function CropDetailPage() { description: "View detailed growth analytics", onClick: () => setIsAnalyticsOpen(true), color: "bg-blue-50 dark:bg-blue-900 text-blue-600 dark:text-blue-300", + disabled: !analytics, // Disable if no analytics data }, { title: "Chat Assistant", @@ -162,35 +248,24 @@ export default function CropDetailPage() { onClick: () => setIsChatOpen(true), color: "bg-green-50 dark:bg-green-900 text-green-600 dark:text-green-300", }, - { - title: "Crop Details", - icon: ListCollapse, - description: "View detailed information", - onClick: () => console.log("Details clicked - Placeholder"), - color: "bg-purple-50 dark:bg-purple-900 text-purple-600 dark:text-purple-300", - }, - { - title: "Settings", - icon: Settings, - description: "Configure crop settings", - onClick: () => console.log("Settings clicked - Placeholder"), - color: "bg-gray-50 dark:bg-gray-900 text-gray-600 dark:text-gray-300", - }, + // Settings moved to dropdown ]; const plantedDate = cropland.createdAt ? new Date(cropland.createdAt) : null; - const daysToMaturity = plant?.daysToMaturity; // Use camelCase + const daysToMaturity = plant?.daysToMaturity; const expectedHarvestDate = - plantedDate && daysToMaturity ? new Date(plantedDate.getTime() + daysToMaturity * 24 * 60 * 60 * 1000) : null; + plantedDate && typeof daysToMaturity === "number" + ? new Date(plantedDate.getTime() + daysToMaturity * 24 * 60 * 60 * 1000) + : null; - const growthProgress = analytics?.growthProgress ?? 0; // Get from analytics - const displayArea = typeof cropland.landSize === "number" ? `${cropland.landSize} ha` : "N/A"; // Use camelCase + const growthProgress = analytics?.growthProgress ?? 0; + const displayArea = typeof cropland.landSize === "number" ? `${cropland.landSize.toFixed(2)} ha` : "N/A"; return (
{/* Breadcrumbs */} -
-

{cropland.name}

{/* Use camelCase */} +

{cropland.name}

- {plant?.variety || "Unknown Variety"} • {displayArea} {/* Use camelCase */} + {plant?.variety || "Unknown Variety"} • {displayArea}

- - {cropland.status} {/* Use camelCase */} + + {cropland.status}
{expectedHarvestDate ? ( @@ -260,23 +357,28 @@ export default function CropDetailPage() { {/* Left Column */}
{/* Quick Actions */} -
+
{quickActions.map((action) => ( ))} @@ -286,51 +388,70 @@ export default function CropDetailPage() { Environmental Conditions - Real-time monitoring data + Real-time monitoring data (if available)
{[ + // ... (metric definitions remain the same) { icon: ThermometerSun, label: "Temperature", - value: analytics?.temperature ? `${analytics.temperature}°C` : "N/A", + value: + analytics?.temperature !== null && analytics?.temperature !== undefined + ? `${analytics.temperature.toFixed(1)}°C` + : "N/A", color: "text-orange-500 dark:text-orange-300", bg: "bg-orange-50 dark:bg-orange-900", }, { icon: Droplets, label: "Humidity", - value: analytics?.humidity ? `${analytics.humidity}%` : "N/A", + value: + analytics?.humidity !== null && analytics?.humidity !== undefined + ? `${analytics.humidity.toFixed(0)}%` + : "N/A", color: "text-blue-500 dark:text-blue-300", bg: "bg-blue-50 dark:bg-blue-900", }, { icon: Sun, label: "Sunlight", - value: analytics?.sunlight ? `${analytics.sunlight}%` : "N/A", + value: + analytics?.sunlight !== null && analytics?.sunlight !== undefined + ? `${analytics.sunlight.toFixed(0)}%` + : "N/A", color: "text-yellow-500 dark:text-yellow-300", bg: "bg-yellow-50 dark:bg-yellow-900", }, { icon: Leaf, label: "Soil Moisture", - value: analytics?.soilMoisture ? `${analytics.soilMoisture}%` : "N/A", + value: + analytics?.soilMoisture !== null && analytics?.soilMoisture !== undefined + ? `${analytics.soilMoisture.toFixed(0)}%` + : "N/A", color: "text-green-500 dark:text-green-300", bg: "bg-green-50 dark:bg-green-900", }, { icon: Wind, label: "Wind Speed", - value: analytics?.windSpeed ?? "N/A", + value: + analytics?.windSpeed !== null && analytics?.windSpeed !== undefined + ? `${analytics.windSpeed.toFixed(1)} m/s` + : "N/A", color: "text-gray-500 dark:text-gray-300", bg: "bg-gray-50 dark:bg-gray-900", }, { icon: CloudRain, - label: "Rainfall", - value: analytics?.rainfall ?? "N/A", + label: "Rainfall (1h)", + value: + analytics?.rainfall !== null && analytics?.rainfall !== undefined + ? `${analytics.rainfall.toFixed(1)} mm` + : "N/A", color: "text-indigo-500 dark:text-indigo-300", bg: "bg-indigo-50 dark:bg-indigo-900", }, @@ -350,42 +471,50 @@ export default function CropDetailPage() { ))}
- - {/* Growth Progress */} -
-
- Growth Progress - {growthProgress}% -
- -

- Based on {daysToMaturity ? `${daysToMaturity} days` : "N/A"} to maturity. -

-
- {/* Next Action Card */} - - -
-
- -
-
-

Next Action Required

-

- {analytics?.nextAction || "Check crop status"} -

- {analytics?.nextActionDue && ( -

- Due by {new Date(analytics.nextActionDue).toLocaleDateString()} -

- )} - {!analytics?.nextAction && ( -

No immediate actions required.

- )} + {/* Show message if no analytics at all */} + {!analytics && !isLoadingAnalytics && ( +

Environmental data not available.

+ )} + {analytics && ( + <> + + {/* Growth Progress */} +
+
+ Growth Progress + {growthProgress}%
+ +

+ Based on {daysToMaturity ? `${daysToMaturity} days` : "N/A"} to maturity. +

- - + {/* Next Action Card */} + + +
+
+ +
+
+

Next Action Required

+

+ {analytics?.nextAction || "Check crop status"} +

+ {analytics?.nextActionDue && ( +

+ Due by {new Date(analytics.nextActionDue).toLocaleDateString()} +

+ )} + {!analytics?.nextAction && ( +

No immediate actions required.

+ )} +
+
+
+
+ + )}
@@ -397,11 +526,11 @@ export default function CropDetailPage() { Visual representation on the farm - {/* TODO: Ensure GoogleMapWithDrawing correctly parses and displays GeoFeatureData */} @@ -420,37 +549,39 @@ export default function CropDetailPage() {
- {[ - { - name: "Nitrogen (N)", - value: analytics?.nutrientLevels?.nitrogen, - color: "bg-blue-500 dark:bg-blue-700", - }, - { - name: "Phosphorus (P)", - value: analytics?.nutrientLevels?.phosphorus, - color: "bg-yellow-500 dark:bg-yellow-700", - }, - { - name: "Potassium (K)", - value: analytics?.nutrientLevels?.potassium, - color: "bg-green-500 dark:bg-green-700", - }, - ].map((nutrient) => ( -
-
- {nutrient.name} - {nutrient.value ?? "N/A"}% + {/* Check if analytics and nutrientLevels exist before mapping */} + {analytics?.nutrientLevels ? ( + [ + { + name: "Nitrogen (N)", + value: analytics.nutrientLevels.nitrogen, + color: "bg-blue-500 dark:bg-blue-700", + }, + { + name: "Phosphorus (P)", + value: analytics.nutrientLevels.phosphorus, + color: "bg-yellow-500 dark:bg-yellow-700", + }, + { + name: "Potassium (K)", + value: analytics.nutrientLevels.potassium, + color: "bg-green-500 dark:bg-green-700", + }, + ].map((nutrient) => ( +
+
+ {nutrient.name} + {nutrient.value ?? "N/A"}% +
+
- -
- ))} - {!analytics?.nutrientLevels && ( + )) + ) : (

Nutrient data not available.

)}
@@ -467,6 +598,7 @@ export default function CropDetailPage() { + {/* Placeholder - Replace with actual activity log */}
No recent activity logged.
@@ -476,28 +608,52 @@ export default function CropDetailPage() { {/* Dialogs */} - {/* Ensure AnalyticsDialog uses the correct props */} + + {/* Conditionally render AnalyticsDialog only if analytics data exists */} {analytics && ( )} + + {/* Edit Crop Dialog */} + { + // 'data' from the dialog should match CropUpdateData structure + await updateMutation.mutateAsync(data as CropUpdateData); + }} + isSubmitting={updateMutation.isPending} + isEditing={true} // Indicate that this is for editing + /> + + {/* Delete Confirmation Dialog */} + + + + Are you absolutely sure? + + This action cannot be undone. This will permanently delete the crop "{cropland.name}" and all + associated data. + + + + Cancel + deleteMutation.mutate()} + disabled={deleteMutation.isPending} + className="bg-destructive text-destructive-foreground hover:bg-destructive/90"> + {deleteMutation.isPending && } + Delete Crop + + + +
); diff --git a/frontend/app/(sidebar)/farms/edit-farm-form.tsx b/frontend/app/(sidebar)/farms/edit-farm-form.tsx new file mode 100644 index 0000000..99ebd15 --- /dev/null +++ b/frontend/app/(sidebar)/farms/edit-farm-form.tsx @@ -0,0 +1,242 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import * as z from "zod"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { useCallback, useEffect } from "react"; // Added useEffect +import { Loader2 } from "lucide-react"; +import type { Farm } from "@/types"; +import GoogleMapWithDrawing, { type ShapeData } from "@/components/google-map-with-drawing"; + +// Schema for editing - make fields optional if needed, but usually same as create +const farmFormSchema = z.object({ + name: z.string().min(2, "Farm name must be at least 2 characters"), + latitude: z + .number({ invalid_type_error: "Latitude must be a number" }) + .min(-90, "Invalid latitude") + .max(90, "Invalid latitude") + .refine((val) => val !== 0, { message: "Please select a location on the map." }), + longitude: z + .number({ invalid_type_error: "Longitude must be a number" }) + .min(-180, "Invalid longitude") + .max(180, "Invalid longitude") + .refine((val) => val !== 0, { message: "Please select a location on the map." }), + type: z.string().min(1, "Please select a farm type"), + area: z.string().optional(), +}); + +export interface EditFarmFormProps { + initialData: Farm; // Require initial data for editing + onSubmit: (data: Partial>) => Promise; // Exclude non-editable fields + onCancel: () => void; + isSubmitting: boolean; +} + +export function EditFarmForm({ initialData, onSubmit, onCancel, isSubmitting }: EditFarmFormProps) { + const form = useForm>({ + resolver: zodResolver(farmFormSchema), + // Set default values from initialData + defaultValues: { + name: initialData.name || "", + latitude: initialData.lat || 0, + longitude: initialData.lon || 0, + type: initialData.farmType || "", + area: initialData.totalSize || "", + }, + }); + + // Update form if initialData changes (e.g., opening dialog for different farms) + useEffect(() => { + form.reset({ + name: initialData.name || "", + latitude: initialData.lat || 0, + longitude: initialData.lon || 0, + type: initialData.farmType || "", + area: initialData.totalSize || "", + }); + }, [initialData, form.reset]); + + const handleSubmit = async (values: z.infer) => { + try { + // Shape data for the API update function + const farmUpdateData: Partial> = { + name: values.name, + lat: values.latitude, + lon: values.longitude, + farmType: values.type, + totalSize: values.area, + }; + await onSubmit(farmUpdateData); + // No need to reset form here, dialog closing handles it or parent component does + } catch (error) { + console.error("Error submitting edit form:", error); + // Error handled by mutation's onError + } + }; + + // Map handler - same as AddFarmForm + const handleShapeDrawn = useCallback( + (data: ShapeData) => { + if (data.type === "marker") { + const { lat, lng } = data.position; + form.setValue("latitude", lat, { shouldValidate: true }); + form.setValue("longitude", lng, { shouldValidate: true }); + } else { + console.log(`Shape type '${data.type}' ignored for coordinate update.`); + } + }, + [form] + ); + + return ( +
+ {/* Form Section */} +
+
+ + {/* Fields: Name, Lat/Lon, Type, Area - same structure as AddFarmForm */} + {/* Farm Name Field */} + ( + + Farm Name + + + + This is your farm's display name. + + + )} + /> + + {/* Coordinate Fields (Latitude & Longitude) */} +
+ ( + + Latitude + + + + + + )} + /> + ( + + Longitude + + + + + + )} + /> +
+ + {/* Farm Type Selection */} + ( + + Farm Type + + + + )} + /> + + {/* Total Area Field */} + ( + + Total Area (optional) + + + + The total size of your farm (e.g., "15 rai", "10 hectares"). + + + )} + /> + + {/* Submit and Cancel Buttons */} +
+ + +
+ + +
+ {/* Map Section */} +
+ Farm Location (Update marker if needed) +
+ +
+ + Click the marker tool and place a new marker to update coordinates. + +
+
+ ); +} diff --git a/frontend/app/(sidebar)/farms/farm-card.tsx b/frontend/app/(sidebar)/farms/farm-card.tsx index 00090ae..4d0a870 100644 --- a/frontend/app/(sidebar)/farms/farm-card.tsx +++ b/frontend/app/(sidebar)/farms/farm-card.tsx @@ -1,19 +1,28 @@ "use client"; import { Card, CardContent, CardHeader, CardFooter } from "@/components/ui/card"; -import { MapPin, Sprout, Plus, CalendarDays, ArrowRight } from "lucide-react"; +import { MapPin, Sprout, Plus, ArrowRight, MoreVertical, Edit, Trash2 } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import type { Farm } from "@/types"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; export interface FarmCardProps { variant: "farm" | "add"; farm?: Farm; // Use updated Farm type onClick?: () => void; + onEditClick?: (e: React.MouseEvent) => void; // Callback for edit + onDeleteClick?: (e: React.MouseEvent) => void; // Callback for delete } -export function FarmCard({ variant, farm, onClick }: FarmCardProps) { +export function FarmCard({ variant, farm, onClick, onEditClick, onDeleteClick }: FarmCardProps) { const cardClasses = cn( "w-full h-full overflow-hidden transition-all duration-200 hover:shadow-lg border", variant === "add" @@ -21,6 +30,10 @@ export function FarmCard({ variant, farm, onClick }: FarmCardProps) { : "bg-white dark:bg-slate-800 hover:bg-muted/10 dark:hover:bg-slate-700 border-muted/60" ); + // Stop propagation for dropdown menu trigger and items + const stopPropagation = (e: React.MouseEvent) => { + e.stopPropagation(); + }; if (variant === "add") { return ( @@ -43,49 +56,81 @@ export function FarmCard({ variant, farm, onClick }: FarmCardProps) { }).format(new Date(farm.createdAt)); return ( - + -
+
+ className="capitalize bg-green-50 dark:bg-green-900 text-green-700 dark:text-green-300 border-green-200 flex-shrink-0"> {farm.farmType} -
- - {formattedDate} -
+ {/* Actions Dropdown */} + + + + + + + + Edit Farm + + + + + Delete Farm + + +
- -
-
- -
-
-

{farm.name}

-
- - {farm.lat} + {/* Use div for clickable area if needed, or rely on button */} +
+ +
+
+
-
-
-

Area

-

{farm.totalSize}

+ {/* Ensure text truncates */} +
+

+ {farm.name} +

+
+ + {/* Display truncated location or just Lat/Lon */} + + Lat: {farm.lat.toFixed(3)}, Lon: {farm.lon.toFixed(3)} +
-
-

Crops

-

{farm.crops ? farm.crops.length : 0}

+
+
+

Area

+

+ {farm.totalSize || "N/A"} +

+
+
+

Crops

+

{farm.crops ? farm.crops.length : 0}

+
-
- - + +
+ + {" "} + {/* Keep footer outside clickable area */} diff --git a/frontend/app/(sidebar)/farms/page.tsx b/frontend/app/(sidebar)/farms/page.tsx index cef3fe3..8b70e1e 100644 --- a/frontend/app/(sidebar)/farms/page.tsx +++ b/frontend/app/(sidebar)/farms/page.tsx @@ -20,11 +20,25 @@ import { } from "@/components/ui/dropdown-menu"; import { Badge } from "@/components/ui/badge"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog"; import { FarmCard } from "./farm-card"; import { AddFarmForm } from "./add-farm-form"; +import { EditFarmForm } from "./edit-farm-form"; import type { Farm } from "@/types"; -import { fetchFarms, createFarm } from "@/api/farm"; +import { fetchFarms, createFarm, updateFarm, deleteFarm } from "@/api/farm"; +import { toast } from "sonner"; +import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card"; +import { Skeleton } from "@/components/ui/skeleton"; export default function FarmSetupPage() { const router = useRouter(); @@ -33,27 +47,68 @@ export default function FarmSetupPage() { const [searchQuery, setSearchQuery] = useState(""); const [activeFilter, setActiveFilter] = useState("all"); const [sortOrder, setSortOrder] = useState<"newest" | "oldest" | "alphabetical">("newest"); - const [isDialogOpen, setIsDialogOpen] = useState(false); + const [isAddDialogOpen, setIsAddDialogOpen] = useState(false); + const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); // State for edit dialog + const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); // State for delete dialog + const [selectedFarm, setSelectedFarm] = useState(null); // Farm to edit/delete + // --- Fetch Farms --- const { - data: farms, // Type is Farm[] now + data: farms, isLoading, isError, error, } = useQuery({ - // Use Farm[] type queryKey: ["farms"], queryFn: fetchFarms, staleTime: 60 * 1000, }); - const mutation = useMutation({ - // Pass the correct type to createFarm + // --- Create Farm Mutation --- + const createMutation = useMutation({ mutationFn: (data: Partial>) => createFarm(data), - onSuccess: () => { + onSuccess: (newFarm) => { queryClient.invalidateQueries({ queryKey: ["farms"] }); - setIsDialogOpen(false); + setIsAddDialogOpen(false); + toast.success(`Farm "${newFarm.name}" created successfully!`); + }, + onError: (error) => { + toast.error(`Failed to create farm: ${(error as Error).message}`); + }, + }); + + // --- Update Farm Mutation --- + const updateMutation = useMutation({ + mutationFn: (data: { + farmId: string; + payload: Partial>; + }) => updateFarm(data.farmId, data.payload), + onSuccess: (updatedFarm) => { + queryClient.invalidateQueries({ queryKey: ["farms"] }); + setIsEditDialogOpen(false); + setSelectedFarm(null); + toast.success(`Farm "${updatedFarm.name}" updated successfully!`); + }, + onError: (error) => { + toast.error(`Failed to update farm: ${(error as Error).message}`); + }, + }); + + // --- Delete Farm Mutation --- + const deleteMutation = useMutation({ + mutationFn: (farmId: string) => deleteFarm(farmId), + onSuccess: (_, farmId) => { + // Second arg is the variable passed to mutate + queryClient.invalidateQueries({ queryKey: ["farms"] }); + // Optionally remove specific farm query if cached elsewhere: queryClient.removeQueries({ queryKey: ["farm", farmId] }); + setIsDeleteDialogOpen(false); + setSelectedFarm(null); + toast.success(`Farm deleted successfully.`); + }, + onError: (error) => { + toast.error(`Failed to delete farm: ${(error as Error).message}`); + setIsDeleteDialogOpen(false); // Close dialog even on error }, }); @@ -69,6 +124,35 @@ export default function FarmSetupPage() { // UpdatedAt: string; // } + const handleAddFarmSubmit = async (data: Partial) => { + await createMutation.mutateAsync(data); + }; + + const handleEditFarmSubmit = async ( + data: Partial> + ) => { + if (!selectedFarm) return; + await updateMutation.mutateAsync({ farmId: selectedFarm.uuid, payload: data }); + }; + + const openEditDialog = (farm: Farm, e: React.MouseEvent) => { + e.stopPropagation(); // Prevent card click + setSelectedFarm(farm); + setIsEditDialogOpen(true); + }; + + const openDeleteDialog = (farm: Farm, e: React.MouseEvent) => { + e.stopPropagation(); // Prevent card click + setSelectedFarm(farm); + setIsDeleteDialogOpen(true); + }; + + const confirmDelete = () => { + if (!selectedFarm) return; + deleteMutation.mutate(selectedFarm.uuid); + }; + + // --- Filtering and Sorting Logic --- const filteredAndSortedFarms = (farms || []) .filter( (farm) => @@ -90,10 +174,6 @@ export default function FarmSetupPage() { // Get distinct farm types. const farmTypes = ["all", ...new Set((farms || []).map((farm) => farm.farmType))]; // Use camelCase farmType - const handleAddFarm = async (data: Partial) => { - await mutation.mutateAsync(data); - }; - return (
@@ -114,7 +194,7 @@ export default function FarmSetupPage() { onChange={(e) => setSearchQuery(e.target.value)} />
- @@ -128,8 +208,9 @@ export default function FarmSetupPage() { setActiveFilter(type)}> {type === "all" ? "All Farms" : type} @@ -148,25 +229,25 @@ export default function FarmSetupPage() { Sort by setSortOrder("newest")}> Newest first - {sortOrder === "newest" && } + {sortOrder === "newest" && } setSortOrder("oldest")}> Oldest first - {sortOrder === "oldest" && } + {sortOrder === "oldest" && } setSortOrder("alphabetical")}> Alphabetical - {sortOrder === "alphabetical" && } + {sortOrder === "alphabetical" && } @@ -178,21 +259,40 @@ export default function FarmSetupPage() { {isError && ( - Error + Error Loading Farms {(error as Error)?.message} )} {/* Loading state */} {isLoading && ( -
- -

Loading your farms...

+
+ {[...Array(4)].map( + ( + _, + i // Render skeleton cards + ) => ( + + + + + + + + + + + + + + ) + )}
)} {/* Empty state */} {!isLoading && !isError && filteredAndSortedFarms.length === 0 && ( + // ... (Empty state remains the same) ...
@@ -204,7 +304,7 @@ export default function FarmSetupPage() {

) : (

- You haven't added any farms yet. Get started by adding your first farm. + You haven't added any farms yet. Get started by adding your first farm.

)}
); } diff --git a/frontend/app/(sidebar)/layout.tsx b/frontend/app/(sidebar)/layout.tsx index e097aaf..ad8999c 100644 --- a/frontend/app/(sidebar)/layout.tsx +++ b/frontend/app/(sidebar)/layout.tsx @@ -4,9 +4,6 @@ import { AppSidebar } from "@/components/sidebar/app-sidebar"; import { ThemeToggle } from "@/components/theme-toggle"; import { Separator } from "@/components/ui/separator"; import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"; -import DynamicBreadcrumb from "./dynamic-breadcrumb"; -import { extractRoute } from "@/lib/utils"; -import { usePathname } from "next/navigation"; import { Toaster } from "@/components/ui/sonner"; import { useForm, FormProvider } from "react-hook-form"; import { APIProvider } from "@vis.gl/react-google-maps"; @@ -16,8 +13,7 @@ export default function AppLayout({ }: Readonly<{ children: React.ReactNode; }>) { - const pathname = usePathname(); - const currentPathname = extractRoute(pathname); + // const pathname = usePathname(); const form = useForm(); return ( @@ -31,7 +27,7 @@ export default function AppLayout({ - + {/* */}
{children} diff --git a/frontend/app/(sidebar)/profile/page.tsx b/frontend/app/(sidebar)/profile/page.tsx new file mode 100644 index 0000000..4300776 --- /dev/null +++ b/frontend/app/(sidebar)/profile/page.tsx @@ -0,0 +1,269 @@ +// frontend/app/(sidebar)/profile/page.tsx +"use client"; + +import React, { useState, useEffect } from "react"; +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import * as z from "zod"; +import { toast } from "sonner"; +import { Loader2, User as UserIcon, Mail, Save, X, Edit, Camera } from "lucide-react"; + +import { fetchUserMe, UserDataOutput } from "@/api/user"; // Fetch function +import { updateUserProfile, UpdateUserProfileInput } from "@/api/profile"; // Update function +import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Button } from "@/components/ui/button"; +import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form"; +import { Separator } from "@/components/ui/separator"; +import { Skeleton } from "@/components/ui/skeleton"; // For loading state + +// Schema for editable fields +const profileSchema = z.object({ + username: z + .string() + .min(3, "Username must be at least 3 characters") + .max(30, "Username cannot exceed 30 characters") + .optional() // Make it optional if user doesn't have one initially + .or(z.literal("")), // Allow empty string +}); + +type ProfileFormData = z.infer; + +export default function ProfilePage() { + const queryClient = useQueryClient(); + const [isEditing, setIsEditing] = useState(false); + + // Fetch current user data + const { + data: userData, + isLoading, + isError, + error, + } = useQuery({ + queryKey: ["userMe"], + queryFn: fetchUserMe, + staleTime: 5 * 60 * 1000, // Cache for 5 minutes + }); + + const user = userData?.user; + + // Setup react-hook-form + const form = useForm({ + resolver: zodResolver(profileSchema), + defaultValues: { + username: "", + }, + }); + + // Populate form when user data loads or edit mode changes + useEffect(() => { + if (user) { + form.reset({ + username: user.username || "", + }); + } + }, [user, isEditing, form.reset]); + + // Mutation for updating profile + const mutation = useMutation({ + mutationFn: updateUserProfile, + onSuccess: (updatedUser) => { + toast.success("Profile updated successfully!"); + // Update the cache with the new user data + queryClient.setQueryData(["userMe"], { user: updatedUser }); + setIsEditing(false); // Exit edit mode + }, + onError: (error) => { + toast.error(`Failed to update profile: ${error.message}`); + }, + }); + + const handleEditToggle = () => { + if (isEditing) { + // Reset form to original values if canceling edit + form.reset({ username: user?.username || "" }); + } + setIsEditing(!isEditing); + }; + + const onSubmit = (formData: ProfileFormData) => { + const updatePayload: UpdateUserProfileInput = {}; + // Only include username if it actually changed + if (formData.username !== undefined && formData.username !== (user?.username || "")) { + // Allow setting to empty string if desired, or add validation to prevent it + updatePayload.username = formData.username; + } + + if (Object.keys(updatePayload).length > 0) { + mutation.mutate(updatePayload); + } else { + // No changes were made + setIsEditing(false); // Just exit edit mode + } + }; + + // --- Render Logic --- + + if (isLoading) { + return ( +
+ + + + + + +
+ +
+ + +
+
+ + +
+
+
+ ); + } + + if (isError) { + return
Error loading profile: {(error as Error)?.message}
; + } + + if (!user) { + return
User data not found.
; + } + + return ( +
+

User Profile

+ + +
+
+ Account Information + View and manage your personal details. +
+ +
+
+ +
+ +
+ {/* Avatar Section (Placeholder for upload) */} +
+ + + + {user.username ? user.username.charAt(0).toUpperCase() : user.email.charAt(0).toUpperCase()} + + + +
+ +
+ {/* Username Field */} + ( + + + + + + + + )} + /> + + {/* Email Field (Read-only) */} +
+ + +

Email cannot be changed currently.

+
+ + {/* User ID (Read-only) */} +
+ + +
+
+
+ + {/* Save Button (Visible only in edit mode) */} + {isEditing && ( + <> + +
+ +
+ + )} + + +
+
+
+ ); +} diff --git a/frontend/app/(sidebar)/settings/page.tsx b/frontend/app/(sidebar)/settings/page.tsx new file mode 100644 index 0000000..f4f4e78 --- /dev/null +++ b/frontend/app/(sidebar)/settings/page.tsx @@ -0,0 +1,94 @@ +"use client"; + +import React from "react"; +import { useTheme } from "next-themes"; +import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "@/components/ui/card"; +import { Label } from "@/components/ui/label"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { Separator } from "@/components/ui/separator"; +import { Button } from "@/components/ui/button"; +import { Paintbrush, User, Trash2, ExternalLink } from "lucide-react"; +import Link from "next/link"; +import { toast } from "sonner"; + +export default function SettingsPage() { + const { theme, setTheme } = useTheme(); + + const handleDeleteAccount = () => { + toast.warning("Account deletion is not yet implemented.", { + description: "This feature will be available in a future update.", + action: { label: "Close", onClick: () => toast.dismiss() }, + }); + }; + + return ( +
+

Settings

+ + {/* Appearance Settings */} + + + + Appearance + + Customize the look and feel of the application. + + +
+ + +
+ {/* Add other appearance settings here if needed */} +
+
+ + {/* Account Settings */} + + + + Account + + Manage your account details and security. + + + + + + + + + +
+

Danger Zone

+

+ Permanently delete your account and all associated data. This action cannot be undone. +

+
+ +
+
+
+ ); +} diff --git a/frontend/app/(sidebar)/setup/page.tsx b/frontend/app/(sidebar)/setup/page.tsx index 4febef6..8ad49b7 100644 --- a/frontend/app/(sidebar)/setup/page.tsx +++ b/frontend/app/(sidebar)/setup/page.tsx @@ -1,141 +1,147 @@ -"use client"; -import { useState } from "react"; -import PlantingDetailsForm from "./planting-detail-form"; -import HarvestDetailsForm from "./harvest-detail-form"; -import GoogleMapWithDrawing from "@/components/google-map-with-drawing"; -import { Separator } from "@/components/ui/separator"; -import { - plantingDetailsFormSchema, - harvestDetailsFormSchema, -} from "@/schemas/application.schema"; -import { z } from "zod"; -import { Button } from "@/components/ui/button"; -import { toast } from "sonner"; +// "use client"; +// import { useState } from "react"; +// import PlantingDetailsForm from "./planting-detail-form"; +// import HarvestDetailsForm from "./harvest-detail-form"; +// import GoogleMapWithDrawing from "@/components/google-map-with-drawing"; +// import { Separator } from "@/components/ui/separator"; +// import { +// plantingDetailsFormSchema, +// harvestDetailsFormSchema, +// } from "@/schemas/application.schema"; +// import { z } from "zod"; +// import { Button } from "@/components/ui/button"; +// import { toast } from "sonner"; +import { redirect } from "next/navigation"; -type PlantingSchema = z.infer; -type HarvestSchema = z.infer; +// type PlantingSchema = z.infer; +// type HarvestSchema = z.infer; -const steps = [ - { title: "Step 1", description: "Planting Details" }, - { title: "Step 2", description: "Harvest Details" }, - { title: "Step 3", description: "Select Map Area" }, -]; +// const steps = [ +// { title: "Step 1", description: "Planting Details" }, +// { title: "Step 2", description: "Harvest Details" }, +// { title: "Step 3", description: "Select Map Area" }, +// ]; + +// export default function SetupPage() { +// const [step, setStep] = useState(1); +// const [plantingDetails, setPlantingDetails] = useState( +// null +// ); +// const [harvestDetails, setHarvestDetails] = useState( +// null +// ); +// const [mapData, setMapData] = useState<{ lat: number; lng: number }[] | null>( +// null +// ); + +// const handleNext = () => { +// if (step === 1 && !plantingDetails) { +// toast.warning( +// "Please complete the Planting Details before proceeding.", +// { +// action: { +// label: "Close", +// onClick: () => toast.dismiss(), +// }, +// } +// ); +// return; +// } +// if (step === 2 && !harvestDetails) { +// toast.warning( +// "Please complete the Harvest Details before proceeding.", +// { +// action: { +// label: "Close", +// onClick: () => toast.dismiss(), +// }, +// } +// ); +// return; +// } +// setStep((prev) => prev + 1); +// }; + +// const handleBack = () => { +// setStep((prev) => prev - 1); +// }; + +// const handleSubmit = () => { +// if (!mapData) { +// toast.warning("Please select an area on the map before submitting.", { +// action: { +// label: "Close", +// onClick: () => toast.dismiss(), +// }, +// }); +// return; +// } + +// console.log("Submitting:", { plantingDetails, harvestDetails, mapData }); + +// // send request to the server + +// }; + +// return ( +//
+// {/* Stepper Navigation */} +//
+// {steps.map((item, index) => ( +//
+//
+// {index + 1} +//
+// {item.title} +// {item.description} +//
+// ))} +//
+ +// + +// {step === 1 && ( +// <> +//

Planting Details

+// +// +// )} + +// {step === 2 && ( +// <> +//

Harvest Details

+// +// +// )} + +// {step === 3 && ( +// <> +//

Select Area on Map

+// +// +// )} + +//
+// + +// {step < 3 ? ( +// +// ) : ( +// +// )} +//
+//
+// ); +// } export default function SetupPage() { - const [step, setStep] = useState(1); - const [plantingDetails, setPlantingDetails] = useState( - null - ); - const [harvestDetails, setHarvestDetails] = useState( - null - ); - const [mapData, setMapData] = useState<{ lat: number; lng: number }[] | null>( - null - ); - - const handleNext = () => { - if (step === 1 && !plantingDetails) { - toast.warning( - "Please complete the Planting Details before proceeding.", - { - action: { - label: "Close", - onClick: () => toast.dismiss(), - }, - } - ); - return; - } - if (step === 2 && !harvestDetails) { - toast.warning( - "Please complete the Harvest Details before proceeding.", - { - action: { - label: "Close", - onClick: () => toast.dismiss(), - }, - } - ); - return; - } - setStep((prev) => prev + 1); - }; - - const handleBack = () => { - setStep((prev) => prev - 1); - }; - - const handleSubmit = () => { - if (!mapData) { - toast.warning("Please select an area on the map before submitting.", { - action: { - label: "Close", - onClick: () => toast.dismiss(), - }, - }); - return; - } - - console.log("Submitting:", { plantingDetails, harvestDetails, mapData }); - - // send request to the server - - }; - - return ( -
- {/* Stepper Navigation */} -
- {steps.map((item, index) => ( -
-
- {index + 1} -
- {item.title} - {item.description} -
- ))} -
- - - - {step === 1 && ( - <> -

Planting Details

- - - )} - - {step === 2 && ( - <> -

Harvest Details

- - - )} - - {step === 3 && ( - <> -

Select Area on Map

- - - )} - -
- - - {step < 3 ? ( - - ) : ( - - )} -
-
- ); + // redirect to /farms + redirect("/farms"); } diff --git a/frontend/components/google-map-with-drawing.tsx b/frontend/components/google-map-with-drawing.tsx index 0cdd310..91bfcca 100644 --- a/frontend/components/google-map-with-drawing.tsx +++ b/frontend/components/google-map-with-drawing.tsx @@ -1,52 +1,160 @@ -// google-map-with-drawing.tsx -import React from "react"; -import { ControlPosition, Map, MapControl } from "@vis.gl/react-google-maps"; - +import React, { useEffect, useRef, useState } from "react"; +import { Map, useMap, useMapsLibrary, MapControl, ControlPosition } from "@vis.gl/react-google-maps"; import { UndoRedoControl } from "@/components/map-component/undo-redo-control"; -// Import ShapeData and useDrawingManager from the correct path -import { useDrawingManager, type ShapeData } from "@/components/map-component/use-drawing-manager"; // Adjust path if needed +import { useDrawingManager } from "@/components/map-component/use-drawing-manager"; +import { GeoFeatureData, GeoPosition } from "@/types"; -// Export the type so the form can use it -export { type ShapeData }; +export type ShapeData = GeoFeatureData; -// Define props for the component interface GoogleMapWithDrawingProps { - onShapeDrawn: (data: ShapeData) => void; // Callback prop - // Add any other props you might need, e.g., initialCenter, initialZoom - initialCenter?: { lat: number; lng: number }; + onShapeDrawn?: (data: GeoFeatureData) => void; + initialCenter?: GeoPosition; initialZoom?: number; + initialFeatures?: GeoFeatureData[] | null; + drawingMode?: google.maps.drawing.OverlayType | null; + editable?: boolean; + displayOnly?: boolean; + mapId?: string; } -// Rename DrawingExample to GoogleMapWithDrawing and accept props -const GoogleMapWithDrawing = ({ - onShapeDrawn, // Destructure the callback prop - initialCenter = { lat: 13.7563, lng: 100.5018 }, // Default center - initialZoom = 10, // Default zoom +const GoogleMapWithDrawingInternal = ({ + onShapeDrawn, + initialCenter = { lat: 13.7563, lng: 100.5018 }, + initialZoom = 10, + initialFeatures, + drawingMode = null, + editable = true, + displayOnly = false, }: GoogleMapWithDrawingProps) => { - // Pass the onShapeDrawn callback directly to the hook + const map = useMap(); + const geometryLib = useMapsLibrary("geometry"); + const [drawnOverlays, setDrawnOverlays] = useState< + (google.maps.Marker | google.maps.Polygon | google.maps.Polyline)[] + >([]); + const isMountedRef = useRef(false); + const drawingManager = useDrawingManager(onShapeDrawn); + useEffect(() => { + if (!map || !initialFeatures || initialFeatures.length === 0 || !geometryLib) return; + if (isMountedRef.current && !displayOnly) return; + + drawnOverlays.forEach((overlay) => overlay.setMap(null)); + const newOverlays: (google.maps.Marker | google.maps.Polygon | google.maps.Polyline)[] = []; + const bounds = new google.maps.LatLngBounds(); + + initialFeatures.forEach((feature) => { + if (!feature) return; + + let overlay: google.maps.Marker | google.maps.Polygon | google.maps.Polyline | null = null; + + try { + if (feature.type === "marker" && feature.position) { + const marker = new google.maps.Marker({ + position: feature.position, + map: map, + }); + bounds.extend(feature.position); + overlay = marker; + } else if (feature.type === "polygon" && feature.path && feature.path.length > 0) { + const polygon = new google.maps.Polygon({ + paths: feature.path, + map: map, + strokeColor: "#FF0000", + strokeOpacity: 0.8, + strokeWeight: 2, + fillColor: "#FF0000", + fillOpacity: 0.35, + }); + feature.path.forEach((pos) => bounds.extend(pos)); + overlay = polygon; + } else if (feature.type === "polyline" && feature.path && feature.path.length > 0) { + const polyline = new google.maps.Polyline({ + path: feature.path, + map: map, + strokeColor: "#0000FF", + strokeOpacity: 1.0, + strokeWeight: 3, + }); + feature.path.forEach((pos) => bounds.extend(pos)); + overlay = polyline; + } + + if (overlay) { + newOverlays.push(overlay); + } + } catch (e) { + console.error("Error creating map overlay:", e, "Feature:", feature); + } + }); + + setDrawnOverlays(newOverlays); + + if (newOverlays.length === 1 && initialFeatures[0]?.type === "marker") { + map.setCenter(initialFeatures[0].position); + map.setZoom(initialZoom + 4); + } else if (!bounds.isEmpty()) { + map.fitBounds(bounds); + } else { + map.setCenter(initialCenter); + map.setZoom(initialZoom); + } + isMountedRef.current = true; + + return () => { + newOverlays.forEach((overlay) => { + try { + overlay.setMap(null); + } catch (e) { + console.warn("Error removing overlay during cleanup:", e); + } + }); + setDrawnOverlays([]); + isMountedRef.current = false; + }; + }, [map, initialFeatures, geometryLib, displayOnly]); + + useEffect(() => { + if (drawingManager) { + drawingManager.setOptions({ + drawingControl: !displayOnly, + drawingMode: displayOnly ? null : drawingMode, + markerOptions: { + draggable: !displayOnly && editable, + }, + polygonOptions: { + editable: !displayOnly && editable, + draggable: !displayOnly && editable, + }, + polylineOptions: { + editable: !displayOnly && editable, + draggable: !displayOnly && editable, + }, + }); + } + }, [drawingManager, displayOnly, drawingMode, editable]); + return ( <> - {/* Use props for map defaults */} - {/* Render controls only if drawingManager is available */} - {drawingManager && ( + {!displayOnly && drawingManager && ( - {/* Pass drawingManager to UndoRedoControl */} - + {editable && } )} - {/* The drawing controls (marker, polygon etc.) are added by useDrawingManager */} ); }; +const GoogleMapWithDrawing = (props: GoogleMapWithDrawingProps) => { + return ; +}; + export default GoogleMapWithDrawing; diff --git a/frontend/components/sidebar/app-sidebar.tsx b/frontend/components/sidebar/app-sidebar.tsx index 638d867..1fbf82f 100644 --- a/frontend/components/sidebar/app-sidebar.tsx +++ b/frontend/components/sidebar/app-sidebar.tsx @@ -10,21 +10,21 @@ import { GalleryVerticalEnd, Map, PieChart, - Settings2, + Settings, SquareTerminal, - User, + UserCircle, } from "lucide-react"; import { NavMain } from "./nav-main"; import { NavUser } from "./nav-user"; -import { TeamSwitcher } from "./team-switcher"; -import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarRail } from "@/components/ui/sidebar"; -import { NavCrops } from "./nav-crops"; +import { Sidebar, SidebarContent, SidebarHeader, SidebarRail } from "@/components/ui/sidebar"; +// import { NavCrops } from "./nav-crops"; import { fetchUserMe } from "@/api/user"; +import { usePathname } from "next/navigation"; interface Team { name: string; - logo: React.ComponentType; + logo: React.ComponentType<{ className?: string }>; // Ensure logo type accepts className plan: string; } @@ -34,12 +34,13 @@ interface NavItem { title: string; url: string; icon: LucideIcon; + isActive?: boolean; // Add isActive property } interface SidebarConfig { teams: Team[]; navMain: NavItem[]; - crops: NavItem[]; + // crops: NavItem[]; } interface AppSidebarProps extends React.ComponentProps { @@ -69,27 +70,28 @@ function UserErrorFallback({ message }: { message: string }) { ); } +const defaultNavMain: NavItem[] = [ + { title: "Farms", url: "/farms", icon: Map }, + { title: "Inventory", url: "/inventory", icon: SquareTerminal }, + { title: "Marketplace", url: "/marketplace", icon: PieChart }, // Updated title and icon + { title: "Knowledge Hub", url: "/hub", icon: BookOpen }, + { title: "AI Chatbot", url: "/chatbot", icon: Bot }, + { title: "Profile", url: "/profile", icon: UserCircle }, // Added Profile + { title: "Settings", url: "/settings", icon: Settings }, // Kept Settings +]; + export function AppSidebar({ config, ...props }: AppSidebarProps) { + const pathname = usePathname(); const defaultConfig: SidebarConfig = { teams: [ { name: "Farm 1", logo: GalleryVerticalEnd, plan: "Hatyai" }, { name: "Farm 2", logo: AudioWaveform, plan: "Songkla" }, { name: "Farm 3", logo: Command, plan: "Layong" }, ], - navMain: [ - { title: "Farms", url: "/farms", icon: Map }, - { title: "Inventory", url: "/inventory", icon: SquareTerminal }, - { title: "Marketplace Information", url: "/marketplace", icon: PieChart }, - { title: "Knowledge Hub", url: "/hub", icon: BookOpen }, - { title: "Users", url: "/users", icon: User }, - { title: "AI Chatbot", url: "/chatbot", icon: Bot }, - { title: "Settings", url: "/settings", icon: Settings2 }, - ], - crops: [ - { title: "Crops 1", url: "/farms/[farmId]/crops/1", icon: Map }, - { title: "Crops 2", url: "/farms/[farmId]/crops/2", icon: Map }, - { title: "Crops 3", url: "/farms/[farmId]/crops/3", icon: Map }, - ], + navMain: defaultNavMain.map((item) => ({ + ...item, + isActive: pathname.startsWith(item.url) && (item.url !== "/" || pathname === "/"), + })), }; // Allow external configuration override @@ -107,17 +109,18 @@ export function AppSidebar({ config, ...props }: AppSidebarProps) { async function getUser() { try { const data = await fetchUserMe(); - console.log(data); + console.log("Fetched user data:", data); setUser({ - name: data.user.uuid, + name: data.user.username || data.user.email.split("@")[0] || `User ${data.user.uuid.substring(0, 6)}`, email: data.user.email, - avatar: data.user.avatar || "/avatars/avatar.webp", + avatar: data.user.avatar || `https://api.dicebear.com/9.x/initials/svg?seed=${data.user.email}`, }); } catch (err: unknown) { + console.error("Failed to fetch user for sidebar:", err); if (err instanceof Error) { setError(err.message); } else { - setError("An unexpected error occurred"); + setError("An unexpected error occurred fetching user data"); } } finally { setLoading(false); @@ -129,17 +132,14 @@ export function AppSidebar({ config, ...props }: AppSidebarProps) { return ( - + {loading ? : error ? : } -
- -
- + {/* {loading ? : error ? : } - + */}
); diff --git a/frontend/components/ui/alert-dialog.tsx b/frontend/components/ui/alert-dialog.tsx new file mode 100644 index 0000000..57760f2 --- /dev/null +++ b/frontend/components/ui/alert-dialog.tsx @@ -0,0 +1,141 @@ +"use client" + +import * as React from "react" +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" + +import { cn } from "@/lib/utils" +import { buttonVariants } from "@/components/ui/button" + +const AlertDialog = AlertDialogPrimitive.Root + +const AlertDialogTrigger = AlertDialogPrimitive.Trigger + +const AlertDialogPortal = AlertDialogPrimitive.Portal + +const AlertDialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName + +const AlertDialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + +)) +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName + +const AlertDialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogHeader.displayName = "AlertDialogHeader" + +const AlertDialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogFooter.displayName = "AlertDialogFooter" + +const AlertDialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName + +const AlertDialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogDescription.displayName = + AlertDialogPrimitive.Description.displayName + +const AlertDialogAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName + +const AlertDialogCancel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} diff --git a/frontend/package.json b/frontend/package.json index 8029496..c3603a9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@hookform/resolvers": "^4.0.0", + "@radix-ui/react-alert-dialog": "^1.1.6", "@radix-ui/react-avatar": "^1.1.3", "@radix-ui/react-checkbox": "^1.1.4", "@radix-ui/react-collapsible": "^1.1.3", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index d3cfefe..a361c2d 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -1,234 +1,2900 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - '@hookform/resolvers': - specifier: ^4.0.0 - version: 4.1.3(react-hook-form@7.54.2) - '@radix-ui/react-avatar': - specifier: ^1.1.3 - version: 1.1.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-checkbox': - specifier: ^1.1.4 - version: 1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-collapsible': - specifier: ^1.1.3 - version: 1.1.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-dialog': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-dropdown-menu': - specifier: ^2.1.6 - version: 2.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-hover-card': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-label': - specifier: ^2.1.2 - version: 2.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-popover': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-progress': - specifier: ^1.1.2 - version: 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-scroll-area': - specifier: ^1.2.3 - version: 1.2.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-select': - specifier: ^2.1.6 - version: 2.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-separator': - specifier: ^1.1.2 - version: 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-slot': - specifier: ^1.1.2 - version: 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-switch': - specifier: ^1.1.3 - version: 1.1.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-tabs': - specifier: ^1.1.3 - version: 1.1.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-tooltip': - specifier: ^1.1.8 - version: 1.1.8(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-visually-hidden': - specifier: ^1.1.2 - version: 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@react-google-maps/api': - specifier: ^2.20.6 - version: 2.20.6(react-dom@19.0.0)(react@19.0.0) - '@react-oauth/google': - specifier: ^0.12.1 - version: 0.12.1(react-dom@19.0.0)(react@19.0.0) - '@tailwindcss/typography': - specifier: ^0.5.16 - version: 0.5.16(tailwindcss@3.4.17) - '@tanstack/react-query': - specifier: ^5.66.0 - version: 5.67.3(react@19.0.0) - '@tanstack/react-table': - specifier: ^8.21.2 - version: 8.21.2(react-dom@19.0.0)(react@19.0.0) - '@vis.gl/react-google-maps': - specifier: ^1.5.2 - version: 1.5.2(react-dom@19.0.0)(react@19.0.0) - axios: - specifier: ^1.7.9 - version: 1.8.3 - class-variance-authority: - specifier: ^0.7.1 - version: 0.7.1 - clsx: - specifier: ^2.1.1 - version: 2.1.1 - date-fns: - specifier: ^4.1.0 - version: 4.1.0 - framer-motion: - specifier: ^12.4.10 - version: 12.5.0(react-dom@19.0.0)(react@19.0.0) - js-cookie: - specifier: ^3.0.5 - version: 3.0.5 - lucide-react: - specifier: ^0.475.0 - version: 0.475.0(react@19.0.0) - next: - specifier: 15.1.0 - version: 15.1.0(react-dom@19.0.0)(react@19.0.0) - next-auth: - specifier: ^4.24.11 - version: 4.24.11(next@15.1.0)(react-dom@19.0.0)(react@19.0.0) - next-themes: - specifier: ^0.4.6 - version: 0.4.6(react-dom@19.0.0)(react@19.0.0) - react: - specifier: ^19.0.0 - version: 19.0.0 - react-day-picker: - specifier: 8.10.1 - version: 8.10.1(date-fns@4.1.0)(react@19.0.0) - react-dom: - specifier: ^19.0.0 - version: 19.0.0(react@19.0.0) - react-hook-form: - specifier: ^7.54.2 - version: 7.54.2(react@19.0.0) - react-icons: - specifier: ^5.5.0 - version: 5.5.0(react@19.0.0) - recharts: - specifier: ^2.15.1 - version: 2.15.1(react-dom@19.0.0)(react@19.0.0) - sonner: - specifier: ^2.0.1 - version: 2.0.1(react-dom@19.0.0)(react@19.0.0) - tailwind-merge: - specifier: ^3.0.1 - version: 3.0.2 - tailwindcss-animate: - specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.17) - zod: - specifier: ^3.24.2 - version: 3.24.2 +importers: -devDependencies: - '@eslint/eslintrc': - specifier: ^3 - version: 3.3.0 - '@types/node': - specifier: ^20 - version: 20.17.24 - '@types/react': - specifier: ^19 - version: 19.0.10 - '@types/react-dom': - specifier: ^19 - version: 19.0.4(@types/react@19.0.10) - eslint: - specifier: ^9 - version: 9.22.0 - eslint-config-next: - specifier: 15.1.0 - version: 15.1.0(eslint@9.22.0)(typescript@5.8.2) - postcss: - specifier: ^8 - version: 8.5.3 - tailwindcss: - specifier: ^3.4.1 - version: 3.4.17 - typescript: - specifier: ^5 - version: 5.8.2 + .: + dependencies: + '@hookform/resolvers': + specifier: ^4.0.0 + version: 4.1.3(react-hook-form@7.55.0(react@19.1.0)) + '@radix-ui/react-alert-dialog': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-avatar': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-checkbox': + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-collapsible': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-dialog': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-dropdown-menu': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-hover-card': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-label': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-popover': + specifier: ^1.1.6 + version: 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-progress': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-scroll-area': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-select': + specifier: ^2.1.6 + version: 2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-separator': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-switch': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-tabs': + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-tooltip': + specifier: ^1.1.8 + version: 1.1.8(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-visually-hidden': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@react-google-maps/api': + specifier: ^2.20.6 + version: 2.20.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@react-oauth/google': + specifier: ^0.12.1 + version: 0.12.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@tailwindcss/typography': + specifier: ^0.5.16 + version: 0.5.16(tailwindcss@3.4.17) + '@tanstack/react-query': + specifier: ^5.66.0 + version: 5.71.5(react@19.1.0) + '@tanstack/react-table': + specifier: ^8.21.2 + version: 8.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@vis.gl/react-google-maps': + specifier: ^1.5.2 + version: 1.5.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + axios: + specifier: ^1.7.9 + version: 1.8.4 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + date-fns: + specifier: ^4.1.0 + version: 4.1.0 + framer-motion: + specifier: ^12.4.10 + version: 12.6.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + lucide-react: + specifier: ^0.475.0 + version: 0.475.0(react@19.1.0) + next: + specifier: 15.1.0 + version: 15.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-auth: + specifier: ^4.24.11 + version: 4.24.11(next@15.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: + specifier: ^19.0.0 + version: 19.1.0 + react-day-picker: + specifier: 8.10.1 + version: 8.10.1(date-fns@4.1.0)(react@19.1.0) + react-dom: + specifier: ^19.0.0 + version: 19.1.0(react@19.1.0) + react-hook-form: + specifier: ^7.54.2 + version: 7.55.0(react@19.1.0) + react-icons: + specifier: ^5.5.0 + version: 5.5.0(react@19.1.0) + recharts: + specifier: ^2.15.1 + version: 2.15.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + sonner: + specifier: ^2.0.1 + version: 2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + tailwind-merge: + specifier: ^3.0.1 + version: 3.1.0 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) + zod: + specifier: ^3.24.2 + version: 3.24.2 + devDependencies: + '@eslint/eslintrc': + specifier: ^3 + version: 3.3.1 + '@types/node': + specifier: ^20 + version: 20.17.30 + '@types/react': + specifier: ^19 + version: 19.1.0 + '@types/react-dom': + specifier: ^19 + version: 19.1.1(@types/react@19.1.0) + eslint: + specifier: ^9 + version: 9.23.0(jiti@1.21.7) + eslint-config-next: + specifier: 15.1.0 + version: 15.1.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) + postcss: + specifier: ^8 + version: 8.5.3 + tailwindcss: + specifier: ^3.4.1 + version: 3.4.17 + typescript: + specifier: ^5 + version: 5.8.2 packages: - /@alloc/quick-lru@5.2.0: + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - /@babel/runtime@7.26.10: - resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} + '@babel/runtime@7.27.0': + resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.1 - dev: false - /@emnapi/runtime@1.3.1: - resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} - requiresBuild: true - dependencies: - tslib: 2.8.1 - dev: false - optional: true + '@emnapi/core@1.4.0': + resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} - /@eslint-community/eslint-utils@4.5.0(eslint@9.22.0): - resolution: {integrity: sha512-RoV8Xs9eNwiDvhv7M+xcL4PWyRyIXRY/FLp3buU4h1EYfdF7unWUy3dOjPqb3C7rMUewIcqwW850PgS8h1o1yg==} + '@emnapi/runtime@1.4.0': + resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} + + '@emnapi/wasi-threads@1.0.1': + resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + + '@eslint-community/eslint-utils@4.5.1': + resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 9.22.0 - eslint-visitor-keys: 3.4.3 - dev: true - /@eslint-community/regexpp@4.12.1: + '@eslint-community/regexpp@4.12.1': resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true - /@eslint/config-array@0.19.2: + '@eslint/config-array@0.19.2': resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.1': + resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.12.0': + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.13.0': + resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.23.0': + resolution: {integrity: sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.8': + resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@floating-ui/core@1.6.9': + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + + '@floating-ui/dom@1.6.13': + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + + '@floating-ui/react-dom@2.1.2': + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@googlemaps/js-api-loader@1.16.8': + resolution: {integrity: sha512-CROqqwfKotdO6EBjZO/gQGVTbeDps5V7Mt9+8+5Q+jTg5CRMi3Ii/L9PmV3USROrt2uWxtGzJHORmByxyo9pSQ==} + + '@googlemaps/markerclusterer@2.5.3': + resolution: {integrity: sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==} + + '@hookform/resolvers@4.1.3': + resolution: {integrity: sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==} + peerDependencies: + react-hook-form: ^7.0.0 + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@napi-rs/wasm-runtime@0.2.8': + resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==} + + '@next/env@15.1.0': + resolution: {integrity: sha512-UcCO481cROsqJuszPPXJnb7GGuLq617ve4xuAyyNG4VSSocJNtMU5Fsx+Lp6mlN8c7W58aZLc5y6D/2xNmaK+w==} + + '@next/eslint-plugin-next@15.1.0': + resolution: {integrity: sha512-+jPT0h+nelBT6HC9ZCHGc7DgGVy04cv4shYdAe6tKlEbjQUtwU3LzQhzbDHQyY2m6g39m6B0kOFVuLGBrxxbGg==} + + '@next/swc-darwin-arm64@15.1.0': + resolution: {integrity: sha512-ZU8d7xxpX14uIaFC3nsr4L++5ZS/AkWDm1PzPO6gD9xWhFkOj2hzSbSIxoncsnlJXB1CbLOfGVN4Zk9tg83PUw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.1.0': + resolution: {integrity: sha512-DQ3RiUoW2XC9FcSM4ffpfndq1EsLV0fj0/UY33i7eklW5akPUCo6OX2qkcLXZ3jyPdo4sf2flwAED3AAq3Om2Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.1.0': + resolution: {integrity: sha512-M+vhTovRS2F//LMx9KtxbkWk627l5Q7AqXWWWrfIzNIaUFiz2/NkOFkxCFyNyGACi5YbA8aekzCLtbDyfF/v5Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.1.0': + resolution: {integrity: sha512-Qn6vOuwaTCx3pNwygpSGtdIu0TfS1KiaYLYXLH5zq1scoTXdwYfdZtwvJTpB1WrLgiQE2Ne2kt8MZok3HlFqmg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.1.0': + resolution: {integrity: sha512-yeNh9ofMqzOZ5yTOk+2rwncBzucc6a1lyqtg8xZv0rH5znyjxHOWsoUtSq4cUTeeBIiXXX51QOOe+VoCjdXJRw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.1.0': + resolution: {integrity: sha512-t9IfNkHQs/uKgPoyEtU912MG6a1j7Had37cSUyLTKx9MnUpjj+ZDKw9OyqTI9OwIIv0wmkr1pkZy+3T5pxhJPg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.1.0': + resolution: {integrity: sha512-WEAoHyG14t5sTavZa1c6BnOIEukll9iqFRTavqRVPfYmfegOAd5MaZfXgOGG6kGo1RduyGdTHD4+YZQSdsNZXg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.1.0': + resolution: {integrity: sha512-J1YdKuJv9xcixzXR24Dv+4SaDKc2jj31IVUEMdO5xJivMTXuE6MAdIi4qPjSymHuFG8O5wbfWKnhJUcHHpj5CA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@panva/hkdf@1.2.1': + resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@radix-ui/number@1.1.0': + resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} + + '@radix-ui/primitive@1.1.1': + resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} + + '@radix-ui/react-alert-dialog@1.1.6': + resolution: {integrity: sha512-p4XnPqgej8sZAAReCAKgz1REYZEBLR8hU9Pg27wFnCWIMc8g1ccCs0FjBcy05V15VTu8pAePw/VDYeOm/uZ6yQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-arrow@1.1.2': + resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-avatar@1.1.3': + resolution: {integrity: sha512-Paen00T4P8L8gd9bNsRMw7Cbaz85oxiv+hzomsRZgFm2byltPFDtfcoqlWJ8GyZlIBWgLssJlzLCnKU0G0302g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-checkbox@1.1.4': + resolution: {integrity: sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collapsible@1.1.3': + resolution: {integrity: sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.2': + resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.1': + resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.6': + resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.0': + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.5': + resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.1.6': + resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.1': + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.2': + resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-hover-card@1.1.6': + resolution: {integrity: sha512-E4ozl35jq0VRlrdc4dhHrNSV0JqBb4Jy73WAhBEK7JoYnQ83ED5r0Rb/XdVKw89ReAJN38N492BAPBZQ57VmqQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-label@2.1.2': + resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menu@2.1.6': + resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.6': + resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.2': + resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.4': + resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.2': + resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.0.2': + resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-progress@1.1.2': + resolution: {integrity: sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.2': + resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-scroll-area@1.2.3': + resolution: {integrity: sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-select@2.1.6': + resolution: {integrity: sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-separator@1.1.2': + resolution: {integrity: sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.1.2': + resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.1.3': + resolution: {integrity: sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tabs@1.1.3': + resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tooltip@1.1.8': + resolution: {integrity: sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.0': + resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.0': + resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.0': + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.1.2': + resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.0': + resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + + '@react-google-maps/api@2.20.6': + resolution: {integrity: sha512-frxkSHWbd36ayyxrEVopSCDSgJUT1tVKXvQld2IyzU3UnDuqqNA3AZE4/fCdqQb2/zBQx3nrWnZB1wBXDcrjcw==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 + react-dom: ^16.8 || ^17 || ^18 || ^19 + + '@react-google-maps/infobox@2.20.0': + resolution: {integrity: sha512-03PJHjohhaVLkX6+NHhlr8CIlvUxWaXhryqDjyaZ8iIqqix/nV8GFdz9O3m5OsjtxtNho09F/15j14yV0nuyLQ==} + + '@react-google-maps/marker-clusterer@2.20.0': + resolution: {integrity: sha512-tieX9Va5w1yP88vMgfH1pHTacDQ9TgDTjox3tLlisKDXRQWdjw+QeVVghhf5XqqIxXHgPdcGwBvKY6UP+SIvLw==} + + '@react-oauth/google@0.12.1': + resolution: {integrity: sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@rushstack/eslint-patch@1.11.0': + resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} + + '@standard-schema/utils@0.3.0': + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tailwindcss/typography@0.5.16': + resolution: {integrity: sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + + '@tanstack/query-core@5.71.5': + resolution: {integrity: sha512-XOQ5SyjCdwhxyLksGKWSL5poqyEXYPDnsrZAzJm2LgrMm4Yh6VOrfC+IFosXreDw9HNqC11YAMY3HlfHjNzuaA==} + + '@tanstack/react-query@5.71.5': + resolution: {integrity: sha512-WpxZWy4fDASjY+iAaXB+aY+LC95PQ34W6EWVkjJ0hdzWWbczFnr9nHvHkVDpwdR18I1NO8igNGQJFrLrgyzI8Q==} + peerDependencies: + react: ^18 || ^19 + + '@tanstack/react-table@8.21.2': + resolution: {integrity: sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + '@tanstack/table-core@8.21.2': + resolution: {integrity: sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==} + engines: {node: '>=12'} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + + '@types/d3-array@3.2.1': + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/google.maps@3.58.1': + resolution: {integrity: sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node@20.17.30': + resolution: {integrity: sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==} + + '@types/react-dom@19.1.1': + resolution: {integrity: sha512-jFf/woGTVTjUJsl2O7hcopJ1r0upqoq/vIOoCj0yLh3RIXxWcljlpuZ+vEBRXsymD1jhfeJrlyTy/S1UW+4y1w==} + peerDependencies: + '@types/react': ^19.0.0 + + '@types/react@19.1.0': + resolution: {integrity: sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==} + + '@typescript-eslint/eslint-plugin@8.29.0': + resolution: {integrity: sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/parser@8.29.0': + resolution: {integrity: sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/scope-manager@8.29.0': + resolution: {integrity: sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.29.0': + resolution: {integrity: sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/types@8.29.0': + resolution: {integrity: sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.29.0': + resolution: {integrity: sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/utils@8.29.0': + resolution: {integrity: sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/visitor-keys@8.29.0': + resolution: {integrity: sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-darwin-arm64@1.3.3': + resolution: {integrity: sha512-EpRILdWr3/xDa/7MoyfO7JuBIJqpBMphtu4+80BK1bRfFcniVT74h3Z7q1+WOc92FuIAYatB1vn9TJR67sORGw==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.3.3': + resolution: {integrity: sha512-ntj/g7lPyqwinMJWZ+DKHBse8HhVxswGTmNgFKJtdgGub3M3zp5BSZ3bvMP+kBT6dnYJLSVlDqdwOq1P8i0+/g==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.3.3': + resolution: {integrity: sha512-l6BT8f2CU821EW7U8hSUK8XPq4bmyTlt9Mn4ERrfjJNoCw0/JoHAh9amZZtV3cwC3bwwIat+GUnrcHTG9+qixw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.3.3': + resolution: {integrity: sha512-8ScEc5a4y7oE2BonRvzJ+2GSkBaYWyh0/Ko4Q25e/ix6ANpJNhwEPZvCR6GVRmsQAYMIfQvYLdM6YEN+qRjnAQ==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.3.3': + resolution: {integrity: sha512-8qQ6l1VTzLNd3xb2IEXISOKwMGXDCzY/UNy/7SovFW2Sp0K3YbL7Ao7R18v6SQkLqQlhhqSBIFRk+u6+qu5R5A==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.3.3': + resolution: {integrity: sha512-v81R2wjqcWXJlQY23byqYHt9221h4anQ6wwN64oMD/WAE+FmxPHFZee5bhRkNVtzqO/q7wki33VFWlhiADwUeQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.3.3': + resolution: {integrity: sha512-cAOx/j0u5coMg4oct/BwMzvWJdVciVauUvsd+GQB/1FZYKQZmqPy0EjJzJGbVzFc6gbnfEcSqvQE6gvbGf2N8Q==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.3.3': + resolution: {integrity: sha512-mq2blqwErgDJD4gtFDlTX/HZ7lNP8YCHYFij2gkXPtMzrXxPW1hOtxL6xg4NWxvnj4bppppb0W3s/buvM55yfg==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.3.3': + resolution: {integrity: sha512-u0VRzfFYysarYHnztj2k2xr+eu9rmgoTUUgCCIT37Nr+j0A05Xk2c3RY8Mh5+DhCl2aYibihnaAEJHeR0UOFIQ==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.3.3': + resolution: {integrity: sha512-OrVo5ZsG29kBF0Ug95a2KidS16PqAMmQNozM6InbquOfW/udouk063e25JVLqIBhHLB2WyBnixOQ19tmeC/hIg==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.3.3': + resolution: {integrity: sha512-PYnmrwZ4HMp9SkrOhqPghY/aoL+Rtd4CQbr93GlrRTjK6kDzfMfgz3UH3jt6elrQAfupa1qyr1uXzeVmoEAxUA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.3.3': + resolution: {integrity: sha512-81AnQY6fShmktQw4hWDUIilsKSdvr/acdJ5azAreu2IWNlaJOKphJSsUVWE+yCk6kBMoQyG9ZHCb/krb5K0PEA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.3.3': + resolution: {integrity: sha512-X/42BMNw7cW6xrB9syuP5RusRnWGoq+IqvJO8IDpp/BZg64J1uuIW6qA/1Cl13Y4LyLXbJVYbYNSKwR/FiHEng==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.3.3': + resolution: {integrity: sha512-EGNnNGQxMU5aTN7js3ETYvuw882zcO+dsVjs+DwO2j/fRVKth87C8e2GzxW1L3+iWAXMyJhvFBKRavk9Og1Z6A==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.3.3': + resolution: {integrity: sha512-GraLbYqOJcmW1qY3osB+2YIiD62nVf2/bVLHZmrb4t/YSUwE03l7TwcDJl08T/Tm3SVhepX8RQkpzWbag/Sb4w==} + cpu: [x64] + os: [win32] + + '@vis.gl/react-google-maps@1.5.2': + resolution: {integrity: sha512-0Ypmde7M73GgV4TgcaUTNKXsbcXWToPVuawMNrVg7htXmhpEfLARHwhtmP6N1da3od195ZKC8ShXzC6Vm+zYHQ==} + peerDependencies: + react: '>=16.8.0 || ^19.0 || ^19.0.0-rc' + react-dom: '>=16.8.0 || ^19.0 || ^19.0.0-rc' + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.10.3: + resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} + engines: {node: '>=4'} + + axios@1.8.4: + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + caniuse-lite@1.0.30001710: + resolution: {integrity: sha512-B5C0I0UmaGqHgo5FuqJ7hBd4L57A4dDD+Xi+XX1nXOoxGeDdY4Ko38qJYOyqznBVJEqON5p8P1x5zRR3+rsnxA==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-next@15.1.0: + resolution: {integrity: sha512-gADO+nKVseGso3DtOrYX9H7TxB/MuX7AUYhMlvQMqLYvUWu4HrOQuU7cC1HW74tHIqkAvXdwgAz3TCbczzSEXw==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.10.0: + resolution: {integrity: sha512-aV3/dVsT0/H9BtpNwbaqvl+0xGMRGzncLyhm793NFGvbwGGvzyAykqWZ8oZlZuGwuHkwJjhWJkG1cM3ynvd2pQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.23.0: + resolution: {integrity: sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-equals@5.2.2: + resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==} + engines: {node: '>=6.0.0'} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + + framer-motion@12.6.3: + resolution: {integrity: sha512-2hsqknz23aloK85bzMc9nSR2/JP+fValQ459ZTVElFQ0xgwR2YqNjYSuDZdFBPOwVCt4Q9jgyTt6hg6sVOALzw==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + jose@4.15.9: + resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + kdbush@4.0.2: + resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.castarray@4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lucide-react@0.475.0: + resolution: {integrity: sha512-NJzvVu1HwFVeZ+Gwq2q00KygM1aBhy/ZrhY9FsAgJtpB+E4R7uxRk9M2iKvHa6/vNxZydIB59htha4c2vvwvVg==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + motion-dom@12.6.3: + resolution: {integrity: sha512-gRY08RjcnzgFYLemUZ1lo/e9RkBxR+6d4BRvoeZDSeArG4XQXERSPapKl3LNQRu22Sndjf1h+iavgY0O4NrYqA==} + + motion-utils@12.6.3: + resolution: {integrity: sha512-R/b3Ia2VxtTNZ4LTEO5pKYau1OUNHOuUfxuP0WFCTDYdHkeTBR9UtxR1cc8mDmKr8PEhmmfnTKGz3rSMjNRoRg==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + next-auth@4.24.11: + resolution: {integrity: sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==} + peerDependencies: + '@auth/core': 0.34.2 + next: ^12.2.5 || ^13 || ^14 || ^15 + nodemailer: ^6.6.5 + react: ^17.0.2 || ^18 || ^19 + react-dom: ^17.0.2 || ^18 || ^19 + peerDependenciesMeta: + '@auth/core': + optional: true + nodemailer: + optional: true + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + next@15.1.0: + resolution: {integrity: sha512-QKhzt6Y8rgLNlj30izdMbxAwjHMFANnLwDwZ+WQh5sMhyt4lEBqDK9QpvWHtIM4rINKPoJ8aiRZKg5ULSybVHw==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + oauth@0.9.15: + resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@2.2.0: + resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} + engines: {node: '>= 6'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + oidc-token-hash@5.1.0: + resolution: {integrity: sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA==} + engines: {node: ^10.13.0 || >=12.0.0} + + openid-client@5.7.1: + resolution: {integrity: sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + preact-render-to-string@5.2.6: + resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} + peerDependencies: + preact: '>=10' + + preact@10.26.4: + resolution: {integrity: sha512-KJhO7LBFTjP71d83trW+Ilnjbo+ySsaAgCfXOXUlmGzJ4ygYPWmysm77yg4emwfmoz3b22yvH5IsVFHbhUaH5w==} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + pretty-format@3.8.0: + resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-day-picker@8.10.1: + resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==} + peerDependencies: + date-fns: ^2.28.0 || ^3.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + peerDependencies: + react: ^19.1.0 + + react-hook-form@7.55.0: + resolution: {integrity: sha512-XRnjsH3GVMQz1moZTW53MxfoWN7aDpUg/GpVNc4A3eXRVNdGXfbzJ4vM4aLQ8g6XCUh1nIbx70aaNCl7kxnjog==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-icons@5.5.0: + resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} + peerDependencies: + react: '*' + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.6.3: + resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-smooth@4.0.4: + resolution: {integrity: sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-transition-group@4.4.5: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + + react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + recharts-scale@0.4.5: + resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + + recharts@2.15.2: + resolution: {integrity: sha512-xv9lVztv3ingk7V3Jf05wfAZbM9Q2umJzu5t/cfnAK7LUslNrGT7LPBr74G+ok8kSCeFMaePmWMg0rcYOnczTw==} + engines: {node: '>=14'} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + sonner@2.0.3: + resolution: {integrity: sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supercluster@8.0.1: + resolution: {integrity: sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tailwind-merge@3.1.0: + resolution: {integrity: sha512-aV27Oj8B7U/tAOMhJsSGdWqelfmudnGMdXIlMnk1JfsjwSjts6o8HyfN7SFH3EztzH4YH8kk6GbLTHzITJO39Q==} + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + + tailwindcss@3.4.17: + resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} + engines: {node: '>=14.0.0'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + unrs-resolver@1.3.3: + resolution: {integrity: sha512-PFLAGQzYlyjniXdbmQ3dnGMZJXX5yrl2YS4DLRfR3BhgUsE1zpRIrccp9XMOGRfIHpdFvCn/nr5N1KMVda4x3A==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + victory-vendor@36.9.2: + resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@2.7.1: + resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} + engines: {node: '>= 14'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod@3.24.2: + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@babel/runtime@7.27.0': + dependencies: + regenerator-runtime: 0.14.1 + + '@emnapi/core@1.4.0': + dependencies: + '@emnapi/wasi-threads': 1.0.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.4.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.0.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@eslint-community/eslint-utils@4.5.1(eslint@9.23.0(jiti@1.21.7))': + dependencies: + eslint: 9.23.0(jiti@1.21.7) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.19.2': dependencies: '@eslint/object-schema': 2.1.6 debug: 4.4.0 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - dev: true - /@eslint/config-helpers@0.1.0: - resolution: {integrity: sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - dev: true + '@eslint/config-helpers@0.2.1': {} - /@eslint/core@0.12.0: - resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.12.0': dependencies: '@types/json-schema': 7.0.15 - dev: true - /@eslint/eslintrc@3.3.0: - resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.13.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 debug: 4.4.0 @@ -241,1301 +2907,710 @@ packages: strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - dev: true - /@eslint/js@9.22.0: - resolution: {integrity: sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - dev: true + '@eslint/js@9.23.0': {} - /@eslint/object-schema@2.1.6: - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - dev: true + '@eslint/object-schema@2.1.6': {} - /@eslint/plugin-kit@0.2.7: - resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.2.8': dependencies: - '@eslint/core': 0.12.0 + '@eslint/core': 0.13.0 levn: 0.4.1 - dev: true - /@floating-ui/core@1.6.9: - resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + '@floating-ui/core@1.6.9': dependencies: '@floating-ui/utils': 0.2.9 - dev: false - /@floating-ui/dom@1.6.13: - resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + '@floating-ui/dom@1.6.13': dependencies: '@floating-ui/core': 1.6.9 '@floating-ui/utils': 0.2.9 - dev: false - /@floating-ui/react-dom@2.1.2(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' + '@floating-ui/react-dom@2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@floating-ui/dom': 1.6.13 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /@floating-ui/utils@0.2.9: - resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} - dev: false + '@floating-ui/utils@0.2.9': {} - /@googlemaps/js-api-loader@1.16.8: - resolution: {integrity: sha512-CROqqwfKotdO6EBjZO/gQGVTbeDps5V7Mt9+8+5Q+jTg5CRMi3Ii/L9PmV3USROrt2uWxtGzJHORmByxyo9pSQ==} - dev: false + '@googlemaps/js-api-loader@1.16.8': {} - /@googlemaps/markerclusterer@2.5.3: - resolution: {integrity: sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw==} + '@googlemaps/markerclusterer@2.5.3': dependencies: fast-deep-equal: 3.1.3 supercluster: 8.0.1 - dev: false - /@hookform/resolvers@4.1.3(react-hook-form@7.54.2): - resolution: {integrity: sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==} - peerDependencies: - react-hook-form: ^7.0.0 + '@hookform/resolvers@4.1.3(react-hook-form@7.55.0(react@19.1.0))': dependencies: '@standard-schema/utils': 0.3.0 - react-hook-form: 7.54.2(react@19.0.0) - dev: false + react-hook-form: 7.55.0(react@19.1.0) - /@humanfs/core@0.19.1: - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - dev: true + '@humanfs/core@0.19.1': {} - /@humanfs/node@0.16.6: - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} + '@humanfs/node@0.16.6': dependencies: '@humanfs/core': 0.19.1 '@humanwhocodes/retry': 0.3.1 - dev: true - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true + '@humanwhocodes/module-importer@1.0.1': {} - /@humanwhocodes/retry@0.3.1: - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - dev: true + '@humanwhocodes/retry@0.3.1': {} - /@humanwhocodes/retry@0.4.2: - resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} - engines: {node: '>=18.18'} - dev: true + '@humanwhocodes/retry@0.4.2': {} - /@img/sharp-darwin-arm64@0.33.5: - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - requiresBuild: true + '@img/sharp-darwin-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.0.4 - dev: false optional: true - /@img/sharp-darwin-x64@0.33.5: - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - requiresBuild: true + '@img/sharp-darwin-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.0.4 - dev: false optional: true - /@img/sharp-libvips-darwin-arm64@1.0.4: - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: false + '@img/sharp-libvips-darwin-arm64@1.0.4': optional: true - /@img/sharp-libvips-darwin-x64@1.0.4: - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: false + '@img/sharp-libvips-darwin-x64@1.0.4': optional: true - /@img/sharp-libvips-linux-arm64@1.0.4: - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false + '@img/sharp-libvips-linux-arm64@1.0.4': optional: true - /@img/sharp-libvips-linux-arm@1.0.5: - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: false + '@img/sharp-libvips-linux-arm@1.0.5': optional: true - /@img/sharp-libvips-linux-s390x@1.0.4: - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: false + '@img/sharp-libvips-linux-s390x@1.0.4': optional: true - /@img/sharp-libvips-linux-x64@1.0.4: - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false + '@img/sharp-libvips-linux-x64@1.0.4': optional: true - /@img/sharp-libvips-linuxmusl-arm64@1.0.4: - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': optional: true - /@img/sharp-libvips-linuxmusl-x64@1.0.4: - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false + '@img/sharp-libvips-linuxmusl-x64@1.0.4': optional: true - /@img/sharp-linux-arm64@0.33.5: - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - requiresBuild: true + '@img/sharp-linux-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.0.4 - dev: false optional: true - /@img/sharp-linux-arm@0.33.5: - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - requiresBuild: true + '@img/sharp-linux-arm@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.0.5 - dev: false optional: true - /@img/sharp-linux-s390x@0.33.5: - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - requiresBuild: true + '@img/sharp-linux-s390x@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.0.4 - dev: false optional: true - /@img/sharp-linux-x64@0.33.5: - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - requiresBuild: true + '@img/sharp-linux-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.0.4 - dev: false optional: true - /@img/sharp-linuxmusl-arm64@0.33.5: - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - requiresBuild: true + '@img/sharp-linuxmusl-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - dev: false optional: true - /@img/sharp-linuxmusl-x64@0.33.5: - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - requiresBuild: true + '@img/sharp-linuxmusl-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - dev: false optional: true - /@img/sharp-wasm32@0.33.5: - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - requiresBuild: true + '@img/sharp-wasm32@0.33.5': dependencies: - '@emnapi/runtime': 1.3.1 - dev: false + '@emnapi/runtime': 1.4.0 optional: true - /@img/sharp-win32-ia32@0.33.5: - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: false + '@img/sharp-win32-ia32@0.33.5': optional: true - /@img/sharp-win32-x64@0.33.5: - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: false + '@img/sharp-win32-x64@0.33.5': optional: true - /@isaacs/cliui@8.0.2: - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 + string-width-cjs: string-width@4.2.3 strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 + strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 - /@jridgewell/gen-mapping@0.3.8: - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 - /@jridgewell/resolve-uri@3.1.2: - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': {} - /@jridgewell/set-array@1.2.1: - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': {} - /@jridgewell/sourcemap-codec@1.5.0: - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.0': {} - /@jridgewell/trace-mapping@0.3.25: - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - /@next/env@15.1.0: - resolution: {integrity: sha512-UcCO481cROsqJuszPPXJnb7GGuLq617ve4xuAyyNG4VSSocJNtMU5Fsx+Lp6mlN8c7W58aZLc5y6D/2xNmaK+w==} - dev: false + '@napi-rs/wasm-runtime@0.2.8': + dependencies: + '@emnapi/core': 1.4.0 + '@emnapi/runtime': 1.4.0 + '@tybys/wasm-util': 0.9.0 + optional: true - /@next/eslint-plugin-next@15.1.0: - resolution: {integrity: sha512-+jPT0h+nelBT6HC9ZCHGc7DgGVy04cv4shYdAe6tKlEbjQUtwU3LzQhzbDHQyY2m6g39m6B0kOFVuLGBrxxbGg==} + '@next/env@15.1.0': {} + + '@next/eslint-plugin-next@15.1.0': dependencies: fast-glob: 3.3.1 - dev: true - /@next/swc-darwin-arm64@15.1.0: - resolution: {integrity: sha512-ZU8d7xxpX14uIaFC3nsr4L++5ZS/AkWDm1PzPO6gD9xWhFkOj2hzSbSIxoncsnlJXB1CbLOfGVN4Zk9tg83PUw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: false + '@next/swc-darwin-arm64@15.1.0': optional: true - /@next/swc-darwin-x64@15.1.0: - resolution: {integrity: sha512-DQ3RiUoW2XC9FcSM4ffpfndq1EsLV0fj0/UY33i7eklW5akPUCo6OX2qkcLXZ3jyPdo4sf2flwAED3AAq3Om2Q==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: false + '@next/swc-darwin-x64@15.1.0': optional: true - /@next/swc-linux-arm64-gnu@15.1.0: - resolution: {integrity: sha512-M+vhTovRS2F//LMx9KtxbkWk627l5Q7AqXWWWrfIzNIaUFiz2/NkOFkxCFyNyGACi5YbA8aekzCLtbDyfF/v5Q==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false + '@next/swc-linux-arm64-gnu@15.1.0': optional: true - /@next/swc-linux-arm64-musl@15.1.0: - resolution: {integrity: sha512-Qn6vOuwaTCx3pNwygpSGtdIu0TfS1KiaYLYXLH5zq1scoTXdwYfdZtwvJTpB1WrLgiQE2Ne2kt8MZok3HlFqmg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false + '@next/swc-linux-arm64-musl@15.1.0': optional: true - /@next/swc-linux-x64-gnu@15.1.0: - resolution: {integrity: sha512-yeNh9ofMqzOZ5yTOk+2rwncBzucc6a1lyqtg8xZv0rH5znyjxHOWsoUtSq4cUTeeBIiXXX51QOOe+VoCjdXJRw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false + '@next/swc-linux-x64-gnu@15.1.0': optional: true - /@next/swc-linux-x64-musl@15.1.0: - resolution: {integrity: sha512-t9IfNkHQs/uKgPoyEtU912MG6a1j7Had37cSUyLTKx9MnUpjj+ZDKw9OyqTI9OwIIv0wmkr1pkZy+3T5pxhJPg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false + '@next/swc-linux-x64-musl@15.1.0': optional: true - /@next/swc-win32-arm64-msvc@15.1.0: - resolution: {integrity: sha512-WEAoHyG14t5sTavZa1c6BnOIEukll9iqFRTavqRVPfYmfegOAd5MaZfXgOGG6kGo1RduyGdTHD4+YZQSdsNZXg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: false + '@next/swc-win32-arm64-msvc@15.1.0': optional: true - /@next/swc-win32-x64-msvc@15.1.0: - resolution: {integrity: sha512-J1YdKuJv9xcixzXR24Dv+4SaDKc2jj31IVUEMdO5xJivMTXuE6MAdIi4qPjSymHuFG8O5wbfWKnhJUcHHpj5CA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: false + '@next/swc-win32-x64-msvc@15.1.0': optional: true - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + '@nodelib/fs.stat@2.0.5': {} - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - /@nolyfill/is-core-module@1.0.39: - resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} - engines: {node: '>=12.4.0'} - dev: true + '@nolyfill/is-core-module@1.0.39': {} - /@panva/hkdf@1.2.1: - resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} - dev: false + '@panva/hkdf@1.2.1': {} - /@pkgjs/parseargs@0.11.0: - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - requiresBuild: true + '@pkgjs/parseargs@0.11.0': optional: true - /@radix-ui/number@1.1.0: - resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} - dev: false + '@radix-ui/number@1.1.0': {} - /@radix-ui/primitive@1.1.1: - resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} - dev: false + '@radix-ui/primitive@1.1.1': {} - /@radix-ui/react-arrow@1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false - - /@radix-ui/react-avatar@1.1.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-Paen00T4P8L8gd9bNsRMw7Cbaz85oxiv+hzomsRZgFm2byltPFDtfcoqlWJ8GyZlIBWgLssJlzLCnKU0G0302g==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false - - /@radix-ui/react-checkbox@1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-alert-dialog@1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-previous': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-size': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dialog': 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-collapsible@1.1.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-arrow@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-avatar@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-checkbox@1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-collection@1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false - - /@radix-ui/react-compose-refs@1.1.1(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - dev: false - - /@radix-ui/react-context@1.1.1(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - dev: false - - /@radix-ui/react-dialog@1.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-collapsible@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-collection@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) + + '@radix-ui/react-compose-refs@1.1.1(@types/react@19.1.0)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-context@1.1.1(@types/react@19.1.0)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 + + '@radix-ui/react-dialog@1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) aria-hidden: 1.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-direction@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-direction@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-menu': 2.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-menu': 2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-focus-guards@1.1.1(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-focus-guards@1.1.1(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-focus-scope@1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-hover-card@1.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-E4ozl35jq0VRlrdc4dhHrNSV0JqBb4Jy73WAhBEK7JoYnQ83ED5r0Rb/XdVKw89ReAJN38N492BAPBZQ57VmqQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-hover-card@1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-id@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-id@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-label@2.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-label@2.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-menu@2.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-menu@2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) aria-hidden: 1.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-popover@1.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-popover@1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) aria-hidden: 1.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-popper@1.2.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-popper@1.2.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-arrow': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-rect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-size': 1.1.0(@types/react@19.0.10)(react@19.0.0) + '@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-arrow': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-rect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.0(@types/react@19.1.0)(react@19.1.0) '@radix-ui/rect': 1.1.0 - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-portal@1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-portal@1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-presence@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-primitive@2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-primitive@2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-progress@1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-progress@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-roving-focus@1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-scroll-area@1.2.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-scroll-area@1.2.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-select@2.1.6(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-select@2.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-previous': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) aria-hidden: 1.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-separator@1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-separator@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-slot@1.1.2(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-slot@1.1.2(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-switch@1.1.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-switch@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-previous': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-size': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-tabs@1.1.3(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-tabs@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-direction': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-tooltip@1.1.8(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-tooltip@1.1.8(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-context': 1.1.1(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.1.2(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.1.0)(react@19.1.0) + '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-use-previous@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-use-previous@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-use-rect@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-use-rect@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: '@radix-ui/rect': 1.1.0 - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-use-size@1.1.0(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + '@radix-ui/react-use-size@1.1.0(@types/react@19.1.0)(react@19.1.0)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@types/react': 19.0.10 - react: 19.0.0 - dev: false + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.0 - /@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4)(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0) - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1(@types/react@19.1.0) - /@radix-ui/rect@1.1.0: - resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} - dev: false + '@radix-ui/rect@1.1.0': {} - /@react-google-maps/api@2.20.6(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-frxkSHWbd36ayyxrEVopSCDSgJUT1tVKXvQld2IyzU3UnDuqqNA3AZE4/fCdqQb2/zBQx3nrWnZB1wBXDcrjcw==} - peerDependencies: - react: ^16.8 || ^17 || ^18 || ^19 - react-dom: ^16.8 || ^17 || ^18 || ^19 + '@react-google-maps/api@2.20.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@googlemaps/js-api-loader': 1.16.8 '@googlemaps/markerclusterer': 2.5.3 @@ -1543,377 +3618,279 @@ packages: '@react-google-maps/marker-clusterer': 2.20.0 '@types/google.maps': 3.58.1 invariant: 2.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /@react-google-maps/infobox@2.20.0: - resolution: {integrity: sha512-03PJHjohhaVLkX6+NHhlr8CIlvUxWaXhryqDjyaZ8iIqqix/nV8GFdz9O3m5OsjtxtNho09F/15j14yV0nuyLQ==} - dev: false + '@react-google-maps/infobox@2.20.0': {} - /@react-google-maps/marker-clusterer@2.20.0: - resolution: {integrity: sha512-tieX9Va5w1yP88vMgfH1pHTacDQ9TgDTjox3tLlisKDXRQWdjw+QeVVghhf5XqqIxXHgPdcGwBvKY6UP+SIvLw==} - dev: false + '@react-google-maps/marker-clusterer@2.20.0': {} - /@react-oauth/google@0.12.1(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' + '@react-oauth/google@0.12.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /@rtsao/scc@1.1.0: - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - dev: true + '@rtsao/scc@1.1.0': {} - /@rushstack/eslint-patch@1.11.0: - resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} - dev: true + '@rushstack/eslint-patch@1.11.0': {} - /@standard-schema/utils@0.3.0: - resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} - dev: false + '@standard-schema/utils@0.3.0': {} - /@swc/counter@0.1.3: - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - dev: false + '@swc/counter@0.1.3': {} - /@swc/helpers@0.5.15: - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 - dev: false - /@tailwindcss/typography@0.5.16(tailwindcss@3.4.17): - resolution: {integrity: sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==} - peerDependencies: - tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + '@tailwindcss/typography@0.5.16(tailwindcss@3.4.17)': dependencies: lodash.castarray: 4.4.0 lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 postcss-selector-parser: 6.0.10 tailwindcss: 3.4.17 - dev: false - /@tanstack/query-core@5.67.3: - resolution: {integrity: sha512-pq76ObpjcaspAW4OmCbpXLF6BCZP2Zr/J5ztnyizXhSlNe7fIUp0QKZsd0JMkw9aDa+vxDX/OY7N+hjNY/dCGg==} - dev: false + '@tanstack/query-core@5.71.5': {} - /@tanstack/react-query@5.67.3(react@19.0.0): - resolution: {integrity: sha512-u/n2HsQeH1vpZIOzB/w2lqKlXUDUKo6BxTdGXSMvNzIq5MHYFckRMVuFABp+QB7RN8LFXWV6X1/oSkuDq+MPIA==} - peerDependencies: - react: ^18 || ^19 + '@tanstack/react-query@5.71.5(react@19.1.0)': dependencies: - '@tanstack/query-core': 5.67.3 - react: 19.0.0 - dev: false + '@tanstack/query-core': 5.71.5 + react: 19.1.0 - /@tanstack/react-table@8.21.2(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==} - engines: {node: '>=12'} - peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' + '@tanstack/react-table@8.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@tanstack/table-core': 8.21.2 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /@tanstack/table-core@8.21.2: - resolution: {integrity: sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==} - engines: {node: '>=12'} - dev: false + '@tanstack/table-core@8.21.2': {} - /@types/d3-array@3.2.1: - resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} - dev: false + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + optional: true - /@types/d3-color@3.1.3: - resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} - dev: false + '@types/d3-array@3.2.1': {} - /@types/d3-ease@3.0.2: - resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} - dev: false + '@types/d3-color@3.1.3': {} - /@types/d3-interpolate@3.0.4: - resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + '@types/d3-ease@3.0.2': {} + + '@types/d3-interpolate@3.0.4': dependencies: '@types/d3-color': 3.1.3 - dev: false - /@types/d3-path@3.1.1: - resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} - dev: false + '@types/d3-path@3.1.1': {} - /@types/d3-scale@4.0.9: - resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + '@types/d3-scale@4.0.9': dependencies: '@types/d3-time': 3.0.4 - dev: false - /@types/d3-shape@3.1.7: - resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + '@types/d3-shape@3.1.7': dependencies: '@types/d3-path': 3.1.1 - dev: false - /@types/d3-time@3.0.4: - resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} - dev: false + '@types/d3-time@3.0.4': {} - /@types/d3-timer@3.0.2: - resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} - dev: false + '@types/d3-timer@3.0.2': {} - /@types/estree@1.0.6: - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - dev: true + '@types/estree@1.0.7': {} - /@types/google.maps@3.58.1: - resolution: {integrity: sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==} - dev: false + '@types/google.maps@3.58.1': {} - /@types/json-schema@7.0.15: - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - dev: true + '@types/json-schema@7.0.15': {} - /@types/json5@0.0.29: - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - dev: true + '@types/json5@0.0.29': {} - /@types/node@20.17.24: - resolution: {integrity: sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==} + '@types/node@20.17.30': dependencies: undici-types: 6.19.8 - dev: true - /@types/react-dom@19.0.4(@types/react@19.0.10): - resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==} - peerDependencies: - '@types/react': ^19.0.0 + '@types/react-dom@19.1.1(@types/react@19.1.0)': dependencies: - '@types/react': 19.0.10 + '@types/react': 19.1.0 - /@types/react@19.0.10: - resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==} + '@types/react@19.1.0': dependencies: csstype: 3.1.3 - /@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1)(eslint@9.22.0)(typescript@5.8.2): - resolution: {integrity: sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2))(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/type-utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.26.1 - eslint: 9.22.0 + '@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/type-utils': 8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) + '@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 8.29.0 + eslint: 9.23.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 2.0.1(typescript@5.8.2) + ts-api-utils: 2.1.0(typescript@5.8.2) typescript: 5.8.2 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2): - resolution: {integrity: sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2)': dependencies: - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.26.1 + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 8.29.0 debug: 4.4.0 - eslint: 9.22.0 + eslint: 9.23.0(jiti@1.21.7) typescript: 5.8.2 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/scope-manager@8.26.1: - resolution: {integrity: sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.29.0': dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 - dev: true + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/visitor-keys': 8.29.0 - /@typescript-eslint/type-utils@8.26.1(eslint@9.22.0)(typescript@5.8.2): - resolution: {integrity: sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/type-utils@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2)': dependencies: - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2) + '@typescript-eslint/utils': 8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) debug: 4.4.0 - eslint: 9.22.0 - ts-api-utils: 2.0.1(typescript@5.8.2) + eslint: 9.23.0(jiti@1.21.7) + ts-api-utils: 2.1.0(typescript@5.8.2) typescript: 5.8.2 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/types@8.26.1: - resolution: {integrity: sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - dev: true + '@typescript-eslint/types@8.29.0': {} - /@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.2): - resolution: {integrity: sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/typescript-estree@8.29.0(typescript@5.8.2)': dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/visitor-keys': 8.29.0 debug: 4.4.0 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.8.2) + ts-api-utils: 2.1.0(typescript@5.8.2) typescript: 5.8.2 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/utils@8.26.1(eslint@9.22.0)(typescript@5.8.2): - resolution: {integrity: sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' + '@typescript-eslint/utils@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2)': dependencies: - '@eslint-community/eslint-utils': 4.5.0(eslint@9.22.0) - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) - eslint: 9.22.0 + '@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.2) + eslint: 9.23.0(jiti@1.21.7) typescript: 5.8.2 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/visitor-keys@8.26.1: - resolution: {integrity: sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.29.0': dependencies: - '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/types': 8.29.0 eslint-visitor-keys: 4.2.0 - dev: true - /@vis.gl/react-google-maps@1.5.2(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-0Ypmde7M73GgV4TgcaUTNKXsbcXWToPVuawMNrVg7htXmhpEfLARHwhtmP6N1da3od195ZKC8ShXzC6Vm+zYHQ==} - peerDependencies: - react: '>=16.8.0 || ^19.0 || ^19.0.0-rc' - react-dom: '>=16.8.0 || ^19.0 || ^19.0.0-rc' + '@unrs/resolver-binding-darwin-arm64@1.3.3': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.3.3': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.3.3': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.3.3': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.3.3': + dependencies: + '@napi-rs/wasm-runtime': 0.2.8 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.3.3': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.3.3': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.3.3': + optional: true + + '@vis.gl/react-google-maps@1.5.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@types/google.maps': 3.58.1 fast-deep-equal: 3.1.3 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /acorn-jsx@5.3.2(acorn@8.14.1): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 - dev: true - /acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true + acorn@8.14.1: {} - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - dev: true - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + ansi-regex@5.0.1: {} - /ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} + ansi-regex@6.1.0: {} - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - /ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} + ansi-styles@6.2.1: {} - /any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + any-promise@1.3.0: {} - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - /arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + arg@5.0.2: {} - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true + argparse@2.0.1: {} - /aria-hidden@1.2.4: - resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} - engines: {node: '>=10'} + aria-hidden@1.2.4: dependencies: tslib: 2.8.1 - dev: false - /aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - dev: true + aria-query@5.3.2: {} - /array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} + array-buffer-byte-length@1.0.2: dependencies: call-bound: 1.0.4 is-array-buffer: 3.0.5 - dev: true - /array-includes@3.1.8: - resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} - engines: {node: '>= 0.4'} + array-includes@3.1.8: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 @@ -1921,11 +3898,8 @@ packages: es-object-atoms: 1.1.1 get-intrinsic: 1.3.0 is-string: 1.1.1 - dev: true - /array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} + array.prototype.findlast@1.2.5: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 @@ -1933,54 +3907,40 @@ packages: es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 - dev: true - /array.prototype.findlastindex@1.2.5: - resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} - engines: {node: '>= 0.4'} + array.prototype.findlastindex@1.2.6: dependencies: call-bind: 1.0.8 + call-bound: 1.0.4 define-properties: 1.2.1 es-abstract: 1.23.9 es-errors: 1.3.0 es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 - dev: true - /array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} + array.prototype.flat@1.3.3: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 es-shim-unscopables: 1.1.0 - dev: true - /array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} + array.prototype.flatmap@1.3.3: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 es-shim-unscopables: 1.1.0 - dev: true - /array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} + array.prototype.tosorted@1.1.4: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 es-errors: 1.3.0 es-shim-unscopables: 1.1.0 - dev: true - /arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} + arraybuffer.prototype.slice@1.0.4: dependencies: array-buffer-byte-length: 1.0.2 call-bind: 1.0.8 @@ -1989,129 +3949,79 @@ packages: es-errors: 1.3.0 get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 - dev: true - /ast-types-flow@0.0.8: - resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - dev: true + ast-types-flow@0.0.8: {} - /async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - dev: true + async-function@1.0.0: {} - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false + asynckit@0.4.0: {} - /available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 - dev: true - /axe-core@4.10.3: - resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} - engines: {node: '>=4'} - dev: true + axe-core@4.10.3: {} - /axios@1.8.3: - resolution: {integrity: sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==} + axios@1.8.4: dependencies: follow-redirects: 1.15.9 form-data: 4.0.2 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - dev: false - /axobject-query@4.1.0: - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} - engines: {node: '>= 0.4'} - dev: true + axobject-query@4.1.0: {} - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@1.0.2: {} - /binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} + binary-extensions@2.3.0: {} - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - dev: true - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 - /braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + braces@3.0.3: dependencies: fill-range: 7.1.1 - /busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} + busboy@1.6.0: dependencies: streamsearch: 1.1.0 - dev: false - /call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 - /call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} + call-bind@1.0.8: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 get-intrinsic: 1.3.0 set-function-length: 1.2.2 - dev: true - /call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + call-bound@1.0.4: dependencies: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - dev: true - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true + callsites@3.1.0: {} - /camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} + camelcase-css@2.0.1: {} - /caniuse-lite@1.0.30001703: - resolution: {integrity: sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==} - dev: false + caniuse-lite@1.0.30001710: {} - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: true - /chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 braces: 3.0.3 @@ -2123,304 +4033,169 @@ packages: optionalDependencies: fsevents: 2.3.3 - /class-variance-authority@0.7.1: - resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 - dev: false - /client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - dev: false + client-only@0.0.1: {} - /clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - dev: false + clsx@2.1.1: {} - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + color-convert@2.0.1: dependencies: color-name: 1.1.4 - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-name@1.1.4: {} - /color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - requiresBuild: true + color-string@1.9.1: dependencies: color-name: 1.1.4 simple-swizzle: 0.2.2 - dev: false optional: true - /color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - requiresBuild: true + color@4.2.3: dependencies: color-convert: 2.0.1 color-string: 1.9.1 - dev: false optional: true - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - dev: false - /commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} + commander@4.1.1: {} - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true + concat-map@0.0.1: {} - /cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - dev: false + cookie@0.7.2: {} - /cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - /cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true + cssesc@3.0.0: {} - /csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.1.3: {} - /d3-array@3.2.4: - resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} - engines: {node: '>=12'} + d3-array@3.2.4: dependencies: internmap: 2.0.3 - dev: false - /d3-color@3.1.0: - resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} - engines: {node: '>=12'} - dev: false + d3-color@3.1.0: {} - /d3-ease@3.0.1: - resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} - engines: {node: '>=12'} - dev: false + d3-ease@3.0.1: {} - /d3-format@3.1.0: - resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} - engines: {node: '>=12'} - dev: false + d3-format@3.1.0: {} - /d3-interpolate@3.0.1: - resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} - engines: {node: '>=12'} + d3-interpolate@3.0.1: dependencies: d3-color: 3.1.0 - dev: false - /d3-path@3.1.0: - resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} - engines: {node: '>=12'} - dev: false + d3-path@3.1.0: {} - /d3-scale@4.0.2: - resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} - engines: {node: '>=12'} + d3-scale@4.0.2: dependencies: d3-array: 3.2.4 d3-format: 3.1.0 d3-interpolate: 3.0.1 d3-time: 3.1.0 d3-time-format: 4.1.0 - dev: false - /d3-shape@3.2.0: - resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} - engines: {node: '>=12'} + d3-shape@3.2.0: dependencies: d3-path: 3.1.0 - dev: false - /d3-time-format@4.1.0: - resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} - engines: {node: '>=12'} + d3-time-format@4.1.0: dependencies: d3-time: 3.1.0 - dev: false - /d3-time@3.1.0: - resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} - engines: {node: '>=12'} + d3-time@3.1.0: dependencies: d3-array: 3.2.4 - dev: false - /d3-timer@3.0.1: - resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} - engines: {node: '>=12'} - dev: false + d3-timer@3.0.1: {} - /damerau-levenshtein@1.0.8: - resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - dev: true + damerau-levenshtein@1.0.8: {} - /data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} + data-view-buffer@1.0.2: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 - dev: true - /data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} + data-view-byte-length@1.0.2: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 - dev: true - /data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} + data-view-byte-offset@1.0.1: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 - dev: true - /date-fns@4.1.0: - resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} - dev: false + date-fns@4.1.0: {} - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + debug@3.2.7: dependencies: ms: 2.1.3 - dev: true - /debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + debug@4.4.0: dependencies: ms: 2.1.3 - dev: true - /decimal.js-light@2.5.1: - resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} - dev: false + decimal.js-light@2.5.1: {} - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true + deep-is@0.1.4: {} - /define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 es-errors: 1.3.0 gopd: 1.2.0 - dev: true - /define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 has-property-descriptors: 1.0.2 object-keys: 1.1.1 - dev: true - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false + delayed-stream@1.0.0: {} - /detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} - engines: {node: '>=8'} - requiresBuild: true - dev: false + detect-libc@2.0.3: optional: true - /detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - dev: false + detect-node-es@1.1.0: {} - /didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + didyoumean@1.2.2: {} - /dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dlv@1.1.3: {} - /doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} + doctrine@2.1.0: dependencies: esutils: 2.0.3 - dev: true - /dom-helpers@5.2.1: - resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dom-helpers@5.2.1: dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 csstype: 3.1.3 - dev: false - /dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 es-errors: 1.3.0 gopd: 1.2.0 - /eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + eastasianwidth@0.2.0: {} - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@8.0.0: {} - /emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + emoji-regex@9.2.2: {} - /enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} - engines: {node: '>=10.13.0'} - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.1 - dev: true - - /es-abstract@1.23.9: - resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} - engines: {node: '>= 0.4'} + es-abstract@1.23.9: dependencies: array-buffer-byte-length: 1.0.2 arraybuffer.prototype.slice: 1.0.4 @@ -2473,19 +4248,12 @@ packages: typed-array-length: 1.0.7 unbox-primitive: 1.1.0 which-typed-array: 1.1.19 - dev: true - /es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} + es-define-property@1.0.1: {} - /es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + es-errors@1.3.0: {} - /es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} - engines: {node: '>= 0.4'} + es-iterator-helpers@1.2.1: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 @@ -2503,158 +4271,96 @@ packages: internal-slot: 1.1.0 iterator.prototype: 1.1.5 safe-array-concat: 1.1.3 - dev: true - /es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 - /es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: dependencies: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 hasown: 2.0.2 - /es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} + es-shim-unscopables@1.1.0: dependencies: hasown: 2.0.2 - dev: true - /es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} + es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 is-date-object: 1.1.0 is-symbol: 1.1.1 - dev: true - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true + escape-string-regexp@4.0.0: {} - /eslint-config-next@15.1.0(eslint@9.22.0)(typescript@5.8.2): - resolution: {integrity: sha512-gADO+nKVseGso3DtOrYX9H7TxB/MuX7AUYhMlvQMqLYvUWu4HrOQuU7cC1HW74tHIqkAvXdwgAz3TCbczzSEXw==} - peerDependencies: - eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 - typescript: '>=3.3.1' - peerDependenciesMeta: - typescript: - optional: true + eslint-config-next@15.1.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2): dependencies: '@next/eslint-plugin-next': 15.1.0 '@rushstack/eslint-patch': 1.11.0 - '@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1)(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - eslint: 9.22.0 + '@typescript-eslint/eslint-plugin': 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2))(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) + '@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) + eslint: 9.23.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.8.5(eslint-plugin-import@2.31.0)(eslint@9.22.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.26.1)(eslint-import-resolver-typescript@3.8.5)(eslint@9.22.0) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.22.0) - eslint-plugin-react: 7.37.4(eslint@9.22.0) - eslint-plugin-react-hooks: 5.2.0(eslint@9.22.0) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@1.21.7)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@1.21.7)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.23.0(jiti@1.21.7)) + eslint-plugin-react: 7.37.5(eslint@9.23.0(jiti@1.21.7)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.23.0(jiti@1.21.7)) + optionalDependencies: typescript: 5.8.2 transitivePeerDependencies: - eslint-import-resolver-webpack - eslint-plugin-import-x - supports-color - dev: true - /eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 is-core-module: 2.16.1 resolve: 1.22.10 transitivePeerDependencies: - supports-color - dev: true - /eslint-import-resolver-typescript@3.8.5(eslint-plugin-import@2.31.0)(eslint@9.22.0): - resolution: {integrity: sha512-0ZRnzOqKc7TRm85w6REOUkVLHevN6nWd/xZsmKhSD/dcDktoxQaQAg59e5EK/QEsGFf7o5JSpE6qTwCEz0WjTw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - eslint-plugin-import-x: '*' - peerDependenciesMeta: - eslint-plugin-import: - optional: true - eslint-plugin-import-x: - optional: true + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@1.21.7)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 - enhanced-resolve: 5.18.1 - eslint: 9.22.0 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.26.1)(eslint-import-resolver-typescript@3.8.5)(eslint@9.22.0) + eslint: 9.23.0(jiti@1.21.7) get-tsconfig: 4.10.0 - is-bun-module: 1.3.0 - stable-hash: 0.0.4 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 tinyglobby: 0.2.12 + unrs-resolver: 1.3.3 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - dev: true - /eslint-module-utils@2.12.0(@typescript-eslint/parser@8.26.1)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.5)(eslint@9.22.0): - resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@1.21.7)): dependencies: - '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) debug: 3.2.7 - eslint: 9.22.0 + optionalDependencies: + '@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) + eslint: 9.23.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.8.5(eslint-plugin-import@2.31.0)(eslint@9.22.0) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - dev: true - /eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.26.1)(eslint-import-resolver-typescript@3.8.5)(eslint@9.22.0): - resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@1.21.7)): dependencies: '@rtsao/scc': 1.1.0 - '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) array-includes: 3.1.8 - array.prototype.findlastindex: 1.2.5 + array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.22.0 + eslint: 9.23.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.26.1)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.5)(eslint@9.22.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -2665,17 +4371,14 @@ packages: semver: 6.3.1 string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.29.0(eslint@9.23.0(jiti@1.21.7))(typescript@5.8.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - dev: true - /eslint-plugin-jsx-a11y@6.10.2(eslint@9.22.0): - resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} - engines: {node: '>=4.0'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + eslint-plugin-jsx-a11y@6.10.2(eslint@9.23.0(jiti@1.21.7)): dependencies: aria-query: 5.3.2 array-includes: 3.1.8 @@ -2685,7 +4388,7 @@ packages: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.22.0 + eslint: 9.23.0(jiti@1.21.7) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -2693,22 +4396,12 @@ packages: object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - dev: true - /eslint-plugin-react-hooks@5.2.0(eslint@9.22.0): - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + eslint-plugin-react-hooks@5.2.0(eslint@9.23.0(jiti@1.21.7)): dependencies: - eslint: 9.22.0 - dev: true + eslint: 9.23.0(jiti@1.21.7) - /eslint-plugin-react@7.37.4(eslint@9.22.0): - resolution: {integrity: sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + eslint-plugin-react@7.37.5(eslint@9.23.0(jiti@1.21.7)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -2716,12 +4409,12 @@ packages: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.2.1 - eslint: 9.22.0 + eslint: 9.23.0(jiti@1.21.7) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 - object.entries: 1.1.8 + object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 prop-types: 15.8.1 @@ -2729,48 +4422,30 @@ packages: semver: 6.3.1 string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - dev: true - /eslint-scope@8.3.0: - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@8.3.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 - dev: true - /eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + eslint-visitor-keys@3.4.3: {} - /eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - dev: true + eslint-visitor-keys@4.2.0: {} - /eslint@9.22.0: - resolution: {integrity: sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true + eslint@9.23.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.5.0(eslint@9.22.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.19.2 - '@eslint/config-helpers': 0.1.0 + '@eslint/config-helpers': 0.2.1 '@eslint/core': 0.12.0 - '@eslint/eslintrc': 3.3.0 - '@eslint/js': 9.22.0 - '@eslint/plugin-kit': 0.2.7 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.23.0 + '@eslint/plugin-kit': 0.2.8 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.2 - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 @@ -2794,69 +4469,36 @@ packages: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 1.21.7 transitivePeerDependencies: - supports-color - dev: true - /espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@10.3.0: dependencies: acorn: 8.14.1 acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 - dev: true - /esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} + esquery@1.6.0: dependencies: estraverse: 5.3.0 - dev: true - /esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 - dev: true - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true + estraverse@5.3.0: {} - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true + esutils@2.0.3: {} - /eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: false + eventemitter3@4.0.7: {} - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-deep-equal@3.1.3: {} - /fast-equals@5.2.2: - resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==} - engines: {node: '>=6.0.0'} - dev: false + fast-equals@5.2.2: {} - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - dev: true - - /fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} + fast-glob@3.3.1: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 @@ -2864,131 +4506,79 @@ packages: merge2: 1.4.1 micromatch: 4.0.8 - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true + fast-json-stable-stringify@2.1.0: {} - /fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: dependencies: reusify: 1.1.0 - /fdir@6.4.3(picomatch@4.0.2): - resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - dependencies: + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: picomatch: 4.0.2 - dev: true - /file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 - dev: true - /fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + find-up@5.0.0: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - dev: true - /flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} + flat-cache@4.0.1: dependencies: flatted: 3.3.3 keyv: 4.5.4 - dev: true - /flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - dev: true + flatted@3.3.3: {} - /follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false + follow-redirects@1.15.9: {} - /for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} + for-each@0.3.5: dependencies: is-callable: 1.2.7 - dev: true - /foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 - /form-data@4.0.2: - resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} - engines: {node: '>= 6'} + form-data@4.0.2: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 mime-types: 2.1.35 - dev: false - /framer-motion@12.5.0(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-buPlioFbH9/W7rDzYh1C09AuZHAk2D1xTA1BlounJ2Rb9aRg84OXexP0GLd+R83v0khURdMX7b5MKnGTaSg5iA==} - peerDependencies: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@emotion/is-prop-valid': - optional: true - react: - optional: true - react-dom: - optional: true + framer-motion@12.6.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - motion-dom: 12.5.0 - motion-utils: 12.5.0 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + motion-dom: 12.6.3 + motion-utils: 12.6.3 tslib: 2.8.1 - dev: false + optionalDependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true + fsevents@2.3.3: optional: true - /function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function-bind@1.1.2: {} - /function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} + function.prototype.name@1.1.8: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 @@ -2996,15 +4586,10 @@ packages: functions-have-names: 1.2.3 hasown: 2.0.2 is-callable: 1.2.7 - dev: true - /functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true + functions-have-names@1.2.3: {} - /get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 @@ -3017,48 +4602,32 @@ packages: hasown: 2.0.2 math-intrinsics: 1.1.0 - /get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} - dev: false + get-nonce@1.0.1: {} - /get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 - /get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} + get-symbol-description@1.1.0: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 get-intrinsic: 1.3.0 - dev: true - /get-tsconfig@4.10.0: - resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + get-tsconfig@4.10.0: dependencies: resolve-pkg-maps: 1.0.0 - dev: true - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + glob-parent@6.0.2: dependencies: is-glob: 4.0.3 - /glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true + glob@10.4.5: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 @@ -3067,313 +4636,183 @@ packages: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - /globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - dev: true + globals@14.0.0: {} - /globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 gopd: 1.2.0 - dev: true - /gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} + gopd@1.2.0: {} - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true + graphemer@1.4.0: {} - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - dev: true + has-bigints@1.1.0: {} - /has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - dev: true + has-flag@4.0.0: {} - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - /has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.1 - dev: true - /has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} + has-proto@1.2.0: dependencies: dunder-proto: 1.0.1 - dev: true - /has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + has-symbols@1.1.0: {} - /has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: dependencies: has-symbols: 1.1.0 - /hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + hasown@2.0.2: dependencies: function-bind: 1.1.2 - /ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - dev: true + ignore@5.3.2: {} - /import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true + imurmurhash@0.1.4: {} - /internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.1.0 - dev: true - /internmap@2.0.3: - resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} - engines: {node: '>=12'} - dev: false + internmap@2.0.3: {} - /invariant@2.2.4: - resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + invariant@2.2.4: dependencies: loose-envify: 1.4.0 - dev: false - /is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 get-intrinsic: 1.3.0 - dev: true - /is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - requiresBuild: true - dev: false + is-arrayish@0.3.2: optional: true - /is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} + is-async-function@2.1.1: dependencies: async-function: 1.0.0 call-bound: 1.0.4 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 - dev: true - /is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} + is-bigint@1.1.0: dependencies: has-bigints: 1.1.0 - dev: true - /is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 - /is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} + is-boolean-object@1.2.2: dependencies: call-bound: 1.0.4 has-tostringtag: 1.0.2 - dev: true - /is-bun-module@1.3.0: - resolution: {integrity: sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==} + is-bun-module@2.0.0: dependencies: semver: 7.7.1 - dev: true - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true + is-callable@1.2.7: {} - /is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} + is-core-module@2.16.1: dependencies: hasown: 2.0.2 - /is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} + is-data-view@1.0.2: dependencies: call-bound: 1.0.4 get-intrinsic: 1.3.0 is-typed-array: 1.1.15 - dev: true - /is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} + is-date-object@1.1.0: dependencies: call-bound: 1.0.4 has-tostringtag: 1.0.2 - dev: true - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + is-extglob@2.1.1: {} - /is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} + is-finalizationregistry@1.1.1: dependencies: call-bound: 1.0.4 - dev: true - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + is-fullwidth-code-point@3.0.0: {} - /is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} - engines: {node: '>= 0.4'} + is-generator-function@1.1.0: dependencies: call-bound: 1.0.4 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 - dev: true - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - /is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - dev: true + is-map@2.0.3: {} - /is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} + is-number-object@1.1.1: dependencies: call-bound: 1.0.4 has-tostringtag: 1.0.2 - dev: true - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + is-number@7.0.0: {} - /is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} + is-regex@1.2.1: dependencies: call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 hasown: 2.0.2 - dev: true - /is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - dev: true + is-set@2.0.3: {} - /is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} + is-shared-array-buffer@1.0.4: dependencies: call-bound: 1.0.4 - dev: true - /is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} + is-string@1.1.1: dependencies: call-bound: 1.0.4 has-tostringtag: 1.0.2 - dev: true - /is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} + is-symbol@1.1.1: dependencies: call-bound: 1.0.4 has-symbols: 1.1.0 safe-regex-test: 1.1.0 - dev: true - /is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} + is-typed-array@1.1.15: dependencies: which-typed-array: 1.1.19 - dev: true - /is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - dev: true + is-weakmap@2.0.2: {} - /is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} + is-weakref@1.1.1: dependencies: call-bound: 1.0.4 - dev: true - /is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} + is-weakset@2.0.4: dependencies: call-bound: 1.0.4 get-intrinsic: 1.3.0 - dev: true - /isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: true + isarray@2.0.5: {} - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@2.0.0: {} - /iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 es-object-atoms: 1.1.1 @@ -3381,294 +4820,165 @@ packages: get-proto: 1.0.1 has-symbols: 1.1.0 set-function-name: 2.0.2 - dev: true - /jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 - /jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true + jiti@1.21.7: {} - /jose@4.15.9: - resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} - dev: false + jose@4.15.9: {} - /js-cookie@3.0.5: - resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} - engines: {node: '>=14'} - dev: false + js-cookie@3.0.5: {} - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@4.0.0: {} - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + js-yaml@4.1.0: dependencies: argparse: 2.0.1 - dev: true - /json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - dev: true + json-buffer@3.0.1: {} - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true + json-schema-traverse@0.4.1: {} - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true + json-stable-stringify-without-jsonify@1.0.1: {} - /json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true + json5@1.0.2: dependencies: minimist: 1.2.8 - dev: true - /jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 array.prototype.flat: 1.3.3 object.assign: 4.1.7 object.values: 1.2.1 - dev: true - /kdbush@4.0.2: - resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==} - dev: false + kdbush@4.0.2: {} - /keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 - dev: true - /language-subtag-registry@0.3.23: - resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} - dev: true + language-subtag-registry@0.3.23: {} - /language-tags@1.0.9: - resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} - engines: {node: '>=0.10'} + language-tags@1.0.9: dependencies: language-subtag-registry: 0.3.23 - dev: true - /levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true - /lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} + lilconfig@3.1.3: {} - /lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lines-and-columns@1.2.4: {} - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 - dev: true - /lodash.castarray@4.4.0: - resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} - dev: false + lodash.castarray@4.4.0: {} - /lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - dev: false + lodash.isplainobject@4.0.6: {} - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.merge@4.6.2: {} - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false + lodash@4.17.21: {} - /loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 - /lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@10.4.3: {} - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + lru-cache@6.0.0: dependencies: yallist: 4.0.0 - dev: false - /lucide-react@0.475.0(react@19.0.0): - resolution: {integrity: sha512-NJzvVu1HwFVeZ+Gwq2q00KygM1aBhy/ZrhY9FsAgJtpB+E4R7uxRk9M2iKvHa6/vNxZydIB59htha4c2vvwvVg==} - peerDependencies: - react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lucide-react@0.475.0(react@19.1.0): dependencies: - react: 19.0.0 - dev: false + react: 19.1.0 - /math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} + math-intrinsics@1.1.0: {} - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + merge2@1.4.1: {} - /micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false + mime-db@1.52.0: {} - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 - dev: false - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - dev: true - /minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true + minimist@1.2.8: {} - /minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.2: {} - /motion-dom@12.5.0: - resolution: {integrity: sha512-uH2PETDh7m+Hjd1UQQ56yHqwn83SAwNjimNPE/kC+Kds0t4Yh7+29rfo5wezVFpPOv57U4IuWved5d1x0kNhbQ==} + motion-dom@12.6.3: dependencies: - motion-utils: 12.5.0 - dev: false + motion-utils: 12.6.3 - /motion-utils@12.5.0: - resolution: {integrity: sha512-+hFFzvimn0sBMP9iPxBa9OtRX35ZQ3py0UHnb8U29VD+d8lQ8zH3dTygJWqK7av2v6yhg7scj9iZuvTS0f4+SA==} - dev: false + motion-utils@12.6.3: {} - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true + ms@2.1.3: {} - /mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + mz@2.7.0: dependencies: any-promise: 1.3.0 object-assign: 4.1.1 thenify-all: 1.6.0 - /nanoid@3.3.9: - resolution: {integrity: sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true + nanoid@3.3.11: {} - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true + natural-compare@1.4.0: {} - /next-auth@4.24.11(next@15.1.0)(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw==} - peerDependencies: - '@auth/core': 0.34.2 - next: ^12.2.5 || ^13 || ^14 || ^15 - nodemailer: ^6.6.5 - react: ^17.0.2 || ^18 || ^19 - react-dom: ^17.0.2 || ^18 || ^19 - peerDependenciesMeta: - '@auth/core': - optional: true - nodemailer: - optional: true + next-auth@4.24.11(next@15.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 '@panva/hkdf': 1.2.1 cookie: 0.7.2 jose: 4.15.9 - next: 15.1.0(react-dom@19.0.0)(react@19.0.0) + next: 15.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) oauth: 0.9.15 openid-client: 5.7.1 preact: 10.26.4 preact-render-to-string: 5.2.6(preact@10.26.4) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) uuid: 8.3.2 - dev: false - /next-themes@0.4.6(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} - peerDependencies: - react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /next@15.1.0(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-QKhzt6Y8rgLNlj30izdMbxAwjHMFANnLwDwZ+WQh5sMhyt4lEBqDK9QpvWHtIM4rINKPoJ8aiRZKg5ULSybVHw==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.41.2 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true + next@15.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@next/env': 15.1.0 '@swc/counter': 0.1.3 '@swc/helpers': 0.5.15 busboy: 1.6.0 - caniuse-lite: 1.0.30001703 + caniuse-lite: 1.0.30001710 postcss: 8.4.31 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - styled-jsx: 5.1.6(react@19.0.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(react@19.1.0) optionalDependencies: '@next/swc-darwin-arm64': 15.1.0 '@next/swc-darwin-x64': 15.1.0 @@ -3682,42 +4992,22 @@ packages: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - dev: false - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + normalize-path@3.0.0: {} - /oauth@0.9.15: - resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} - dev: false + oauth@0.9.15: {} - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} + object-assign@4.1.1: {} - /object-hash@2.2.0: - resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} - engines: {node: '>= 6'} - dev: false + object-hash@2.2.0: {} - /object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} + object-hash@3.0.0: {} - /object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - dev: true + object-inspect@1.13.4: {} - /object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true + object-keys@1.1.1: {} - /object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} + object.assign@4.1.7: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 @@ -3725,63 +5015,44 @@ packages: es-object-atoms: 1.1.1 has-symbols: 1.1.0 object-keys: 1.1.1 - dev: true - /object.entries@1.1.8: - resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - dev: true - - /object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-object-atoms: 1.1.1 - dev: true - - /object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - dev: true - - /object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} + object.entries@1.1.9: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 - dev: true - /oidc-token-hash@5.1.0: - resolution: {integrity: sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA==} - engines: {node: ^10.13.0 || >=12.0.0} - dev: false + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 - /openid-client@5.7.1: - resolution: {integrity: sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==} + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + oidc-token-hash@5.1.0: {} + + openid-client@5.7.1: dependencies: jose: 4.15.9 lru-cache: 6.0.0 object-hash: 2.2.0 oidc-token-hash: 5.1.0 - dev: false - /optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} + optionator@0.9.4: dependencies: deep-is: 0.1.4 fast-levenshtein: 2.0.6 @@ -3789,371 +5060,215 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 word-wrap: 1.2.5 - dev: true - /own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} + own-keys@1.0.1: dependencies: get-intrinsic: 1.3.0 object-keys: 1.1.1 safe-push-apply: 1.0.0 - dev: true - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - dev: true - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + p-locate@5.0.0: dependencies: p-limit: 3.1.0 - dev: true - /package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-json-from-dist@1.0.1: {} - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + parent-module@1.0.1: dependencies: callsites: 3.1.0 - dev: true - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true + path-exists@4.0.0: {} - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + path-key@3.1.1: {} - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-parse@1.0.7: {} - /path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} + path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 minipass: 7.1.2 - /picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picocolors@1.1.1: {} - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + picomatch@2.3.1: {} - /picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} - engines: {node: '>=12'} - dev: true + picomatch@4.0.2: {} - /pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} + pify@2.3.0: {} - /pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} + pirates@4.0.7: {} - /possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - dev: true + possible-typed-array-names@1.1.0: {} - /postcss-import@15.1.0(postcss@8.5.3): - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 + postcss-import@15.1.0(postcss@8.5.3): dependencies: postcss: 8.5.3 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.10 - /postcss-js@4.0.1(postcss@8.5.3): - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 + postcss-js@4.0.1(postcss@8.5.3): dependencies: camelcase-css: 2.0.1 postcss: 8.5.3 - /postcss-load-config@4.0.2(postcss@8.5.3): - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true + postcss-load-config@4.0.2(postcss@8.5.3): dependencies: lilconfig: 3.1.3 + yaml: 2.7.1 + optionalDependencies: postcss: 8.5.3 - yaml: 2.7.0 - /postcss-nested@6.2.0(postcss@8.5.3): - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 + postcss-nested@6.2.0(postcss@8.5.3): dependencies: postcss: 8.5.3 postcss-selector-parser: 6.1.2 - /postcss-selector-parser@6.0.10: - resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} - engines: {node: '>=4'} - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - dev: false - - /postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} + postcss-selector-parser@6.0.10: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - /postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - /postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} + postcss-selector-parser@6.1.2: dependencies: - nanoid: 3.3.9 - picocolors: 1.1.1 - source-map-js: 1.2.1 - dev: false + cssesc: 3.0.0 + util-deprecate: 1.0.2 - /postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} - engines: {node: ^10 || ^12 || >=14} + postcss-value-parser@4.2.0: {} + + postcss@8.4.31: dependencies: - nanoid: 3.3.9 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 - /preact-render-to-string@5.2.6(preact@10.26.4): - resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} - peerDependencies: - preact: '>=10' + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + preact-render-to-string@5.2.6(preact@10.26.4): dependencies: preact: 10.26.4 pretty-format: 3.8.0 - dev: false - /preact@10.26.4: - resolution: {integrity: sha512-KJhO7LBFTjP71d83trW+Ilnjbo+ySsaAgCfXOXUlmGzJ4ygYPWmysm77yg4emwfmoz3b22yvH5IsVFHbhUaH5w==} - dev: false + preact@10.26.4: {} - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true + prelude-ls@1.2.1: {} - /pretty-format@3.8.0: - resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} - dev: false + pretty-format@3.8.0: {} - /prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false + proxy-from-env@1.1.0: {} - /punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - dev: true + punycode@2.3.1: {} - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + queue-microtask@1.2.3: {} - /react-day-picker@8.10.1(date-fns@4.1.0)(react@19.0.0): - resolution: {integrity: sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==} - peerDependencies: - date-fns: ^2.28.0 || ^3.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-day-picker@8.10.1(date-fns@4.1.0)(react@19.1.0): dependencies: date-fns: 4.1.0 - react: 19.0.0 - dev: false + react: 19.1.0 - /react-dom@19.0.0(react@19.0.0): - resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} - peerDependencies: - react: ^19.0.0 + react-dom@19.1.0(react@19.1.0): dependencies: - react: 19.0.0 - scheduler: 0.25.0 - dev: false + react: 19.1.0 + scheduler: 0.26.0 - /react-hook-form@7.54.2(react@19.0.0): - resolution: {integrity: sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg==} - engines: {node: '>=18.0.0'} - peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^19 + react-hook-form@7.55.0(react@19.1.0): dependencies: - react: 19.0.0 - dev: false + react: 19.1.0 - /react-icons@5.5.0(react@19.0.0): - resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} - peerDependencies: - react: '*' + react-icons@5.5.0(react@19.1.0): dependencies: - react: 19.0.0 - dev: false + react: 19.1.0 - /react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@16.13.1: {} - /react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - dev: false + react-is@18.3.1: {} - /react-remove-scroll-bar@2.3.8(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true + react-remove-scroll-bar@2.3.8(@types/react@19.1.0)(react@19.1.0): dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - react-style-singleton: 2.2.3(@types/react@19.0.10)(react@19.0.0) + react: 19.1.0 + react-style-singleton: 2.2.3(@types/react@19.1.0)(react@19.1.0) tslib: 2.8.1 - dev: false + optionalDependencies: + '@types/react': 19.1.0 - /react-remove-scroll@2.6.3(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + react-remove-scroll@2.6.3(@types/react@19.1.0)(react@19.1.0): dependencies: - '@types/react': 19.0.10 - react: 19.0.0 - react-remove-scroll-bar: 2.3.8(@types/react@19.0.10)(react@19.0.0) - react-style-singleton: 2.2.3(@types/react@19.0.10)(react@19.0.0) + react: 19.1.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.0)(react@19.1.0) + react-style-singleton: 2.2.3(@types/react@19.1.0)(react@19.1.0) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.0.10)(react@19.0.0) - use-sidecar: 1.1.3(@types/react@19.0.10)(react@19.0.0) - dev: false + use-callback-ref: 1.3.3(@types/react@19.1.0)(react@19.1.0) + use-sidecar: 1.1.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.0 - /react-smooth@4.0.4(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-smooth@4.0.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: fast-equals: 5.2.2 prop-types: 15.8.1 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-transition-group: 4.4.5(react-dom@19.0.0)(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-transition-group: 4.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - /react-style-singleton@2.2.3(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + react-style-singleton@2.2.3(@types/react@19.1.0)(react@19.1.0): dependencies: - '@types/react': 19.0.10 get-nonce: 1.0.1 - react: 19.0.0 + react: 19.1.0 tslib: 2.8.1 - dev: false + optionalDependencies: + '@types/react': 19.1.0 - /react-transition-group@4.4.5(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} - peerDependencies: - react: '>=16.6.0' - react-dom: '>=16.6.0' + react-transition-group@4.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /react@19.0.0: - resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} - engines: {node: '>=0.10.0'} - dev: false + react@19.1.0: {} - /read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + read-cache@1.0.0: dependencies: pify: 2.3.0 - /readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + readdirp@3.6.0: dependencies: picomatch: 2.3.1 - /recharts-scale@0.4.5: - resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + recharts-scale@0.4.5: dependencies: decimal.js-light: 2.5.1 - dev: false - /recharts@2.15.1(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==} - engines: {node: '>=14'} - peerDependencies: - react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + recharts@2.15.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: clsx: 2.1.1 eventemitter3: 4.0.7 lodash: 4.17.21 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) react-is: 18.3.1 - react-smooth: 4.0.4(react-dom@19.0.0)(react@19.0.0) + react-smooth: 4.0.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) recharts-scale: 0.4.5 tiny-invariant: 1.3.3 victory-vendor: 36.9.2 - dev: false - /reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 @@ -4163,15 +5278,10 @@ packages: get-intrinsic: 1.3.0 get-proto: 1.0.1 which-builtin-type: 1.2.1 - dev: true - /regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: false + regenerator-runtime@0.14.1: {} - /regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} + regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 @@ -4179,89 +5289,55 @@ packages: get-proto: 1.0.1 gopd: 1.2.0 set-function-name: 2.0.2 - dev: true - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true + resolve-from@4.0.0: {} - /resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - dev: true + resolve-pkg-maps@1.0.0: {} - /resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true + resolve@1.22.10: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - /resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true + resolve@2.0.0-next.5: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true - /reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + reusify@1.1.0: {} - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - /safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} + safe-array-concat@1.1.3: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 get-intrinsic: 1.3.0 has-symbols: 1.1.0 isarray: 2.0.5 - dev: true - /safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} + safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 isarray: 2.0.5 - dev: true - /safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} + safe-regex-test@1.1.0: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-regex: 1.2.1 - dev: true - /scheduler@0.25.0: - resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} - dev: false + scheduler@0.26.0: {} - /semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - dev: true + semver@6.3.1: {} - /semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} - engines: {node: '>=10'} - hasBin: true + semver@7.7.1: {} - /set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 @@ -4269,31 +5345,21 @@ packages: get-intrinsic: 1.3.0 gopd: 1.2.0 has-property-descriptors: 1.0.2 - dev: true - /set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} + set-function-name@2.0.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 - dev: true - /set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} + set-proto@1.0.0: dependencies: dunder-proto: 1.0.1 es-errors: 1.3.0 es-object-atoms: 1.1.1 - dev: true - /sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - requiresBuild: true + sharp@0.33.5: dependencies: color: 4.2.3 detect-libc: 2.0.3 @@ -4318,122 +5384,79 @@ packages: '@img/sharp-wasm32': 0.33.5 '@img/sharp-win32-ia32': 0.33.5 '@img/sharp-win32-x64': 0.33.5 - dev: false optional: true - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + shebang-regex@3.0.0: {} - /side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 - dev: true - /side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} + side-channel-map@1.0.1: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 get-intrinsic: 1.3.0 object-inspect: 1.13.4 - dev: true - /side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} + side-channel-weakmap@1.0.2: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 get-intrinsic: 1.3.0 object-inspect: 1.13.4 side-channel-map: 1.0.1 - dev: true - /side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} + side-channel@1.1.0: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 side-channel-list: 1.0.0 side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 - dev: true - /signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} + signal-exit@4.1.0: {} - /simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - requiresBuild: true + simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 - dev: false optional: true - /sonner@2.0.1(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-FRBphaehZ5tLdLcQ8g2WOIRE+Y7BCfWi5Zyd8bCvBjiW8TxxAyoWZIxS661Yz6TGPqFQ4VLzOF89WEYhfynSFQ==} - peerDependencies: - react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc - react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + sonner@2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - dev: false + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - /source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + source-map-js@1.2.1: {} - /stable-hash@0.0.4: - resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} - dev: true + stable-hash@0.0.5: {} - /streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - dev: false + streamsearch@1.1.0: {} - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - /string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + string-width@5.1.2: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 - /string.prototype.includes@2.0.1: - resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} - engines: {node: '>= 0.4'} + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 - dev: true - /string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} + string.prototype.matchall@4.0.12: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 @@ -4448,18 +5471,13 @@ packages: regexp.prototype.flags: 1.5.4 set-function-name: 2.0.2 side-channel: 1.1.0 - dev: true - /string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + string.prototype.repeat@1.0.0: dependencies: define-properties: 1.2.1 es-abstract: 1.23.9 - dev: true - /string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} + string.prototype.trim@1.2.10: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 @@ -4468,112 +5486,64 @@ packages: es-abstract: 1.23.9 es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 - dev: true - /string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} + string.prototype.trimend@1.0.9: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 - dev: true - /string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} + string.prototype.trimstart@1.0.8: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 es-object-atoms: 1.1.1 - dev: true - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - /strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} + strip-ansi@7.1.0: dependencies: ansi-regex: 6.1.0 - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true + strip-bom@3.0.0: {} - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true + strip-json-comments@3.1.1: {} - /styled-jsx@5.1.6(react@19.0.0): - resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true + styled-jsx@5.1.6(react@19.1.0): dependencies: client-only: 0.0.1 - react: 19.0.0 - dev: false + react: 19.1.0 - /sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true + sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.8 commander: 4.1.1 glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 - pirates: 4.0.6 + pirates: 4.0.7 ts-interface-checker: 0.1.13 - /supercluster@8.0.1: - resolution: {integrity: sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==} + supercluster@8.0.1: dependencies: kdbush: 4.0.2 - dev: false - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - dev: true - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + supports-preserve-symlinks-flag@1.0.0: {} - /tailwind-merge@3.0.2: - resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==} - dev: false + tailwind-merge@3.1.0: {} - /tailwindcss-animate@1.0.7(tailwindcss@3.4.17): - resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} - peerDependencies: - tailwindcss: '>=3.0.0 || insiders' + tailwindcss-animate@1.0.7(tailwindcss@3.4.17): dependencies: tailwindcss: 3.4.17 - dev: false - /tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} - engines: {node: '>=14.0.0'} - hasBin: true + tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -4600,95 +5570,59 @@ packages: transitivePeerDependencies: - ts-node - /tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} - engines: {node: '>=6'} - dev: true - - /thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} + thenify-all@1.6.0: dependencies: thenify: 3.3.1 - /thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thenify@3.3.1: dependencies: any-promise: 1.3.0 - /tiny-invariant@1.3.3: - resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - dev: false + tiny-invariant@1.3.3: {} - /tinyglobby@0.2.12: - resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} - engines: {node: '>=12.0.0'} + tinyglobby@0.2.12: dependencies: fdir: 6.4.3(picomatch@4.0.2) picomatch: 4.0.2 - dev: true - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - /ts-api-utils@2.0.1(typescript@5.8.2): - resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' + ts-api-utils@2.1.0(typescript@5.8.2): dependencies: typescript: 5.8.2 - dev: true - /ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-interface-checker@0.1.13: {} - /tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 json5: 1.0.2 minimist: 1.2.8 strip-bom: 3.0.0 - dev: true - /tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - dev: false + tslib@2.8.1: {} - /type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - dev: true - /typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 es-errors: 1.3.0 is-typed-array: 1.1.15 - dev: true - /typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} + typed-array-byte-length@1.0.3: dependencies: call-bind: 1.0.8 for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 - dev: true - /typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} + typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 @@ -4697,11 +5631,8 @@ packages: has-proto: 1.2.0 is-typed-array: 1.1.15 reflect.getprototypeof: 1.0.10 - dev: true - /typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} + typed-array-length@1.0.7: dependencies: call-bind: 1.0.8 for-each: 0.3.5 @@ -4709,75 +5640,60 @@ packages: is-typed-array: 1.1.15 possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - dev: true - /typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} - engines: {node: '>=14.17'} - hasBin: true - dev: true + typescript@5.8.2: {} - /unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 has-bigints: 1.1.0 has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - dev: true - /undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - dev: true + undici-types@6.19.8: {} - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + unrs-resolver@1.3.3: + optionalDependencies: + '@unrs/resolver-binding-darwin-arm64': 1.3.3 + '@unrs/resolver-binding-darwin-x64': 1.3.3 + '@unrs/resolver-binding-freebsd-x64': 1.3.3 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.3.3 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.3.3 + '@unrs/resolver-binding-linux-arm64-gnu': 1.3.3 + '@unrs/resolver-binding-linux-arm64-musl': 1.3.3 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.3.3 + '@unrs/resolver-binding-linux-s390x-gnu': 1.3.3 + '@unrs/resolver-binding-linux-x64-gnu': 1.3.3 + '@unrs/resolver-binding-linux-x64-musl': 1.3.3 + '@unrs/resolver-binding-wasm32-wasi': 1.3.3 + '@unrs/resolver-binding-win32-arm64-msvc': 1.3.3 + '@unrs/resolver-binding-win32-ia32-msvc': 1.3.3 + '@unrs/resolver-binding-win32-x64-msvc': 1.3.3 + + uri-js@4.4.1: dependencies: punycode: 2.3.1 - dev: true - /use-callback-ref@1.3.3(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + use-callback-ref@1.3.3(@types/react@19.1.0)(react@19.1.0): dependencies: - '@types/react': 19.0.10 - react: 19.0.0 + react: 19.1.0 tslib: 2.8.1 - dev: false + optionalDependencies: + '@types/react': 19.1.0 - /use-sidecar@1.1.3(@types/react@19.0.10)(react@19.0.0): - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + use-sidecar@1.1.3(@types/react@19.1.0)(react@19.1.0): dependencies: - '@types/react': 19.0.10 detect-node-es: 1.1.0 - react: 19.0.0 + react: 19.1.0 tslib: 2.8.1 - dev: false + optionalDependencies: + '@types/react': 19.1.0 - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + util-deprecate@1.0.2: {} - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false + uuid@8.3.2: {} - /victory-vendor@36.9.2: - resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + victory-vendor@36.9.2: dependencies: '@types/d3-array': 3.2.1 '@types/d3-ease': 3.0.2 @@ -4793,22 +5709,16 @@ packages: d3-shape: 3.2.0 d3-time: 3.1.0 d3-timer: 3.0.1 - dev: false - /which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 is-boolean-object: 1.2.2 is-number-object: 1.1.1 is-string: 1.1.1 is-symbol: 1.1.1 - dev: true - /which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} + which-builtin-type@1.2.1: dependencies: call-bound: 1.0.4 function.prototype.name: 1.1.8 @@ -4823,21 +5733,15 @@ packages: which-boxed-primitive: 1.1.1 which-collection: 1.0.2 which-typed-array: 1.1.19 - dev: true - /which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} + which-collection@1.0.2: dependencies: is-map: 2.0.3 is-set: 2.0.3 is-weakmap: 2.0.2 is-weakset: 2.0.4 - dev: true - /which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} - engines: {node: '>= 0.4'} + which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 @@ -4846,50 +5750,29 @@ packages: get-proto: 1.0.1 gopd: 1.2.0 has-tostringtag: 1.0.2 - dev: true - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true + which@2.0.2: dependencies: isexe: 2.0.0 - /word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - dev: true + word-wrap@1.2.5: {} - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - /wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} + wrap-ansi@8.1.0: dependencies: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: false + yallist@4.0.0: {} - /yaml@2.7.0: - resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} - engines: {node: '>= 14'} - hasBin: true + yaml@2.7.1: {} - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true + yocto-queue@0.1.0: {} - /zod@3.24.2: - resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} - dev: false + zod@3.24.2: {}