From ef969a5cf785a4012436e913835ae0658be98708 Mon Sep 17 00:00:00 2001 From: Ryan Martin Date: Thu, 17 Oct 2024 16:11:11 +0700 Subject: [PATCH] feat: embed jaeger ui in cardinal editor --- package.json | 4 +- pnpm-lock.yaml | 870 ++++++++++++++---- src/components/{ => cardinal}/bottom-bar.tsx | 0 .../{ => cardinal}/entity-views.tsx | 0 .../sheets/edit-entity-group.tsx | 0 .../sheets/new-entity-group.tsx | 0 .../{ => cardinal}/sheets/sample-entities.tsx | 2 +- .../{ => cardinal}/sidebar/index.tsx | 2 +- .../{ => cardinal}/sidebar/messages.tsx | 0 .../{ => cardinal}/sidebar/persona.tsx | 0 .../{ => cardinal}/sidebar/queries.tsx | 0 .../{ => cardinal}/sidebar/utils.tsx | 0 src/components/header.tsx | 172 ++-- src/components/jaeger/sidebar.tsx | 274 ++++++ src/lib/cardinal-provider.tsx | 7 + src/lib/query-options.ts | 108 ++- src/lib/types.ts | 8 + src/routeTree.gen.ts | 170 +++- src/routes/__root.tsx | 133 +-- src/routes/_cardinal.cardinal.tsx | 139 +++ src/routes/_cardinal.tsx | 141 +++ src/routes/_jaeger.jaeger.tsx | 19 + src/routes/_jaeger.tsx | 21 + src/routes/index.tsx | 142 +-- 24 files changed, 1691 insertions(+), 521 deletions(-) rename src/components/{ => cardinal}/bottom-bar.tsx (100%) rename src/components/{ => cardinal}/entity-views.tsx (100%) rename src/components/{ => cardinal}/sheets/edit-entity-group.tsx (100%) rename src/components/{ => cardinal}/sheets/new-entity-group.tsx (100%) rename src/components/{ => cardinal}/sheets/sample-entities.tsx (95%) rename src/components/{ => cardinal}/sidebar/index.tsx (97%) rename src/components/{ => cardinal}/sidebar/messages.tsx (100%) rename src/components/{ => cardinal}/sidebar/persona.tsx (100%) rename src/components/{ => cardinal}/sidebar/queries.tsx (100%) rename src/components/{ => cardinal}/sidebar/utils.tsx (100%) create mode 100644 src/components/jaeger/sidebar.tsx create mode 100644 src/routes/_cardinal.cardinal.tsx create mode 100644 src/routes/_cardinal.tsx create mode 100644 src/routes/_jaeger.jaeger.tsx create mode 100644 src/routes/_jaeger.tsx diff --git a/package.json b/package.json index 7160db0..635c84b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@sentry/react": "^8.28.0", "@sentry/vite-plugin": "^2.22.4", "@tanstack/react-query": "^5.28.14", - "@tanstack/react-router": "^1.26.9", + "@tanstack/react-router": "^1.70.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "lucide-react": "^0.334.0", @@ -41,7 +41,7 @@ }, "devDependencies": { "@biomejs/biome": "1.9.3", - "@tanstack/router-vite-plugin": "^1.26.8", + "@tanstack/router-vite-plugin": "^1.69.1", "@types/node": "^20.12.4", "@types/react": "^18.2.74", "@types/react-dom": "^18.2.24", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b4730a4..da345b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,8 +51,8 @@ importers: specifier: ^5.28.14 version: 5.28.14(react@18.2.0) '@tanstack/react-router': - specifier: ^1.26.9 - version: 1.26.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^1.70.0 + version: 1.70.0(@tanstack/router-generator@1.69.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -94,8 +94,8 @@ importers: specifier: 1.9.3 version: 1.9.3 '@tanstack/router-vite-plugin': - specifier: ^1.26.8 - version: 1.26.8(vite@5.2.8(@types/node@20.12.4)) + specifier: ^1.69.1 + version: 1.69.1(vite@5.2.8(@types/node@20.12.4))(webpack-sources@3.2.3) '@types/node': specifier: ^20.12.4 version: 20.12.4 @@ -141,31 +141,41 @@ packages: resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.25.7': + resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.24.4': resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.25.8': + resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} + engines: {node: '>=6.9.0'} + '@babel/core@7.24.4': resolution: {integrity: sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==} engines: {node: '>=6.9.0'} + '@babel/core@7.25.8': + resolution: {integrity: sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.24.4': resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.22.5': - resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + '@babel/generator@7.25.7': + resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.23.6': resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.24.4': - resolution: {integrity: sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==} + '@babel/helper-compilation-targets@7.25.7': + resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 '@babel/helper-environment-visitor@7.22.20': resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} @@ -179,40 +189,36 @@ packages: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.23.0': - resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.24.3': resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.25.7': + resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.23.3': resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.22.5': - resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-plugin-utils@7.24.0': - resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-replace-supers@7.24.1': - resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} + '@babel/helper-module-transforms@7.25.7': + resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-plugin-utils@7.25.7': + resolution: {integrity: sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==} + engines: {node: '>=6.9.0'} + '@babel/helper-simple-access@7.22.5': resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': - resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + '@babel/helper-simple-access@7.25.7': + resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} engines: {node: '>=6.9.0'} '@babel/helper-split-export-declaration@7.22.6': @@ -223,59 +229,60 @@ packages: resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.25.7': + resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.22.20': resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.7': + resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.23.5': resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.7': + resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} + engines: {node: '>=6.9.0'} + '@babel/helpers@7.24.4': resolution: {integrity: sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.25.7': + resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} + engines: {node: '>=6.9.0'} + '@babel/highlight@7.24.2': resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} engines: {node: '>=6.9.0'} + '@babel/highlight@7.25.7': + resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.24.4': resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-jsx@7.24.1': - resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.24.1': - resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx-self@7.24.1': - resolution: {integrity: sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-transform-react-jsx-source@7.24.1': - resolution: {integrity: sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/parser@7.25.8': + resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} + engines: {node: '>=6.0.0'} + hasBin: true - '@babel/plugin-transform-react-jsx@7.23.4': - resolution: {integrity: sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==} + '@babel/plugin-syntax-jsx@7.25.7': + resolution: {integrity: sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.24.4': - resolution: {integrity: sha512-79t3CQ8+oBGk/80SQ8MN3Bs3obf83zJ0YZjDmDaEZN8MqhMI760apl5z6a20kFeMXBwJX99VpKT8CKxEBp5H1g==} + '@babel/plugin-syntax-typescript@7.25.7': + resolution: {integrity: sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -288,10 +295,18 @@ packages: resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} + '@babel/template@7.25.7': + resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.24.1': resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.25.7': + resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} + engines: {node: '>=6.9.0'} + '@babel/types@7.17.0': resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} engines: {node: '>=6.9.0'} @@ -300,6 +315,10 @@ packages: resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} + '@babel/types@7.25.8': + resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} + engines: {node: '>=6.9.0'} + '@biomejs/biome@1.9.3': resolution: {integrity: sha512-POjAPz0APAmX33WOQFGQrwLvlu7WLV4CFJMlB12b6ZSg+2q6fYu9kZwLCOA+x83zXfcPd1RpuWOKJW0GbBwLIQ==} engines: {node: '>=14.21.3'} @@ -359,138 +378,282 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.20.2': resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} engines: {node: '>=12'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.20.2': resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} engines: {node: '>=12'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.20.2': resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} engines: {node: '>=12'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.20.2': resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.20.2': resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.20.2': resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.20.2': resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.20.2': resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.20.2': resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} engines: {node: '>=12'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.20.2': resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.20.2': resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.20.2': resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.20.2': resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.20.2': resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.20.2': resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.20.2': resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} engines: {node: '>=12'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-x64@0.20.2': resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.20.2': resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.20.2': resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} engines: {node: '>=12'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.20.2': resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.20.2': resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.20.2': resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} engines: {node: '>=12'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@floating-ui/core@1.6.0': resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} @@ -1204,8 +1367,8 @@ packages: '@swc/types@0.1.6': resolution: {integrity: sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==} - '@tanstack/history@1.26.3': - resolution: {integrity: sha512-NhRgiyTdNy7lw2iL1gggj6Znz5wWi8c2yFE1zCfn0G6CPRDZZ//Stgd7bPOs6XIp24YeCFrIq4J3HAhbo8jyZg==} + '@tanstack/history@1.61.1': + resolution: {integrity: sha512-2CqERleeqO3hkhJmyJm37tiL3LYgeOpmo8szqdjgtnnG0z7ZpvzkZz6HkfOr9Ca/ha7mhAiouSvLYuLkM37AMg==} engines: {node: '>=12'} '@tanstack/query-core@5.28.13': @@ -1216,29 +1379,52 @@ packages: peerDependencies: react: ^18.0.0 - '@tanstack/react-router@1.26.9': - resolution: {integrity: sha512-7UlNKRpk71Uh6ZsN4OQkZSXJw8u7n7gKKipmxWB9iPsvczymOoJ78JYgR26y3awpqXvbEjdCb7hbxSxZt2xfbA==} + '@tanstack/react-router@1.70.0': + resolution: {integrity: sha512-PS5Y01n01B8LW6btdvphBhl7ChPo4p/sVi43Wcs7KjF7xJTSsVB0wo7l9yb1gfLIOpAhm4Gtiy+7YOd/oCXbWQ==} engines: {node: '>=12'} peerDependencies: - react: '>=16.8' - react-dom: '>=16.8' + '@tanstack/router-generator': 1.69.1 + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + '@tanstack/router-generator': + optional: true - '@tanstack/react-store@0.2.1': - resolution: {integrity: sha512-tEbMCQjbeVw9KOP/202LfqZMSNAVi6zYkkp1kBom8nFuMx/965Hzes3+6G6b/comCwVxoJU8Gg9IrcF8yRPthw==} + '@tanstack/react-store@0.5.5': + resolution: {integrity: sha512-1orYXGatBqXCYKuroFwV8Ll/6aDa5E3pU6RR4h7RvRk7TmxF1+zLCsWALZaeijXkySNMGmvawSbUXRypivg2XA==} peerDependencies: - react: '>=16' - react-dom: '>=16' + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 - '@tanstack/router-generator@1.23.0': - resolution: {integrity: sha512-iOZP489rueCdDeNYkZ3wtmnMaxiQxPZJwJeW3x7ODqhxPzZEtlnsrzxTyuLZ27kc9wUV09IQxJEFegQ6RuMOOg==} + '@tanstack/router-generator@1.69.1': + resolution: {integrity: sha512-llWfYf2oEgSC8QoO0uSov1SGC9/5r4oED7k07AAnfDMQ/jdXU4g0OdJlu2se7m5a17GgN2lEkaz/ZjmgM/tQrA==} engines: {node: '>=12'} - '@tanstack/router-vite-plugin@1.26.8': - resolution: {integrity: sha512-aoai3HGpKBEE58CjrX83/8Jzt6PUPobTpiD0tLSZ9VGGKMqkxQAXDBJycLTMpzKGBpkcZurNOh+DZP2qZd47ww==} + '@tanstack/router-plugin@1.69.1': + resolution: {integrity: sha512-GM7qUwtyUPpC1uP6bgIkK6IipKUfdahv7PUyhyK8JhCsgWiymf8X5LuMwgLIKa6G3qr9Hm0DZnbGaAlirFqYFQ==} engines: {node: '>=12'} + peerDependencies: + '@rsbuild/core': '>=1.0.2' + vite: '>=5.0.0' + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + vite: + optional: true + webpack: + optional: true - '@tanstack/store@0.1.3': - resolution: {integrity: sha512-GnolmC8Fr4mvsHE1fGQmR3Nm0eBO3KnZjDU0a+P3TeQNM/dDscFGxtA7p31NplQNW3KwBw4t1RVFmz0VeKLxcw==} + '@tanstack/router-vite-plugin@1.69.1': + resolution: {integrity: sha512-zMDYepDn2yL/MP8K5zWl93oBYsPeehoM6N4CTJCypsEa6+frKM8eNtuyEcMbIa7Ge0F/DAdLQr0AKgB5m1AXQQ==} + engines: {node: '>=12'} + + '@tanstack/store@0.5.5': + resolution: {integrity: sha512-EOSrgdDAJExbvRZEQ/Xhh9iZchXpMN+ga1Bnk8Nmygzs8TfiE6hbzThF+Pr2G19uHL6+DTDTHhJ8VQiOd7l4tA==} + + '@tanstack/virtual-file-routes@1.64.0': + resolution: {integrity: sha512-soW+gE9QTmMaqXM17r7y1p8NiQVIIECjdTaYla8BKL5Flj030m3KuxEQoiG1XgjtA0O7ayznFz2YvPcXIy3qDg==} + engines: {node: '>=12'} '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1249,8 +1435,8 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.5': - resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -1272,12 +1458,6 @@ packages: peerDependencies: vite: ^4 || ^5 - '@vitejs/plugin-react@4.2.1': - resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 - abitype@1.0.0: resolution: {integrity: sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==} peerDependencies: @@ -1294,6 +1474,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -1339,6 +1524,9 @@ packages: peerDependencies: postcss: ^8.1.0 + babel-dead-code-elimination@1.0.6: + resolution: {integrity: sha512-JxFi9qyRJpN0LjEbbjbN8g0ux71Qppn9R8Qe3k6QzHg2CaKsbUQtbn307LQGiDLGjV6JCtEFqfxzVig9MyDCHQ==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1358,6 +1546,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.24.0: + resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -1365,6 +1558,9 @@ packages: caniuse-lite@1.0.30001606: resolution: {integrity: sha512-LPbwnW4vfpJId225pwjZJOgX1m9sGfbw/RKJvw/t0QhYOOaTXHvkjVGFGPpvwEzufrjvTlsULnVTxdy4/6cqkg==} + caniuse-lite@1.0.30001669: + resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1425,6 +1621,15 @@ packages: supports-color: optional: true + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} @@ -1444,6 +1649,9 @@ packages: electron-to-chromium@1.4.728: resolution: {integrity: sha512-Ud1v7hJJYIqehlUJGqR6PF1Ek8l80zWwxA6nGxigBsGJ9f9M2fciHyrIiNMerSHSH3p+0/Ia7jIlnDkt41h5cw==} + electron-to-chromium@1.5.40: + resolution: {integrity: sha512-LYm78o6if4zTasnYclgQzxEcgMoIcybWOhkATWepN95uwVVWV0/IW10v+2sIeHE+bIYWipLneTftVyQm45UY7g==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1455,10 +1663,19 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + escalade@3.1.2: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -1507,6 +1724,9 @@ packages: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1593,6 +1813,11 @@ packages: engines: {node: '>=4'} hasBin: true + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -1660,6 +1885,9 @@ packages: ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -1680,6 +1908,9 @@ packages: node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -1722,6 +1953,9 @@ packages: picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -1781,8 +2015,8 @@ packages: preact@10.23.2: resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} - prettier@3.2.5: - resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} hasBin: true @@ -1810,10 +2044,6 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-refresh@0.14.0: - resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} - engines: {node: '>=0.10.0'} - react-remove-scroll-bar@2.3.6: resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} engines: {node: '>=10'} @@ -1864,6 +2094,9 @@ packages: regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -1975,6 +2208,11 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tsx@4.19.1: + resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} + engines: {node: '>=18.0.0'} + hasBin: true + typescript@5.4.4: resolution: {integrity: sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==} engines: {node: '>=14.17'} @@ -1986,12 +2224,27 @@ packages: unplugin@1.0.1: resolution: {integrity: sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==} + unplugin@1.14.1: + resolution: {integrity: sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==} + engines: {node: '>=14.0.0'} + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true + update-browserslist-db@1.0.13: resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + use-callback-ref@1.3.2: resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} engines: {node: '>=10'} @@ -2012,8 +2265,8 @@ packages: '@types/react': optional: true - use-sync-external-store@1.2.0: - resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + use-sync-external-store@1.2.2: + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -2069,6 +2322,9 @@ packages: webpack-virtual-modules@0.5.0: resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -2112,6 +2368,9 @@ packages: zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + snapshots: '@adraffy/ens-normalize@1.10.0': {} @@ -2128,8 +2387,15 @@ snapshots: '@babel/highlight': 7.24.2 picocolors: 1.0.0 + '@babel/code-frame@7.25.7': + dependencies: + '@babel/highlight': 7.25.7 + picocolors: 1.1.1 + '@babel/compat-data@7.24.4': {} + '@babel/compat-data@7.25.8': {} + '@babel/core@7.24.4': dependencies: '@ampproject/remapping': 2.3.0 @@ -2150,6 +2416,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@7.25.8': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helpers': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + convert-source-map: 2.0.0 + debug: 4.3.7 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/generator@7.24.4': dependencies: '@babel/types': 7.24.0 @@ -2157,9 +2443,12 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - '@babel/helper-annotate-as-pure@7.22.5': + '@babel/generator@7.25.7': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.25.8 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 '@babel/helper-compilation-targets@7.23.6': dependencies: @@ -2169,17 +2458,12 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.24.4(@babel/core@7.24.4)': + '@babel/helper-compilation-targets@7.25.7': dependencies: - '@babel/core': 7.24.4 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.4) - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 + '@babel/compat-data': 7.25.8 + '@babel/helper-validator-option': 7.25.7 + browserslist: 4.24.0 + lru-cache: 5.1.1 semver: 6.3.1 '@babel/helper-environment-visitor@7.22.20': {} @@ -2193,13 +2477,16 @@ snapshots: dependencies: '@babel/types': 7.24.0 - '@babel/helper-member-expression-to-functions@7.23.0': + '@babel/helper-module-imports@7.24.3': dependencies: '@babel/types': 7.24.0 - '@babel/helper-module-imports@7.24.3': + '@babel/helper-module-imports@7.25.7': dependencies: - '@babel/types': 7.24.0 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color '@babel/helper-module-transforms@7.23.3(@babel/core@7.24.4)': dependencies: @@ -2210,26 +2497,28 @@ snapshots: '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 - '@babel/helper-optimise-call-expression@7.22.5': + '@babel/helper-module-transforms@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/types': 7.24.0 - - '@babel/helper-plugin-utils@7.24.0': {} + '@babel/core': 7.25.8 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-simple-access': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color - '@babel/helper-replace-supers@7.24.1(@babel/core@7.24.4)': - dependencies: - '@babel/core': 7.24.4 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.23.0 - '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils@7.25.7': {} '@babel/helper-simple-access@7.22.5': dependencies: '@babel/types': 7.24.0 - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': + '@babel/helper-simple-access@7.25.7': dependencies: - '@babel/types': 7.24.0 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color '@babel/helper-split-export-declaration@7.22.6': dependencies: @@ -2237,10 +2526,16 @@ snapshots: '@babel/helper-string-parser@7.24.1': {} + '@babel/helper-string-parser@7.25.7': {} + '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-validator-identifier@7.25.7': {} + '@babel/helper-validator-option@7.23.5': {} + '@babel/helper-validator-option@7.25.7': {} + '@babel/helpers@7.24.4': dependencies: '@babel/template': 7.24.0 @@ -2249,6 +2544,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helpers@7.25.7': + dependencies: + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + '@babel/highlight@7.24.2': dependencies: '@babel/helper-validator-identifier': 7.22.20 @@ -2256,46 +2556,30 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.0.0 - '@babel/parser@7.24.4': + '@babel/highlight@7.25.7': dependencies: - '@babel/types': 7.17.0 - - '@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.4)': - dependencies: - '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 - - '@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.4)': - dependencies: - '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-validator-identifier': 7.25.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 - '@babel/plugin-transform-react-jsx-self@7.24.1(@babel/core@7.24.4)': + '@babel/parser@7.24.4': dependencies: - '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/types': 7.17.0 - '@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.24.4)': + '@babel/parser@7.25.8': dependencies: - '@babel/core': 7.24.4 - '@babel/helper-plugin-utils': 7.24.0 + '@babel/types': 7.25.8 - '@babel/plugin-transform-react-jsx@7.23.4(@babel/core@7.24.4)': + '@babel/plugin-syntax-jsx@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.24.4 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.4) - '@babel/types': 7.24.0 + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 - '@babel/plugin-transform-typescript@7.24.4(@babel/core@7.24.4)': + '@babel/plugin-syntax-typescript@7.25.7(@babel/core@7.25.8)': dependencies: - '@babel/core': 7.24.4 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.4(@babel/core@7.24.4) - '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.4) + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 '@babel/runtime@7.24.4': dependencies: @@ -2307,6 +2591,12 @@ snapshots: '@babel/parser': 7.24.4 '@babel/types': 7.24.0 + '@babel/template@7.25.7': + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + '@babel/traverse@7.24.1': dependencies: '@babel/code-frame': 7.24.2 @@ -2322,6 +2612,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.25.7': + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + debug: 4.3.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + '@babel/types@7.17.0': dependencies: '@babel/helper-validator-identifier': 7.22.20 @@ -2333,6 +2635,12 @@ snapshots: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + '@babel/types@7.25.8': + dependencies: + '@babel/helper-string-parser': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + to-fast-properties: 2.0.0 + '@biomejs/biome@1.9.3': optionalDependencies: '@biomejs/cli-darwin-arm64': 1.9.3 @@ -2371,72 +2679,144 @@ snapshots: '@esbuild/aix-ppc64@0.20.2': optional: true + '@esbuild/aix-ppc64@0.23.1': + optional: true + '@esbuild/android-arm64@0.20.2': optional: true + '@esbuild/android-arm64@0.23.1': + optional: true + '@esbuild/android-arm@0.20.2': optional: true + '@esbuild/android-arm@0.23.1': + optional: true + '@esbuild/android-x64@0.20.2': optional: true + '@esbuild/android-x64@0.23.1': + optional: true + '@esbuild/darwin-arm64@0.20.2': optional: true + '@esbuild/darwin-arm64@0.23.1': + optional: true + '@esbuild/darwin-x64@0.20.2': optional: true + '@esbuild/darwin-x64@0.23.1': + optional: true + '@esbuild/freebsd-arm64@0.20.2': optional: true + '@esbuild/freebsd-arm64@0.23.1': + optional: true + '@esbuild/freebsd-x64@0.20.2': optional: true + '@esbuild/freebsd-x64@0.23.1': + optional: true + '@esbuild/linux-arm64@0.20.2': optional: true + '@esbuild/linux-arm64@0.23.1': + optional: true + '@esbuild/linux-arm@0.20.2': optional: true + '@esbuild/linux-arm@0.23.1': + optional: true + '@esbuild/linux-ia32@0.20.2': optional: true + '@esbuild/linux-ia32@0.23.1': + optional: true + '@esbuild/linux-loong64@0.20.2': optional: true + '@esbuild/linux-loong64@0.23.1': + optional: true + '@esbuild/linux-mips64el@0.20.2': optional: true + '@esbuild/linux-mips64el@0.23.1': + optional: true + '@esbuild/linux-ppc64@0.20.2': optional: true + '@esbuild/linux-ppc64@0.23.1': + optional: true + '@esbuild/linux-riscv64@0.20.2': optional: true + '@esbuild/linux-riscv64@0.23.1': + optional: true + '@esbuild/linux-s390x@0.20.2': optional: true + '@esbuild/linux-s390x@0.23.1': + optional: true + '@esbuild/linux-x64@0.20.2': optional: true + '@esbuild/linux-x64@0.23.1': + optional: true + '@esbuild/netbsd-x64@0.20.2': optional: true + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + '@esbuild/openbsd-x64@0.20.2': optional: true + '@esbuild/openbsd-x64@0.23.1': + optional: true + '@esbuild/sunos-x64@0.20.2': optional: true + '@esbuild/sunos-x64@0.23.1': + optional: true + '@esbuild/win32-arm64@0.20.2': optional: true + '@esbuild/win32-arm64@0.23.1': + optional: true + '@esbuild/win32-ia32@0.20.2': optional: true + '@esbuild/win32-ia32@0.23.1': + optional: true + '@esbuild/win32-x64@0.20.2': optional: true + '@esbuild/win32-x64@0.23.1': + optional: true + '@floating-ui/core@1.6.0': dependencies: '@floating-ui/utils': 0.2.1 @@ -3172,7 +3552,7 @@ snapshots: dependencies: '@swc/counter': 0.1.3 - '@tanstack/history@1.26.3': {} + '@tanstack/history@1.61.1': {} '@tanstack/query-core@5.28.13': {} @@ -3181,71 +3561,91 @@ snapshots: '@tanstack/query-core': 5.28.13 react: 18.2.0 - '@tanstack/react-router@1.26.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@tanstack/react-router@1.70.0(@tanstack/router-generator@1.69.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@tanstack/history': 1.26.3 - '@tanstack/react-store': 0.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@tanstack/history': 1.61.1 + '@tanstack/react-store': 0.5.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 + optionalDependencies: + '@tanstack/router-generator': 1.69.1 - '@tanstack/react-store@0.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@tanstack/react-store@0.5.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@tanstack/store': 0.1.3 + '@tanstack/store': 0.5.5 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - use-sync-external-store: 1.2.0(react@18.2.0) - - '@tanstack/router-generator@1.23.0': - dependencies: - prettier: 3.2.5 - zod: 3.22.4 - - '@tanstack/router-vite-plugin@1.26.8(vite@5.2.8(@types/node@20.12.4))': - dependencies: - '@babel/core': 7.24.4 - '@babel/generator': 7.24.4 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.4) - '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.4) - '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.4) - '@babel/plugin-transform-typescript': 7.24.4(@babel/core@7.24.4) - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.1 - '@babel/types': 7.24.0 - '@tanstack/router-generator': 1.23.0 + use-sync-external-store: 1.2.2(react@18.2.0) + + '@tanstack/router-generator@1.69.1': + dependencies: + '@tanstack/virtual-file-routes': 1.64.0 + prettier: 3.3.3 + tsx: 4.19.1 + zod: 3.23.8 + + '@tanstack/router-plugin@1.69.1(vite@5.2.8(@types/node@20.12.4))(webpack-sources@3.2.3)': + dependencies: + '@babel/core': 7.25.8 + '@babel/generator': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.8) + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + '@tanstack/router-generator': 1.69.1 + '@tanstack/virtual-file-routes': 1.64.0 '@types/babel__core': 7.20.5 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.5 - '@vitejs/plugin-react': 4.2.1(vite@5.2.8(@types/node@20.12.4)) - zod: 3.22.4 + '@types/babel__traverse': 7.20.6 + babel-dead-code-elimination: 1.0.6 + chokidar: 3.6.0 + unplugin: 1.14.1(webpack-sources@3.2.3) + zod: 3.23.8 + optionalDependencies: + vite: 5.2.8(@types/node@20.12.4) transitivePeerDependencies: + - supports-color + - webpack-sources + + '@tanstack/router-vite-plugin@1.69.1(vite@5.2.8(@types/node@20.12.4))(webpack-sources@3.2.3)': + dependencies: + '@tanstack/router-plugin': 1.69.1(vite@5.2.8(@types/node@20.12.4))(webpack-sources@3.2.3) + transitivePeerDependencies: + - '@rsbuild/core' - supports-color - vite + - webpack + - webpack-sources + + '@tanstack/store@0.5.5': {} - '@tanstack/store@0.1.3': {} + '@tanstack/virtual-file-routes@1.64.0': {} '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.24.4 - '@babel/types': 7.24.0 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.5 + '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.25.8 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.24.4 - '@babel/types': 7.24.0 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 - '@types/babel__traverse@7.20.5': + '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.24.0 + '@babel/types': 7.25.8 '@types/estree@1.0.5': {} @@ -3271,17 +3671,6 @@ snapshots: transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@4.2.1(vite@5.2.8(@types/node@20.12.4))': - dependencies: - '@babel/core': 7.24.4 - '@babel/plugin-transform-react-jsx-self': 7.24.1(@babel/core@7.24.4) - '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.4) - '@types/babel__core': 7.20.5 - react-refresh: 0.14.0 - vite: 5.2.8(@types/node@20.12.4) - transitivePeerDependencies: - - supports-color - abitype@1.0.0(typescript@5.4.4)(zod@3.22.4): optionalDependencies: typescript: 5.4.4 @@ -3289,6 +3678,8 @@ snapshots: acorn@8.11.3: {} + acorn@8.13.0: {} + agent-base@6.0.2: dependencies: debug: 4.3.4 @@ -3332,6 +3723,15 @@ snapshots: postcss: 8.4.38 postcss-value-parser: 4.2.0 + babel-dead-code-elimination@1.0.6: + dependencies: + '@babel/core': 7.25.8 + '@babel/parser': 7.25.8 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + balanced-match@1.0.2: {} binary-extensions@2.3.0: {} @@ -3351,10 +3751,19 @@ snapshots: node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.23.0) + browserslist@4.24.0: + dependencies: + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.40 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.0) + camelcase-css@2.0.1: {} caniuse-lite@1.0.30001606: {} + caniuse-lite@1.0.30001669: {} + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -3411,6 +3820,10 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.3.7: + dependencies: + ms: 2.1.3 + detect-node-es@1.1.0: {} didyoumean@1.2.2: {} @@ -3423,6 +3836,8 @@ snapshots: electron-to-chromium@1.4.728: {} + electron-to-chromium@1.5.40: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -3453,8 +3868,37 @@ snapshots: '@esbuild/win32-ia32': 0.20.2 '@esbuild/win32-x64': 0.20.2 + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + escalade@3.1.2: {} + escalade@3.2.0: {} + escape-string-regexp@1.0.5: {} fast-glob@3.3.2: @@ -3498,6 +3942,10 @@ snapshots: get-nonce@1.0.1: {} + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -3580,6 +4028,8 @@ snapshots: jsesc@2.5.2: {} + jsesc@3.0.2: {} + json5@2.2.3: {} lilconfig@2.1.0: {} @@ -3631,6 +4081,8 @@ snapshots: ms@2.1.2: {} + ms@2.1.3: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -3645,6 +4097,8 @@ snapshots: node-releases@2.0.14: {} + node-releases@2.0.18: {} + normalize-path@3.0.0: {} normalize-range@0.1.2: {} @@ -3674,6 +4128,8 @@ snapshots: picocolors@1.0.0: {} + picocolors@1.1.1: {} + picomatch@2.3.1: {} pify@2.3.0: {} @@ -3725,7 +4181,7 @@ snapshots: preact@10.23.2: {} - prettier@3.2.5: {} + prettier@3.3.3: {} progress@2.0.3: {} @@ -3745,8 +4201,6 @@ snapshots: react-is@16.13.1: {} - react-refresh@0.14.0: {} - react-remove-scroll-bar@2.3.6(@types/react@18.2.74)(react@18.2.0): dependencies: react: 18.2.0 @@ -3794,6 +4248,8 @@ snapshots: regenerator-runtime@0.14.1: {} + resolve-pkg-maps@1.0.0: {} + resolve@1.22.8: dependencies: is-core-module: 2.13.1 @@ -3938,6 +4394,13 @@ snapshots: tslib@2.6.2: {} + tsx@4.19.1: + dependencies: + esbuild: 0.23.1 + get-tsconfig: 4.8.1 + optionalDependencies: + fsevents: 2.3.3 + typescript@5.4.4: {} undici-types@5.26.5: {} @@ -3949,12 +4412,25 @@ snapshots: webpack-sources: 3.2.3 webpack-virtual-modules: 0.5.0 + unplugin@1.14.1(webpack-sources@3.2.3): + dependencies: + acorn: 8.13.0 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + webpack-sources: 3.2.3 + update-browserslist-db@1.0.13(browserslist@4.23.0): dependencies: browserslist: 4.23.0 escalade: 3.1.2 picocolors: 1.0.0 + update-browserslist-db@1.1.1(browserslist@4.24.0): + dependencies: + browserslist: 4.24.0 + escalade: 3.2.0 + picocolors: 1.1.1 + use-callback-ref@1.3.2(@types/react@18.2.74)(react@18.2.0): dependencies: react: 18.2.0 @@ -3970,7 +4446,7 @@ snapshots: optionalDependencies: '@types/react': 18.2.74 - use-sync-external-store@1.2.0(react@18.2.0): + use-sync-external-store@1.2.2(react@18.2.0): dependencies: react: 18.2.0 @@ -4010,6 +4486,8 @@ snapshots: webpack-virtual-modules@0.5.0: {} + webpack-virtual-modules@0.6.2: {} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -4040,3 +4518,5 @@ snapshots: yocto-queue@0.1.0: {} zod@3.22.4: {} + + zod@3.23.8: {} diff --git a/src/components/bottom-bar.tsx b/src/components/cardinal/bottom-bar.tsx similarity index 100% rename from src/components/bottom-bar.tsx rename to src/components/cardinal/bottom-bar.tsx diff --git a/src/components/entity-views.tsx b/src/components/cardinal/entity-views.tsx similarity index 100% rename from src/components/entity-views.tsx rename to src/components/cardinal/entity-views.tsx diff --git a/src/components/sheets/edit-entity-group.tsx b/src/components/cardinal/sheets/edit-entity-group.tsx similarity index 100% rename from src/components/sheets/edit-entity-group.tsx rename to src/components/cardinal/sheets/edit-entity-group.tsx diff --git a/src/components/sheets/new-entity-group.tsx b/src/components/cardinal/sheets/new-entity-group.tsx similarity index 100% rename from src/components/sheets/new-entity-group.tsx rename to src/components/cardinal/sheets/new-entity-group.tsx diff --git a/src/components/sheets/sample-entities.tsx b/src/components/cardinal/sheets/sample-entities.tsx similarity index 95% rename from src/components/sheets/sample-entities.tsx rename to src/components/cardinal/sheets/sample-entities.tsx index afa5745..a5435c2 100644 --- a/src/components/sheets/sample-entities.tsx +++ b/src/components/cardinal/sheets/sample-entities.tsx @@ -1,4 +1,4 @@ -import { EntityCard } from '@/components/entity-views' +import { EntityCard } from '@/components/cardinal/entity-views' import { Accordion, AccordionContent, diff --git a/src/components/sidebar/index.tsx b/src/components/cardinal/sidebar/index.tsx similarity index 97% rename from src/components/sidebar/index.tsx rename to src/components/cardinal/sidebar/index.tsx index a26b5d7..ce2ccc3 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/cardinal/sidebar/index.tsx @@ -19,7 +19,7 @@ import { SidebarQueries } from './queries' const builtinMessages = new Set([routeMsgCreatePersona, routeMsgAuthorizePersonaAddress]) const builtinQueries = new Set([routeQryPersonaSigner, routeQryReceiptsList]) -export function Sidebar() { +export function CardinalSidebar() { const cardinal = useCardinal() const { data, isError, error } = useQuery(worldQueryOptions(cardinal)) const { toast } = useToast() diff --git a/src/components/sidebar/messages.tsx b/src/components/cardinal/sidebar/messages.tsx similarity index 100% rename from src/components/sidebar/messages.tsx rename to src/components/cardinal/sidebar/messages.tsx diff --git a/src/components/sidebar/persona.tsx b/src/components/cardinal/sidebar/persona.tsx similarity index 100% rename from src/components/sidebar/persona.tsx rename to src/components/cardinal/sidebar/persona.tsx diff --git a/src/components/sidebar/queries.tsx b/src/components/cardinal/sidebar/queries.tsx similarity index 100% rename from src/components/sidebar/queries.tsx rename to src/components/cardinal/sidebar/queries.tsx diff --git a/src/components/sidebar/utils.tsx b/src/components/cardinal/sidebar/utils.tsx similarity index 100% rename from src/components/sidebar/utils.tsx rename to src/components/cardinal/sidebar/utils.tsx diff --git a/src/components/header.tsx b/src/components/header.tsx index 55931d0..632491e 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -1,23 +1,28 @@ import * as Sentry from '@sentry/react' import { useQueryClient } from '@tanstack/react-query' -import { Bell, BellOff, RefreshCw } from 'lucide-react' +import { Bell, BellOff, ExternalLink, RefreshCw } from 'lucide-react' import { useEffect, useState } from 'react' import logoDark from '@/assets/world-dark.svg' import logoLight from '@/assets/world-light.svg' -import { Button } from '@/components/ui/button' +import { Button, buttonVariants } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { useToast } from '@/components/ui/use-toast' import { useCardinal } from '@/lib/cardinal-provider' import { worldQueryOptions } from '@/lib/query-options' import { cn, errorToast } from '@/lib/utils' +import { Link, useRouterState } from '@tanstack/react-router' + +const links = [ + { title: 'Cardinal', href: '/cardinal' }, + { title: 'Jaeger', href: '/jaeger' }, +] export function Header() { - const { cardinalUrl, setCardinalUrl, isCardinalConnected, notifications, setNotifications } = - useCardinal() - const [fetching, setFetching] = useState(false) - const queryClient = useQueryClient() - const { toast } = useToast() + const routerState = useRouterState({ + select: (state) => state.location, + }) + const location = routerState.pathname useEffect(() => { const feedback = Sentry.getFeedback() @@ -25,6 +30,50 @@ export function Header() { return unsubscribe }, []) + return ( +
+ +
+ ) +} + +function CardinalUrl() { + const { cardinalUrl, setCardinalUrl, isCardinalConnected, notifications, setNotifications } = + useCardinal() + const [fetching, setFetching] = useState(false) + const queryClient = useQueryClient() + const { toast } = useToast() + const refetchWorld = async () => { setFetching(true) try { @@ -36,50 +85,69 @@ export function Header() { } return ( -
- -
+
+
+ + setCardinalUrl(e.target.value)} + className="h-8" + /> + + +
+ ) +} + +function JaegerUrl() { + const { jaegerUrl, setJaegerUrl } = useCardinal() + + return ( +
+ + setJaegerUrl(e.target.value)} + className="h-8" + /> + + + +
) } diff --git a/src/components/jaeger/sidebar.tsx b/src/components/jaeger/sidebar.tsx new file mode 100644 index 0000000..76eb169 --- /dev/null +++ b/src/components/jaeger/sidebar.tsx @@ -0,0 +1,274 @@ +import { ThemeToggle } from '@/components/theme-toggle' +import { Button } from '@/components/ui/button' +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form' +import { Input } from '@/components/ui/input' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { useCardinal } from '@/lib/cardinal-provider' +import { jaegerSearchQueryOptions, jaegerServicesQueryOptions } from '@/lib/query-options' +import { errorToast } from '@/lib/utils' +import { zodResolver } from '@hookform/resolvers/zod' +import { useQuery, useQueryClient } from '@tanstack/react-query' +import { BookDashed, Loader } from 'lucide-react' +import { useForm } from 'react-hook-form' +import { z } from 'zod' +import { useToast } from '@/components/ui/use-toast' + +// custom lookback values not supported yet +const lookbackValues = [ + { title: 'Last 5 Minutes', value: '5m' }, + { title: 'Last 15 Minutes', value: '15m' }, + { title: 'Last 30 Minutes', value: '30m' }, + { title: 'Last Hour', value: '1h' }, + { title: 'Last 2 Hours', value: '2h' }, + { title: 'Last 3 Hours', value: '3h' }, + { title: 'Last 6 Hours', value: '6h' }, + { title: 'Last 12 Hours', value: '12h' }, + { title: 'Last 24 Hours', value: '24h' }, + { title: 'Last 2 Days', value: '2d' }, +] + +// we can afford to have a weak-ish schema and form validation since it will be validated +// again by the original jaeger ui. validation errors will be show in the iframe. this +// simplifies our code as it's already handled for us +const formSchema = z.object({ + service: z.string(), + operation: z.string().optional(), + tags: z.string().optional(), + lookback: z.string(), + maxDuration: z.string().optional(), + minDuration: z.string().optional(), + limit: z.coerce.number().int().gte(1).lte(1500), +}) + +export function JaegerSidebar() { + const { jaegerUrl } = useCardinal() + const { data: services } = useQuery(jaegerServicesQueryOptions({ jaegerUrl })) + const queryClient = useQueryClient() + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + service: '', + operation: '', + tags: '', + lookback: '1h', + maxDuration: '', + minDuration: '', + limit: 20, + }, + }) + const { toast } = useToast() + const serviceNames = Object.keys((services as object) ?? {}) + const selectedService = form.watch('service') + + const handleSubmit = async (values: z.infer) => { + if (!services || !services[values.service]) { + form.setError('service', { + type: 'custom', + message: 'Please select a service', + }) + return + } + + // set to empty string if user selected all. this will cause the `operation` + // search param to not be included in the url + if (values.operation === 'all') values.operation = '' + + try { + await queryClient.fetchQuery(jaegerSearchQueryOptions({ jaegerUrl, options: values })) + } catch (error) { + errorToast(toast, error, 'Error searching Jaeger') + } + } + + return ( + + ) +} diff --git a/src/lib/cardinal-provider.tsx b/src/lib/cardinal-provider.tsx index e1ddf73..a1ca862 100644 --- a/src/lib/cardinal-provider.tsx +++ b/src/lib/cardinal-provider.tsx @@ -16,6 +16,7 @@ interface Config { entityGroups: EntityGroup[] personas: Persona[] notifications: boolean + jaegerUrl: string } interface Projects { @@ -34,6 +35,8 @@ interface CardinalProviderState { setPersonas: (personas: Persona[]) => void notifications: boolean setNotifications: (on: boolean) => void + jaegerUrl: string + setJaegerUrl: (jaegerUrl: string) => void } interface CardinalProviderProps { @@ -50,12 +53,14 @@ const defaultEntityGroups: EntityGroup[] = [ }, ] const defaultPersonas: Persona[] = [] +const defaultJaegerUrl = 'http://localhost:16686' const defaultConfig: Config = { cardinalUrl: defaultCardinalUrl, view: defaultView, entityGroups: defaultEntityGroups, personas: defaultPersonas, notifications: false, + jaegerUrl: defaultJaegerUrl, } const defaultProject: Projects = { [__CARDINAL_PROJECT_ID__]: defaultConfig, @@ -68,6 +73,7 @@ const initialState: CardinalProviderState = { setEntityGroups: () => null, setPersonas: () => null, setNotifications: () => null, + setJaegerUrl: () => null, } const CardinalProviderContext = createContext(initialState) @@ -123,6 +129,7 @@ export function CardinalProvider({ children, ...props }: CardinalProviderProps) setEntityGroups: (entityGroups: EntityGroup[]) => setConfigItem('entityGroups', entityGroups), setPersonas: (personas: Persona[]) => setConfigItem('personas', personas), setNotifications: (on: boolean) => setConfigItem('notifications', on), + setJaegerUrl: (jaegerUrl: string) => setConfigItem('jaegerUrl', jaegerUrl), } return ( diff --git a/src/lib/query-options.ts b/src/lib/query-options.ts index dd79fcd..df4801f 100644 --- a/src/lib/query-options.ts +++ b/src/lib/query-options.ts @@ -1,7 +1,13 @@ -import { Entity, Receipt, TransactionReturn, WorldResponse } from '@/lib/types' +import { + Entity, + JaegerServicesResponse, + Receipt, + TransactionReturn, + WorldResponse, +} from '@/lib/types' import { sleep } from '@/lib/utils' -// builtin endpoints +// cardinal builtin endpoints export const routeDebugState = '/debug/state' export const routeHealth = '/health' export const routeWorld = '/world' @@ -12,6 +18,10 @@ export const routeMsgAuthorizePersonaAddress = '/tx/game/authorize-persona-addre export const routeQryPersonaSigner = '/query/persona/signer' export const routeQryReceiptsList = '/query/receipts/list' +// jaeger endpoints +export const routeJaegerServices = '/api/services' +export const routeJaegerSearch = '/search' + interface cardinalQueryOptionsProps { cardinalUrl: string isCardinalConnected: boolean @@ -174,3 +184,97 @@ export const personaQueryOptions = ({ }, enabled: isCardinalConnected, }) + +interface JaegerQueryOptionProps { + jaegerUrl: string + options?: { + service: string + operation?: string + tags?: string + lookback: string + maxDuration?: string + minDuration?: string + limit: number + } +} + +export const jaegerServicesQueryOptions = ({ jaegerUrl }: JaegerQueryOptionProps) => ({ + queryKey: ['jaegerServicesAndOperations'], + queryFn: async () => { + const res = await fetch(`${jaegerUrl}${routeJaegerServices}`) + if (!res.ok) { + const error = await res.text() + throw new Error(`error fetching ${jaegerUrl}${routeJaegerServices}: ${error}`) + } + + const data = (await res.json()) as JaegerServicesResponse + if (data.errors) { + throw new Error(`error fetching ${jaegerUrl}${routeJaegerServices}: ${data.errors}`) + } + + const services: { [k: string]: string[] } = {} + for (const service of data.data) { + const url = `${jaegerUrl}${routeJaegerServices}/${service}/operations` + const res = await fetch(url) + if (!res.ok) { + const error = await res.text() + throw new Error(`error fetching ${url}: ${error}`) + } + const operation = (await res.json()) as JaegerServicesResponse + // assume if 1 operation request errors, error the whole request + if (operation.errors) { + throw new Error(`error fetching ${url}: ${operation.errors}`) + } + services[service] = operation.data + } + + return services + }, +}) + +// TODO: validations && clean up +function getDuration(lookback: string) { + const lookupSeconds: { [k: string]: number } = { + m: 60, + h: 60 * 60, + d: 60 * 60 * 24, + } + const unit = lookback[lookback.length - 1] + const ns = lookupSeconds[unit] * 1_000_000 + return ns +} + +// since we're embedding an iframe, instead of fetching the page here, we're just +// returning the url with the search params. we're effectively using tanstack query +// as a state managemnt tool instead of putting it in a react context +export const jaegerSearchQueryOptions = ({ jaegerUrl, options }: JaegerQueryOptionProps) => ({ + queryKey: ['jaegerSearch'], + queryFn: () => { + if (!options) return // unreachable + const url = new URL(routeJaegerSearch, jaegerUrl) + + url.searchParams.append('service', options.service) + url.searchParams.append('lookback', options.lookback) + url.searchParams.append('limit', options.limit.toString()) + url.searchParams.append('uiEmbed', 'v0') + + const now = Date.now() * 1000 // convert to ns + url.searchParams.append('start', (now - getDuration(options.lookback)).toString()) + url.searchParams.append('end', now.toString()) + + if (options.operation && options.operation.length > 0) { + url.searchParams.append('operation', options.operation) + } + if (options.tags && options.tags.length > 0) { + url.searchParams.append('tags', options.tags) + } + if (options.maxDuration && options.maxDuration.length > 0) { + url.searchParams.append('maxDuration', options.maxDuration) + } + if (options.minDuration && options.minDuration.length > 0) { + url.searchParams.append('minDuration', options.minDuration) + } + + return url.toString() + }, +}) diff --git a/src/lib/types.ts b/src/lib/types.ts index 4a388b7..868a2fa 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -48,3 +48,11 @@ export interface Receipt { }[] | null } + +export interface JaegerServicesResponse { + data: string[] + total: number + limit: number + offset: number + errors: string[] | null +} diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index 6b2afc9..aca1e76 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -11,28 +11,196 @@ // Import Routes import { Route as rootRoute } from './routes/__root' +import { Route as JaegerImport } from './routes/_jaeger' +import { Route as CardinalImport } from './routes/_cardinal' import { Route as IndexImport } from './routes/index' +import { Route as JaegerJaegerImport } from './routes/_jaeger.jaeger' +import { Route as CardinalCardinalImport } from './routes/_cardinal.cardinal' // Create/Update Routes +const JaegerRoute = JaegerImport.update({ + id: '/_jaeger', + getParentRoute: () => rootRoute, +} as any) + +const CardinalRoute = CardinalImport.update({ + id: '/_cardinal', + getParentRoute: () => rootRoute, +} as any) + const IndexRoute = IndexImport.update({ path: '/', getParentRoute: () => rootRoute, } as any) +const JaegerJaegerRoute = JaegerJaegerImport.update({ + path: '/jaeger', + getParentRoute: () => JaegerRoute, +} as any) + +const CardinalCardinalRoute = CardinalCardinalImport.update({ + path: '/cardinal', + getParentRoute: () => CardinalRoute, +} as any) + // Populate the FileRoutesByPath interface declare module '@tanstack/react-router' { interface FileRoutesByPath { '/': { + id: '/' + path: '/' + fullPath: '/' preLoaderRoute: typeof IndexImport parentRoute: typeof rootRoute } + '/_cardinal': { + id: '/_cardinal' + path: '' + fullPath: '' + preLoaderRoute: typeof CardinalImport + parentRoute: typeof rootRoute + } + '/_jaeger': { + id: '/_jaeger' + path: '' + fullPath: '' + preLoaderRoute: typeof JaegerImport + parentRoute: typeof rootRoute + } + '/_cardinal/cardinal': { + id: '/_cardinal/cardinal' + path: '/cardinal' + fullPath: '/cardinal' + preLoaderRoute: typeof CardinalCardinalImport + parentRoute: typeof CardinalImport + } + '/_jaeger/jaeger': { + id: '/_jaeger/jaeger' + path: '/jaeger' + fullPath: '/jaeger' + preLoaderRoute: typeof JaegerJaegerImport + parentRoute: typeof JaegerImport + } } } // Create and export the route tree -export const routeTree = rootRoute.addChildren([IndexRoute]) +interface CardinalRouteChildren { + CardinalCardinalRoute: typeof CardinalCardinalRoute +} + +const CardinalRouteChildren: CardinalRouteChildren = { + CardinalCardinalRoute: CardinalCardinalRoute, +} + +const CardinalRouteWithChildren = CardinalRoute._addFileChildren( + CardinalRouteChildren, +) + +interface JaegerRouteChildren { + JaegerJaegerRoute: typeof JaegerJaegerRoute +} + +const JaegerRouteChildren: JaegerRouteChildren = { + JaegerJaegerRoute: JaegerJaegerRoute, +} + +const JaegerRouteWithChildren = + JaegerRoute._addFileChildren(JaegerRouteChildren) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '': typeof JaegerRouteWithChildren + '/cardinal': typeof CardinalCardinalRoute + '/jaeger': typeof JaegerJaegerRoute +} + +export interface FileRoutesByTo { + '/': typeof IndexRoute + '': typeof JaegerRouteWithChildren + '/cardinal': typeof CardinalCardinalRoute + '/jaeger': typeof JaegerJaegerRoute +} + +export interface FileRoutesById { + __root__: typeof rootRoute + '/': typeof IndexRoute + '/_cardinal': typeof CardinalRouteWithChildren + '/_jaeger': typeof JaegerRouteWithChildren + '/_cardinal/cardinal': typeof CardinalCardinalRoute + '/_jaeger/jaeger': typeof JaegerJaegerRoute +} + +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' | '' | '/cardinal' | '/jaeger' + fileRoutesByTo: FileRoutesByTo + to: '/' | '' | '/cardinal' | '/jaeger' + id: + | '__root__' + | '/' + | '/_cardinal' + | '/_jaeger' + | '/_cardinal/cardinal' + | '/_jaeger/jaeger' + fileRoutesById: FileRoutesById +} + +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + CardinalRoute: typeof CardinalRouteWithChildren + JaegerRoute: typeof JaegerRouteWithChildren +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + CardinalRoute: CardinalRouteWithChildren, + JaegerRoute: JaegerRouteWithChildren, +} + +export const routeTree = rootRoute + ._addFileChildren(rootRouteChildren) + ._addFileTypes() /* prettier-ignore-end */ + +/* ROUTE_MANIFEST_START +{ + "routes": { + "__root__": { + "filePath": "__root.tsx", + "children": [ + "/", + "/_cardinal", + "/_jaeger" + ] + }, + "/": { + "filePath": "index.tsx" + }, + "/_cardinal": { + "filePath": "_cardinal.tsx", + "children": [ + "/_cardinal/cardinal" + ] + }, + "/_jaeger": { + "filePath": "_jaeger.tsx", + "children": [ + "/_jaeger/jaeger" + ] + }, + "/_cardinal/cardinal": { + "filePath": "_cardinal.cardinal.tsx", + "parent": "/_cardinal" + }, + "/_jaeger/jaeger": { + "filePath": "_jaeger.jaeger.tsx", + "parent": "/_jaeger" + } + } +} +ROUTE_MANIFEST_END */ diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index ddb13db..a6abe89 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -1,25 +1,10 @@ import * as Sentry from '@sentry/react' -import { useQueryClient } from '@tanstack/react-query' import { Outlet, createRootRoute } from '@tanstack/react-router' import posthog from 'posthog-js' -import { useEffect } from 'react' -import { BottomBar } from '@/components/bottom-bar' import { Header } from '@/components/header' -import { Sidebar } from '@/components/sidebar' import { buttonVariants } from '@/components/ui/button' -import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable' -import { Toaster } from '@/components/ui/toaster' -import { useToast } from '@/components/ui/use-toast' -import { createPersonaAccount } from '@/lib/account' -import { useCardinal } from '@/lib/cardinal-provider' -import { - personaQueryOptions, - routeEvents, - syncStateQueryOptions, - worldQueryOptions, -} from '@/lib/query-options' -import { cn, errorToast } from '@/lib/utils' +import { cn } from '@/lib/utils' export const Route = createRootRoute({ component: Root, @@ -28,125 +13,11 @@ export const Route = createRootRoute({ }, }) -interface CardinalEvent { - Events: string[] -} - function Root() { - const { personas, setPersonas, cardinalUrl, isCardinalConnected, notifications } = useCardinal() - const queryClient = useQueryClient() - const { toast } = useToast() - - // biome-ignore lint: we don't want to rerun whenever `personas` changes - useEffect(() => { - const sync = async () => { - try { - // syncs local personas with cardinal's. this is needed for running with `world cardinal start`, - // where the state is persisted accross restarts. this is needed to keep track of the last nonce - // used by each signer. - const entities = await queryClient.fetchQuery( - syncStateQueryOptions({ cardinalUrl, isCardinalConnected }), - ) - const newPersonas = personas.filter((p) => { - const match = entities?.filter((e) => { - const signer = e.components['SignerComponent'] - if (!signer) return false - return signer['PersonaTag'] === p.personaTag && signer['SignerAddress'] === p.address - }) - return match && match.length !== 0 - }) - setPersonas(newPersonas) - - // if there is no default persona (_test_persona), create it - const personaTag = '_test_persona' - if (newPersonas.filter((p) => p.personaTag === personaTag).length > 0) return - - try { - const { namespace } = await queryClient.fetchQuery( - worldQueryOptions({ cardinalUrl, isCardinalConnected }), - ) - const { privateKey, address, sign } = createPersonaAccount(personaTag) - const nonce = 0 - const message = `${personaTag}${namespace}${nonce}{"personaTag":"${personaTag}","signerAddress":"${address}"}` - const signature = sign(message) - const body = { - personaTag, - nonce, - signature, - namespace, - body: { personaTag, signerAddress: address }, - } - try { - const receipt = await queryClient.fetchQuery( - personaQueryOptions({ cardinalUrl, isCardinalConnected, body }), - ) - - if (!receipt.receipts) return - const result = receipt.receipts[0] - if (result.result) { - const newPersona = { personaTag, privateKey, address, nonce: nonce + 1 } - setPersonas([...newPersonas, newPersona]) - } - } catch (error) { - errorToast(toast, error, 'Failed to create test persona') - } - } catch (error) { - errorToast(toast, error, 'Failed to fetch cardinal namespace') - } - } catch (error) { - errorToast(toast, error, 'Failed to sync personas') - } - } - if (isCardinalConnected) sync().catch((e) => console.log(e)) - }, [isCardinalConnected, cardinalUrl, toast, queryClient]) - - // setup websocket connection to receive events - useEffect(() => { - const wsCardinalUrl = cardinalUrl.replace(/https|http/, 'ws') - const ws = new WebSocket(`${wsCardinalUrl}${routeEvents}`) - ws.onopen = () => console.log('Connected to events ws') - ws.onmessage = (event) => { - const data = JSON.parse(event.data as string) as CardinalEvent - if (data.Events && data.Events.length > 0) { - // data.Events is an array of base64-ed JSON representation of an event - data.Events.forEach((evt) => { - let eventData = atob(evt) - try { - const json = JSON.parse(eventData) as { [k: string]: string } - eventData = json.event - } catch (_error) { - // this just means the backend used EmitStringEvent instead of EmitEvent, - // we can safely ignore this error - } - if (notifications) { - toast({ title: eventData }) - } else { - console.log('Received event: ', eventData) - } - }) - } - } - return () => ws.close() - }, [cardinalUrl, toast, notifications]) - return (
-
- -
- - -
- -
- -
- - -
-
-
+ ) } diff --git a/src/routes/_cardinal.cardinal.tsx b/src/routes/_cardinal.cardinal.tsx new file mode 100644 index 0000000..739e946 --- /dev/null +++ b/src/routes/_cardinal.cardinal.tsx @@ -0,0 +1,139 @@ +import { useQuery } from '@tanstack/react-query' +import { createFileRoute } from '@tanstack/react-router' +import { Box, LayoutGrid, List, Unlink } from 'lucide-react' +import { useEffect } from 'react' + +import { EntityCards, EntityList } from '@/components/cardinal/entity-views' +import { EditEntityGroupSheet } from '@/components/cardinal/sheets/edit-entity-group' +import { NewEntityGroupSheet } from '@/components/cardinal/sheets/new-entity-group' +import { Badge } from '@/components/ui/badge' +import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs' +import { useToast } from '@/components/ui/use-toast' +import { useCardinal } from '@/lib/cardinal-provider' +import { stateQueryOptions } from '@/lib/query-options' + +export const Route = createFileRoute('/_cardinal/cardinal')({ + component: Cardinal, +}) + +function Cardinal() { + const { cardinalUrl, isCardinalConnected, view, setView, entityGroups } = useCardinal() + const { + data: entities, + isError, + error, + } = useQuery(stateQueryOptions({ cardinalUrl, isCardinalConnected })) + const { toast } = useToast() + + // we need this useEffect to avoid react's infinite rerender error + useEffect(() => { + if (isError) + toast({ + title: 'Failed to fetch entities', + description: error.message, + variant: 'destructive', + }) + }, [isError, error, toast]) + + const hasNoEntities = !(entities && entities.length > 0) + // TODO: this is probably very inefficient. come up with a better filter algorithm + const grouped = new Set() + const filtered = entityGroups.map((eg) => ({ + ...eg, + entities: + entities?.filter((e) => { + const exists = eg.components.filter((c) => e.components[c]).length > 0 + if (exists) grouped.add(e.id) + return exists + }) ?? [], + })) + const ungrouped = entities?.filter((e) => !grouped.has(e.id)) ?? [] + + return ( +
+
+

Entities

+
+ + + + + + + + + + + +
+
+ {!isCardinalConnected ? ( +
+ +
+

Not Connected

+

Make sure you have a running Cardinal instance!

+
+
+ ) : hasNoEntities ? ( +
+ +
+

No Entities Found

+

+ Create entities in Cardinal to display them here +

+
+
+ ) : ( +
+ {filtered.map((eg) => ( +
+
+
+

{eg.name}

+ +

+ {eg.entities.length} results +

+
+ {eg.components.map((c) => ( + + {c} + + ))} +
+
+ {view === 'card' ? ( + + ) : ( + + )} +
+ ))} +
+
+
+

Ungrouped

+

+ {ungrouped.length} results +

+
+
+
+ {view === 'card' ? ( + + ) : ( + + )} +
+
+ )} +
+ ) +} diff --git a/src/routes/_cardinal.tsx b/src/routes/_cardinal.tsx new file mode 100644 index 0000000..1366f80 --- /dev/null +++ b/src/routes/_cardinal.tsx @@ -0,0 +1,141 @@ +import { BottomBar } from '@/components/cardinal/bottom-bar' +import { CardinalSidebar } from '@/components/cardinal/sidebar' +import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable' +import { Toaster } from '@/components/ui/toaster' +import { useToast } from '@/components/ui/use-toast' +import { createPersonaAccount } from '@/lib/account' +import { useCardinal } from '@/lib/cardinal-provider' +import { + personaQueryOptions, + routeEvents, + syncStateQueryOptions, + worldQueryOptions, +} from '@/lib/query-options' +import { errorToast } from '@/lib/utils' +import { useQueryClient } from '@tanstack/react-query' +import { Outlet, createFileRoute } from '@tanstack/react-router' +import { useEffect } from 'react' + +export const Route = createFileRoute('/_cardinal')({ + component: CardinalLayout, +}) + +interface CardinalEvent { + Events: string[] +} + +function CardinalLayout() { + const { personas, setPersonas, cardinalUrl, isCardinalConnected, notifications } = useCardinal() + const queryClient = useQueryClient() + const { toast } = useToast() + + // biome-ignore lint: we don't want to rerun whenever `personas` changes + useEffect(() => { + const sync = async () => { + try { + // syncs local personas with cardinal's. this is needed for running with `world cardinal start`, + // where the state is persisted accross restarts. this is needed to keep track of the last nonce + // used by each signer. + const entities = await queryClient.fetchQuery( + syncStateQueryOptions({ cardinalUrl, isCardinalConnected }), + ) + const newPersonas = personas.filter((p) => { + const match = entities?.filter((e) => { + const signer = e.components['SignerComponent'] + if (!signer) return false + return signer['PersonaTag'] === p.personaTag && signer['SignerAddress'] === p.address + }) + return match && match.length !== 0 + }) + setPersonas(newPersonas) + + // if there is no default persona (_test_persona), create it + const personaTag = '_test_persona' + if (newPersonas.filter((p) => p.personaTag === personaTag).length > 0) return + + try { + const { namespace } = await queryClient.fetchQuery( + worldQueryOptions({ cardinalUrl, isCardinalConnected }), + ) + const { privateKey, address, sign } = createPersonaAccount(personaTag) + const nonce = 0 + const message = `${personaTag}${namespace}${nonce}{"personaTag":"${personaTag}","signerAddress":"${address}"}` + const signature = sign(message) + const body = { + personaTag, + nonce, + signature, + namespace, + body: { personaTag, signerAddress: address }, + } + try { + const receipt = await queryClient.fetchQuery( + personaQueryOptions({ cardinalUrl, isCardinalConnected, body }), + ) + + if (!receipt.receipts) return + const result = receipt.receipts[0] + if (result.result) { + const newPersona = { personaTag, privateKey, address, nonce: nonce + 1 } + setPersonas([...newPersonas, newPersona]) + } + } catch (error) { + errorToast(toast, error, 'Failed to create test persona') + } + } catch (error) { + errorToast(toast, error, 'Failed to fetch cardinal namespace') + } + } catch (error) { + errorToast(toast, error, 'Failed to sync personas') + } + } + if (isCardinalConnected) sync().catch((e) => console.log(e)) + }, [isCardinalConnected, cardinalUrl, toast, queryClient]) + + // setup websocket connection to receive events + useEffect(() => { + const wsCardinalUrl = cardinalUrl.replace(/https|http/, 'ws') + const ws = new WebSocket(`${wsCardinalUrl}${routeEvents}`) + ws.onopen = () => console.log('Connected to events ws') + ws.onmessage = (event) => { + const data = JSON.parse(event.data as string) as CardinalEvent + if (data.Events && data.Events.length > 0) { + // data.Events is an array of base64-ed JSON representation of an event + data.Events.forEach((evt) => { + let eventData = atob(evt) + try { + const json = JSON.parse(eventData) as { [k: string]: string } + eventData = json.event + } catch (_error) { + // this just means the backend used EmitStringEvent instead of EmitEvent, + // we can safely ignore this error + } + if (notifications) { + toast({ title: eventData }) + } else { + console.log('Received event: ', eventData) + } + }) + } + } + return () => ws.close() + }, [cardinalUrl, toast, notifications]) + + return ( +
+ +
+ + +
+ +
+ +
+ + +
+
+
+ ) +} diff --git a/src/routes/_jaeger.jaeger.tsx b/src/routes/_jaeger.jaeger.tsx new file mode 100644 index 0000000..89ffd29 --- /dev/null +++ b/src/routes/_jaeger.jaeger.tsx @@ -0,0 +1,19 @@ +import { useCardinal } from '@/lib/cardinal-provider' +import { useQuery } from '@tanstack/react-query' +import { createFileRoute } from '@tanstack/react-router' + +export const Route = createFileRoute('/_jaeger/jaeger')({ + component: Jaeger, +}) + +function Jaeger() { + const { jaegerUrl } = useCardinal() + const { data: url } = useQuery({ queryKey: ['jaegerSearch'], enabled: false }) + const defaultUrl = `${jaegerUrl}/?uiEmbed=v0` + + return ( +
+