From 9b5ab39d0032e1b948f5c1c48159a039c9d10154 Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Tue, 4 Jun 2024 13:30:06 -0400 Subject: [PATCH 01/26] Upgrade `jest`, `vite` and `vitest` (#4449) * upgrade vite and vitest * rm hook tests * jest upgrade --- app/package.json | 4 +- app/packages/aggregations/package.json | 4 +- app/packages/app/package.json | 2 +- app/packages/components/package.json | 2 +- app/packages/core/package.json | 2 +- app/packages/embeddings/package.json | 4 +- app/packages/flashlight/package.json | 2 +- app/packages/looker-3d/package.json | 4 +- app/packages/looker/package.json | 2 +- app/packages/map/package.json | 2 +- app/packages/operators/package.json | 4 +- app/packages/plugins/package.json | 4 +- app/packages/relay/package.json | 2 +- app/packages/spaces/package.json | 2 +- app/packages/state/package.json | 4 +- .../state/src/hooks/useGroupEntries.test.tsx | 201 -- app/packages/utilities/package.json | 4 +- app/yarn.lock | 2244 +++++++++-------- 18 files changed, 1209 insertions(+), 1284 deletions(-) delete mode 100644 app/packages/state/src/hooks/useGroupEntries.test.tsx diff --git a/app/package.json b/app/package.json index 00b3eb283c..7b15f87d6d 100644 --- a/app/package.json +++ b/app/package.json @@ -42,10 +42,10 @@ "typedoc": "^0.23.21", "typescript": "^4.7.4", "typescript-plugin-css-modules": "^5.0.2", - "vite": "^3.2.10", + "vite": "^5.2.12", "vite-plugin-eslint": "^1.8.1", "vite-plugin-relay": "^2.0.0", - "vitest": "^0.34.6" + "vitest": "^1.6.0" }, "workspaces": [ "packages/*" diff --git a/app/packages/aggregations/package.json b/app/packages/aggregations/package.json index 854371cb95..04c0c06aa7 100644 --- a/app/packages/aggregations/package.json +++ b/app/packages/aggregations/package.json @@ -23,10 +23,10 @@ "@babel/preset-typescript": "^7.17.12", "@types/react": "^18.0.12", "fs-extra": "^10.1.0", - "jest": "^28.1.1", + "jest": "^29.7.0", "lodash": "^4.17.21", "prettier": "2.2.1", "typescript": "4.2.4", - "vite": "^3.2.10" + "vite": "^5.2.12" } } diff --git a/app/packages/app/package.json b/app/packages/app/package.json index 9383ecdb7e..6f1676f060 100644 --- a/app/packages/app/package.json +++ b/app/packages/app/package.json @@ -53,7 +53,7 @@ "rollup-plugin-polyfill-node": "^0.6.2", "typescript": "^4.7.4", "typescript-plugin-css-modules": "^5.0.2", - "vite": "^3.2.10", + "vite": "^5.2.12", "vite-plugin-relay": "^1.0.7", "vite-plugin-rewrite-all": "^1.0.2" }, diff --git a/app/packages/components/package.json b/app/packages/components/package.json index fd73782eb6..7f4eece090 100644 --- a/app/packages/components/package.json +++ b/app/packages/components/package.json @@ -27,7 +27,7 @@ "prettier": "^2.7.1", "typescript": "^4.7.4", "typescript-plugin-css-modules": "^5.0.2", - "vite": "^3.2.10" + "vite": "^5.2.12" }, "peerDependencies": { "re-resizable": "*", diff --git a/app/packages/core/package.json b/app/packages/core/package.json index 0177ae7b2c..082d7410d7 100644 --- a/app/packages/core/package.json +++ b/app/packages/core/package.json @@ -66,7 +66,7 @@ "rollup-plugin-polyfill-node": "^0.6.2", "typescript": "^4.7.4", "typescript-plugin-css-modules": "^5.0.2", - "vite": "^3.2.10", + "vite": "^5.2.12", "vite-plugin-relay": "^1.0.7" }, "peerDependencies": { diff --git a/app/packages/embeddings/package.json b/app/packages/embeddings/package.json index 01d9a99a98..0786341a4d 100644 --- a/app/packages/embeddings/package.json +++ b/app/packages/embeddings/package.json @@ -23,9 +23,9 @@ "devDependencies": { "@vitest/ui": "^0.34.6", "typescript": "^4.7.4", - "vite": "^3.2.10", + "vite": "^5.2.12", "vite-plugin-externals": "^0.5.0", - "vitest": "^0.34.6" + "vitest": "^1.6.0" }, "fiftyone": { "script": "dist/index.umd.js" diff --git a/app/packages/flashlight/package.json b/app/packages/flashlight/package.json index 970dcfb4da..2b8f0bc638 100644 --- a/app/packages/flashlight/package.json +++ b/app/packages/flashlight/package.json @@ -21,6 +21,6 @@ "prettier": "^2.7.1", "typescript": "^4.7.4", "typescript-plugin-css-modules": "^5.0.2", - "vite": "^3.2.10" + "vite": "^5.2.12" } } diff --git a/app/packages/looker-3d/package.json b/app/packages/looker-3d/package.json index a15ba47622..c8938f0dbb 100644 --- a/app/packages/looker-3d/package.json +++ b/app/packages/looker-3d/package.json @@ -34,9 +34,9 @@ "nodemon": "^3.0.3", "rollup-plugin-external-globals": "^0.6.1", "typescript": "^5.4.5", - "vite": "^3.2.10", + "vite": "^5.2.12", "vite-plugin-externals": "^0.5.0", - "vitest": "^1.5.0" + "vitest": "^1.6.0" }, "peerDependencies": { "@mui/icons-material": "*", diff --git a/app/packages/looker/package.json b/app/packages/looker/package.json index a150cccaf1..d7f1fa31d2 100644 --- a/app/packages/looker/package.json +++ b/app/packages/looker/package.json @@ -38,6 +38,6 @@ "prettier": "^2.7.1", "typescript": "^4.7.4", "typescript-plugin-css-modules": "^5.0.2", - "vite": "^3.2.10" + "vite": "^5.2.12" } } diff --git a/app/packages/map/package.json b/app/packages/map/package.json index 5a5460d7f2..89227d5039 100644 --- a/app/packages/map/package.json +++ b/app/packages/map/package.json @@ -29,7 +29,7 @@ "@types/react-map-gl": "^6.1.3", "@types/robust-point-in-polygon": "^1.0.2", "typescript": "^4.7.4", - "vite": "^3.2.10", + "vite": "^5.2.12", "vite-plugin-externals": "^0.5.0" }, "fiftyone": { diff --git a/app/packages/operators/package.json b/app/packages/operators/package.json index 8f032c8c93..9e6ca563b6 100644 --- a/app/packages/operators/package.json +++ b/app/packages/operators/package.json @@ -21,10 +21,10 @@ "@babel/preset-typescript": "^7.17.12", "@fiftyone/utilities": "workspace:^", "@types/react": "^18.0.12", - "jest": "^28.1.1", + "jest": "^29.7.0", "prettier": "2.2.1", "typescript": "4.2.4", - "vite": "^3.2.10" + "vite": "^5.2.12" }, "peerDependencies": { "@mui/icons-material": "*", diff --git a/app/packages/plugins/package.json b/app/packages/plugins/package.json index 8223a0211d..4bdf298979 100644 --- a/app/packages/plugins/package.json +++ b/app/packages/plugins/package.json @@ -22,10 +22,10 @@ "@babel/preset-typescript": "^7.17.12", "@fiftyone/utilities": "workspace:^", "@types/react": "^18.0.12", - "jest": "^28.1.1", + "jest": "^29.7.0", "prettier": "2.2.1", "typescript": "4.2.4", - "vite": "^3.2.10" + "vite": "^5.2.12" }, "dependencies": { "moment": "^2.29.4" diff --git a/app/packages/relay/package.json b/app/packages/relay/package.json index acceaed89a..a2daffbf5c 100644 --- a/app/packages/relay/package.json +++ b/app/packages/relay/package.json @@ -23,7 +23,7 @@ "relay-compiler-language-typescript": "^15.0.1", "relay-config": "^12.0.1", "typescript": "^4.7.4", - "vite": "^3.2.10" + "vite": "^5.2.12" }, "dependencies": { "@recoiljs/refine": "^0.1.1", diff --git a/app/packages/spaces/package.json b/app/packages/spaces/package.json index 9b28f75ba1..7335242765 100644 --- a/app/packages/spaces/package.json +++ b/app/packages/spaces/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@types/sortablejs": "^1.15.0", - "vite": "^3.2.10" + "vite": "^5.2.12" }, "dependencies": { "allotment": "^1.17.0", diff --git a/app/packages/state/package.json b/app/packages/state/package.json index 588da90fa4..b263794cb0 100644 --- a/app/packages/state/package.json +++ b/app/packages/state/package.json @@ -30,8 +30,8 @@ "babel-plugin-relay": "^14.1.0", "prettier": "^2.7.1", "typescript": "^4.7.4", - "vite": "^3.2.10", - "vitest": "^0.34.6" + "vite": "^5.2.12", + "vitest": "^1.6.0" }, "dependencies": { "@fiftyone/looker": "*", diff --git a/app/packages/state/src/hooks/useGroupEntries.test.tsx b/app/packages/state/src/hooks/useGroupEntries.test.tsx deleted file mode 100644 index 28a83dc213..0000000000 --- a/app/packages/state/src/hooks/useGroupEntries.test.tsx +++ /dev/null @@ -1,201 +0,0 @@ -import { act, renderHook } from "@testing-library/react-hooks"; -import React from "react"; -import { RecoilRoot, useRecoilValue } from "recoil"; -import { expect, it, test } from "vitest"; -import { - attributeVisibility, - modalAttributeVisibility, - sidebarGroupsDefinition, -} from ".."; -import { filters, modalFilters } from "../recoil/filters"; -import { useClearFiltered, useClearVisibility } from "./useGroupEntries"; - -const Root1: React.FC> = ({ children }) => { - return ( - { - snapshot.set(filters, { - "ground_truth.detections.camera": { - values: ["cannon"], - exclude: false, - isMatching: true, - }, - "ground_truth.detections.label": { - values: ["cat", "dog"], - exclude: false, - isMatching: true, - }, - }); - snapshot.set(modalFilters, { - "ground_truth.detections.camera": { - values: ["cannon"], - exclude: false, - isMatching: true, - }, - }); - snapshot.set(sidebarGroupsDefinition(false), [ - { - name: "ground_truth", - paths: ["ground_truth.detection"], - expanded: true, - }, - { - name: "predictions", - paths: ["predictions.detection"], - expanded: true, - }, - { - name: "primitives", - paths: ["list_bools", "id", "filepath"], - expanded: true, - }, - ]); - snapshot.set(sidebarGroupsDefinition(true), [ - { - name: "ground_truth", - paths: ["ground_truth.detection"], - expanded: true, - }, - { - name: "predictions", - paths: ["predictions.detection"], - expanded: true, - }, - { - name: "primitives", - paths: ["list_bools", "id", "filepath"], - expanded: true, - }, - ]); - }} - > - {children} - - ); -}; - -const Root2: React.FC> = ({ children }) => { - return ( - { - snapshot.set(attributeVisibility, { - "ground_truth.detections.camera": { - values: ["cannon"], - exclude: false, - isMatching: true, - }, - "ground_truth.detections.label": { - values: ["cat", "dog"], - exclude: false, - isMatching: true, - }, - }); - snapshot.set(modalAttributeVisibility, { - "ground_truth.detections.camera": { - values: ["cannon"], - exclude: false, - isMatching: true, - }, - }); - snapshot.set(sidebarGroupsDefinition(false), [ - { - name: "ground_truth", - paths: ["ground_truth.detection"], - expanded: true, - }, - { - name: "predictions", - paths: ["predictions.detection"], - expanded: true, - }, - { - name: "primitives", - paths: ["list_bools", "id", "filepath"], - expanded: true, - }, - ]); - snapshot.set(sidebarGroupsDefinition(true), [ - { - name: "ground_truth", - paths: ["ground_truth.detection"], - expanded: true, - }, - { - name: "predictions", - paths: ["predictions.detection"], - expanded: true, - }, - { - name: "primitives", - paths: ["list_bools", "id", "filepath"], - expanded: true, - }, - ]); - }} - > - {children} - - ); -}; - -test("Test useClearFiltered", () => { - const { result } = renderHook( - () => ({ - clearModalFilters: useClearFiltered(true, "ground_truth"), - clearGridFilters: useClearFiltered(false, "ground_truth"), - filters: useRecoilValue(filters), - modalFilters: useRecoilValue(modalFilters), - }), - { - wrapper: Root1, - } - ); - - it("should clear modal filters", () => { - act(() => { - result.current.clearModalFilters(); - }); - - expect(result.current.modalFilters).toStrictEqual({}); - expect(Object.keys(result.current.filters)).toHaveLength(2); - }); - - it("should clear grid filters", () => { - act(() => { - result.current.clearGridFilters(); - }); - expect(result.current.filters).toStrictEqual({}); - expect(Object.keys(result.current.modalFilters)).toHaveLength(1); - }); -}); - -test("Test useClearVisibility", () => { - const { result } = renderHook( - () => ({ - clearModalVisibility: useClearVisibility(true, "ground_truth"), - clearGridVisibility: useClearVisibility(false, "ground_truth"), - visibility: useRecoilValue(attributeVisibility), - modalVisibility: useRecoilValue(modalAttributeVisibility), - }), - { - wrapper: Root2, - } - ); - - it("should clear modal attribute visibility", () => { - act(() => { - result.current.clearModalVisibility(); - }); - - expect(result.current.modalVisibility).toStrictEqual({}); - expect(Object.keys(result.current.visibility)).toHaveLength(2); - }); - - it("should clear grid attribute visibility", () => { - act(() => { - result.current.clearGridVisibility(); - }); - expect(result.current.visibility).toStrictEqual({}); - expect(Object.keys(result.current.modalVisibility)).toHaveLength(1); - }); -}); diff --git a/app/packages/utilities/package.json b/app/packages/utilities/package.json index 021acea569..e0151b0f6c 100644 --- a/app/packages/utilities/package.json +++ b/app/packages/utilities/package.json @@ -21,8 +21,8 @@ "prettier": "^2.7.1", "typescript": "^4.7.4", "typescript-plugin-css-modules": "^5.0.2", - "vite": "^3.2.10", - "vitest": "^1.4.0" + "vite": "^5.2.12", + "vitest": "^1.6.0" }, "dependencies": { "@microsoft/fetch-event-source": "^2.0.1", diff --git a/app/yarn.lock b/app/yarn.lock index fb3e5fe8b6..22874fc051 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -46,6 +46,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/code-frame@npm:7.24.6" + dependencies: + "@babel/highlight": ^7.24.6 + picocolors: ^1.0.0 + checksum: 0904514ea7079a9590c1c546cd20b9c1beab9649873f2a0703429860775c1713a8dfb2daacd781a0210bb3930c656c1c436013fb20eaa3644880fb3a2b34541d + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.23.5, @babel/compat-data@npm:^7.24.1": version: 7.24.1 resolution: "@babel/compat-data@npm:7.24.1" @@ -53,6 +63,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/compat-data@npm:7.24.6" + checksum: 92233c708f7c349923c1f9a2b3c9354875a951ac3afaca0a2c159de1c808f6799ad4433652b90870015281aa466ec6e9aa8922e755cd7ac1413a3a5782cd685d + languageName: node + linkType: hard + "@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.14.8, @babel/core@npm:^7.15.0, @babel/core@npm:^7.17.10, @babel/core@npm:^7.23.5": version: 7.24.1 resolution: "@babel/core@npm:7.24.1" @@ -76,6 +93,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.23.9": + version: 7.24.6 + resolution: "@babel/core@npm:7.24.6" + dependencies: + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.24.6 + "@babel/generator": ^7.24.6 + "@babel/helper-compilation-targets": ^7.24.6 + "@babel/helper-module-transforms": ^7.24.6 + "@babel/helpers": ^7.24.6 + "@babel/parser": ^7.24.6 + "@babel/template": ^7.24.6 + "@babel/traverse": ^7.24.6 + "@babel/types": ^7.24.6 + convert-source-map: ^2.0.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.3 + semver: ^6.3.1 + checksum: f8af23de19865818c27c2fbe0d87b0834b118386da5ee09b20ae0cf7a5540065054ef2b70f377d025d9feee765db18df39900e4c18e905988b94b54a104c738e + languageName: node + linkType: hard + "@babel/core@npm:^7.24.3": version: 7.24.3 resolution: "@babel/core@npm:7.24.3" @@ -111,6 +151,18 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/generator@npm:7.24.6" + dependencies: + "@babel/types": ^7.24.6 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + jsesc: ^2.5.1 + checksum: a477e03129106908f464b195c4f138052d732cfca47506b127edbed6a496371bae821662a8a4e51e6d144ac236a5d05dc2da0e145e29bb8e19d3e7c480ac00fe + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" @@ -152,6 +204,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-compilation-targets@npm:7.24.6" + dependencies: + "@babel/compat-data": ^7.24.6 + "@babel/helper-validator-option": ^7.24.6 + browserslist: ^4.22.2 + lru-cache: ^5.1.1 + semver: ^6.3.1 + checksum: c66bf86387fbeefc617db9510de553880ed33dc91308421ee36a7b489d0e8c8eb615e0f467a9ec886eada7c05b03e421e55b2a724ff302402fdd4e0c0b2b0443 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.24.1": version: 7.24.1 resolution: "@babel/helper-create-class-features-plugin@npm:7.24.1" @@ -206,6 +271,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-environment-visitor@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-environment-visitor@npm:7.24.6" + checksum: 9c2b3f1ee7ba46b61b0482efab6d37f5c76f0ea4e9d9775df44a89644729c3a50101040a0233543ec6c3f416d8e548d337f310ff3e164f847945507428ee39e5 + languageName: node + linkType: hard + "@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0": version: 7.23.0 resolution: "@babel/helper-function-name@npm:7.23.0" @@ -216,6 +288,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-function-name@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-function-name@npm:7.24.6" + dependencies: + "@babel/template": ^7.24.6 + "@babel/types": ^7.24.6 + checksum: d7a2198b6bf2cae9767d5b0d6cb5d3cbd9a07640ad4b6798abb7d7242e8f32765a94fd98ab1a039d7607f0ddbeaf9ddc822dd536b856e499f7082899c6f455f0 + languageName: node + linkType: hard + "@babel/helper-hoist-variables@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-hoist-variables@npm:7.22.5" @@ -225,6 +307,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-hoist-variables@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-hoist-variables@npm:7.24.6" + dependencies: + "@babel/types": ^7.24.6 + checksum: 4819b574393a5214aff6ae02a6e5250ace2564f8bcdb28d580ffec57bbb2092425e8f39563d75cfa268940a01fd425bad503c0b92717c12426f15cf6847855d3 + languageName: node + linkType: hard + "@babel/helper-member-expression-to-functions@npm:^7.23.0": version: 7.23.0 resolution: "@babel/helper-member-expression-to-functions@npm:7.23.0" @@ -243,6 +334,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-module-imports@npm:7.24.6" + dependencies: + "@babel/types": ^7.24.6 + checksum: 3484420c45529aac34cb14111a03c78edab84e5c4419634affe61176d832af82963395ea319f67c7235fd4106d9052a9f3ce012d2d57d56644572d3f7d495231 + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.23.3": version: 7.23.3 resolution: "@babel/helper-module-transforms@npm:7.23.3" @@ -258,6 +358,21 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-module-transforms@npm:7.24.6" + dependencies: + "@babel/helper-environment-visitor": ^7.24.6 + "@babel/helper-module-imports": ^7.24.6 + "@babel/helper-simple-access": ^7.24.6 + "@babel/helper-split-export-declaration": ^7.24.6 + "@babel/helper-validator-identifier": ^7.24.6 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 904e2a0701eb1eeb84b0d0df5dacdc40291307025b7e3a9a3c6f3eee912c893524f9dc7f5624225a5783a258dec2eb2489a9638bf5f3de26ebfcbcac1b5cc2fc + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" @@ -274,6 +389,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-plugin-utils@npm:7.24.6" + checksum: d22bb82c75afed0d8c37784876fd6deb9db06ef21526db909ef7986a6050b50beb60a7823c08a1bb7c57c668af2e086d8086e88b6f9140b0d9ade07472f7c748 + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20" @@ -309,6 +431,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-simple-access@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-simple-access@npm:7.24.6" + dependencies: + "@babel/types": ^7.24.6 + checksum: 929162e887efc1bcadd4e141ed7782b45fccc6873d5023a744fee9c94d16d3a13dbfb66eb259181613a36c2d35f7d2088ee37e76014223d3b9b6c9ef1094e4b6 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0, @babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" @@ -327,6 +458,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-split-export-declaration@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-split-export-declaration@npm:7.24.6" + dependencies: + "@babel/types": ^7.24.6 + checksum: b546fd7e186b4aa69f96e041b6c4c9154115a2579a297b86773719dbed53b938cfc3f6b4996ae410296bb8aa30ea031f9ff31f1255aa25c3af75026c5b7c4059 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.23.4": version: 7.24.1 resolution: "@babel/helper-string-parser@npm:7.24.1" @@ -334,6 +474,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-string-parser@npm:7.24.6" + checksum: c8c614a663928b67c5c65cfea958ed20c858fa2af8c957d301bd852c0ab98adae0861f081fd8f5add16539d9393bd4b10b8c86a97a9d7304f70a6a67b2c2ff07 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-validator-identifier@npm:7.22.20" @@ -341,6 +488,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-validator-identifier@npm:7.24.6" + checksum: a265a6fba570332dca63ad7e749b867d29b52da2573dc62bf19b5b8c5387d4f4296af33da9da7c71ffe3d3abecd743418278f56d38b057ad4b53f09b937fe113 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.23.5": version: 7.23.5 resolution: "@babel/helper-validator-option@npm:7.23.5" @@ -348,6 +502,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helper-validator-option@npm:7.24.6" + checksum: 5defb2da74e1cac9497016f4e41698aeed75ec7a5e9dc07e777cdb67ef73cd2e27bd2bf8a3ab8d37e0b93a6a45524a9728f03e263afdef452436cf74794bde87 + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-wrap-function@npm:7.22.20" @@ -370,6 +531,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/helpers@npm:7.24.6" + dependencies: + "@babel/template": ^7.24.6 + "@babel/types": ^7.24.6 + checksum: c936058fd5caf7173e157f790fdbe9535237a7b8bc2c3d084bdf16467a034f73bd5d731deb514aa84e356c72de1cc93500a376f9d481f5c1e335f5a563426e58 + languageName: node + linkType: hard + "@babel/highlight@npm:^7.24.2": version: 7.24.2 resolution: "@babel/highlight@npm:7.24.2" @@ -382,6 +553,18 @@ __metadata: languageName: node linkType: hard +"@babel/highlight@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/highlight@npm:7.24.6" + dependencies: + "@babel/helper-validator-identifier": ^7.24.6 + chalk: ^2.4.2 + js-tokens: ^4.0.0 + picocolors: ^1.0.0 + checksum: 2f8f7f060eeccc3ddf03ba12c263995de0e6c0dd31ad224bed58d983b3bb08fe34dfc01440396266456a4cad83226c38ad6814805bc5d0c774a056cac9182eca + languageName: node + linkType: hard + "@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1": version: 7.24.1 resolution: "@babel/parser@npm:7.24.1" @@ -391,6 +574,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/parser@npm:7.24.6" + bin: + parser: ./bin/babel-parser.js + checksum: ca3773f5b2a4a065b827990ca0c867e670f01d7a7d7278838bd64d583e68ed52356b5a613303c5aa736d20f024728fec80fc5845fed1eb751ab5f1bfbdc1dd3c + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.1": version: 7.24.1 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.24.1" @@ -783,6 +975,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-jsx@npm:^7.7.2": + version: 7.24.6 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.6" + dependencies: + "@babel/helper-plugin-utils": ^7.24.6 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: e288681cab57d059b0b2e132040eb5e21a158c40229c600e77cb0289ba5d32a2102af94e43390d270e0ddd968685e9de8d10dab0291c53b84e2219a7bc4cdb54 + languageName: node + linkType: hard + "@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" @@ -1779,7 +1982,18 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.24.1, @babel/traverse@npm:^7.7.2": +"@babel/template@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/template@npm:7.24.6" + dependencies: + "@babel/code-frame": ^7.24.6 + "@babel/parser": ^7.24.6 + "@babel/types": ^7.24.6 + checksum: 8e532ebdd5e1398c030af16881061bad43b9c3b758a193a6289dc5be5988cc543f7aa56a360e15b755258c0b3d387f3cd78b505835b040a2729d0261d0ff1711 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.24.1": version: 7.24.1 resolution: "@babel/traverse@npm:7.24.1" dependencies: @@ -1797,6 +2011,24 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/traverse@npm:7.24.6" + dependencies: + "@babel/code-frame": ^7.24.6 + "@babel/generator": ^7.24.6 + "@babel/helper-environment-visitor": ^7.24.6 + "@babel/helper-function-name": ^7.24.6 + "@babel/helper-hoist-variables": ^7.24.6 + "@babel/helper-split-export-declaration": ^7.24.6 + "@babel/parser": ^7.24.6 + "@babel/types": ^7.24.6 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: 654151b2ab5c9d5031c274cf197f707b8a27a1c70b38fcb8d1bf5ad2d8848f38675ab9c2a86aeb804657c5817124ac5be4cb6f5defa8ef7ac40596e1220697aa + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.10, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.24.0 resolution: "@babel/types@npm:7.24.0" @@ -1808,6 +2040,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/types@npm:7.24.6" + dependencies: + "@babel/helper-string-parser": ^7.24.6 + "@babel/helper-validator-identifier": ^7.24.6 + to-fast-properties: ^2.0.0 + checksum: 58d798dd37e6b14f818730b4536795d68d28ccd5dc2a105fd977104789b20602be11d92cdd47cdbd48d8cce3cc0e14c7773813357ad9d5d6e94d70587eb45bf5 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -2103,6 +2346,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/aix-ppc64@npm:0.20.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/android-arm64@npm:0.19.12" @@ -2110,10 +2360,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.15.18": - version: 0.15.18 - resolution: "@esbuild/android-arm@npm:0.15.18" - conditions: os=android & cpu=arm +"@esbuild/android-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm64@npm:0.20.2" + conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -2124,6 +2374,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-arm@npm:0.20.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/android-x64@npm:0.19.12" @@ -2131,6 +2388,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/android-x64@npm:0.20.2" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/darwin-arm64@npm:0.19.12" @@ -2138,6 +2402,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-arm64@npm:0.20.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/darwin-x64@npm:0.19.12" @@ -2145,6 +2416,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/darwin-x64@npm:0.20.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/freebsd-arm64@npm:0.19.12" @@ -2152,6 +2430,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-arm64@npm:0.20.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/freebsd-x64@npm:0.19.12" @@ -2159,6 +2444,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/freebsd-x64@npm:0.20.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-arm64@npm:0.19.12" @@ -2166,6 +2458,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm64@npm:0.20.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-arm@npm:0.19.12" @@ -2173,6 +2472,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-arm@npm:0.20.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-ia32@npm:0.19.12" @@ -2180,10 +2486,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.15.18": - version: 0.15.18 - resolution: "@esbuild/linux-loong64@npm:0.15.18" - conditions: os=linux & cpu=loong64 +"@esbuild/linux-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ia32@npm:0.20.2" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2194,6 +2500,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-loong64@npm:0.20.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-mips64el@npm:0.19.12" @@ -2201,6 +2514,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-mips64el@npm:0.20.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-ppc64@npm:0.19.12" @@ -2208,6 +2528,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-ppc64@npm:0.20.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-riscv64@npm:0.19.12" @@ -2215,6 +2542,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-riscv64@npm:0.20.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-s390x@npm:0.19.12" @@ -2222,6 +2556,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-s390x@npm:0.20.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/linux-x64@npm:0.19.12" @@ -2229,6 +2570,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/linux-x64@npm:0.20.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/netbsd-x64@npm:0.19.12" @@ -2236,6 +2584,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/netbsd-x64@npm:0.20.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/openbsd-x64@npm:0.19.12" @@ -2243,6 +2598,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/openbsd-x64@npm:0.20.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/sunos-x64@npm:0.19.12" @@ -2250,6 +2612,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/sunos-x64@npm:0.20.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-arm64@npm:0.19.12" @@ -2257,6 +2626,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-arm64@npm:0.20.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-ia32@npm:0.19.12" @@ -2264,6 +2640,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-ia32@npm:0.20.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.19.12": version: 0.19.12 resolution: "@esbuild/win32-x64@npm:0.19.12" @@ -2271,6 +2654,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.20.2": + version: 0.20.2 + resolution: "@esbuild/win32-x64@npm:0.20.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" @@ -2320,11 +2710,11 @@ __metadata: "@babel/preset-typescript": ^7.17.12 "@types/react": ^18.0.12 fs-extra: ^10.1.0 - jest: ^28.1.1 + jest: ^29.7.0 lodash: ^4.17.21 prettier: 2.2.1 typescript: 4.2.4 - vite: ^3.2.10 + vite: ^5.2.12 languageName: unknown linkType: soft @@ -2370,7 +2760,7 @@ __metadata: typescript: ^4.7.4 typescript-plugin-css-modules: ^5.0.2 uuid: ^8.3.2 - vite: ^3.2.10 + vite: ^5.2.12 vite-plugin-relay: ^1.0.7 vite-plugin-rewrite-all: ^1.0.2 peerDependencies: @@ -2403,7 +2793,7 @@ __metadata: react-use: ^17.3.2 typescript: ^4.7.4 typescript-plugin-css-modules: ^5.0.2 - vite: ^3.2.10 + vite: ^5.2.12 peerDependencies: re-resizable: "*" react: "*" @@ -2472,7 +2862,7 @@ __metadata: typescript: ^4.7.4 typescript-plugin-css-modules: ^5.0.2 uuid: ^8.3.2 - vite: ^3.2.10 + vite: ^5.2.12 vite-plugin-relay: ^1.0.7 xstate: ^4.14.0 peerDependencies: @@ -2497,9 +2887,9 @@ __metadata: react-plotly.js: ^2.6.0 typescript: ^4.7.4 use-resize-observer: ^9.0.2 - vite: ^3.2.10 + vite: ^5.2.12 vite-plugin-externals: ^0.5.0 - vitest: ^0.34.6 + vitest: ^1.6.0 peerDependencies: "@mui/icons-material": "*" react-error-boundary: "*" @@ -2533,10 +2923,10 @@ __metadata: typedoc: ^0.23.21 typescript: ^4.7.4 typescript-plugin-css-modules: ^5.0.2 - vite: ^3.2.10 + vite: ^5.2.12 vite-plugin-eslint: ^1.8.1 vite-plugin-relay: ^2.0.0 - vitest: ^0.34.6 + vitest: ^1.6.0 languageName: unknown linkType: soft @@ -2547,7 +2937,7 @@ __metadata: prettier: ^2.7.1 typescript: ^4.7.4 typescript-plugin-css-modules: ^5.0.2 - vite: ^3.2.10 + vite: ^5.2.12 languageName: unknown linkType: soft @@ -2574,9 +2964,9 @@ __metadata: three: ^0.164.1 tunnel-rat: ^0.1.2 typescript: ^5.4.5 - vite: ^3.2.10 + vite: ^5.2.12 vite-plugin-externals: ^0.5.0 - vitest: ^1.5.0 + vitest: ^1.6.0 peerDependencies: "@mui/icons-material": "*" "@mui/material": "*" @@ -2607,7 +2997,7 @@ __metadata: typescript: ^4.7.4 typescript-plugin-css-modules: ^5.0.2 uuid: ^8.3.2 - vite: ^3.2.10 + vite: ^5.2.12 languageName: unknown linkType: soft @@ -2630,7 +3020,7 @@ __metadata: react-map-gl: ^7.0.18 typescript: ^4.7.4 use-resize-observer: ^9.0.2 - vite: ^3.2.10 + vite: ^5.2.12 vite-plugin-externals: ^0.5.0 peerDependencies: "@mui/icons-material": "*" @@ -2646,10 +3036,10 @@ __metadata: "@babel/preset-typescript": ^7.17.12 "@fiftyone/utilities": "workspace:^" "@types/react": ^18.0.12 - jest: ^28.1.1 + jest: ^29.7.0 prettier: 2.2.1 typescript: 4.2.4 - vite: ^3.2.10 + vite: ^5.2.12 peerDependencies: "@mui/icons-material": "*" "@mui/material": "*" @@ -2663,11 +3053,11 @@ __metadata: "@babel/preset-typescript": ^7.17.12 "@fiftyone/utilities": "workspace:^" "@types/react": ^18.0.12 - jest: ^28.1.1 + jest: ^29.7.0 moment: ^2.29.4 prettier: 2.2.1 typescript: 4.2.4 - vite: ^3.2.10 + vite: ^5.2.12 languageName: unknown linkType: soft @@ -2683,7 +3073,7 @@ __metadata: relay-compiler-language-typescript: ^15.0.1 relay-config: ^12.0.1 typescript: ^4.7.4 - vite: ^3.2.10 + vite: ^5.2.12 languageName: unknown linkType: soft @@ -2695,7 +3085,7 @@ __metadata: allotment: ^1.17.0 react-sortablejs: ^6.1.4 sortablejs: ^1.15.0 - vite: ^3.2.10 + vite: ^5.2.12 peerDependencies: "@mui/icons-material": "*" "@mui/material": "*" @@ -2720,8 +3110,8 @@ __metadata: lodash: ^4.17.21 prettier: ^2.7.1 typescript: ^4.7.4 - vite: ^3.2.10 - vitest: ^0.34.6 + vite: ^5.2.12 + vitest: ^1.6.0 peerDependencies: react: "*" react-error-boundary: "*" @@ -2743,8 +3133,8 @@ __metadata: prettier: ^2.7.1 typescript: ^4.7.4 typescript-plugin-css-modules: ^5.0.2 - vite: ^3.2.10 - vitest: ^1.4.0 + vite: ^5.2.12 + vitest: ^1.6.0 languageName: unknown linkType: soft @@ -2847,58 +3237,57 @@ __metadata: languageName: node linkType: hard -"@istanbuljs/schema@npm:^0.1.2": +"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": version: 0.1.3 resolution: "@istanbuljs/schema@npm:0.1.3" checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 languageName: node linkType: hard -"@jest/console@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/console@npm:28.1.3" +"@jest/console@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/console@npm:29.7.0" dependencies: - "@jest/types": ^28.1.3 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 - jest-message-util: ^28.1.3 - jest-util: ^28.1.3 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 slash: ^3.0.0 - checksum: fe50d98d26d02ce2901c76dff4bd5429a33c13affb692c9ebf8a578ca2f38a5dd854363d40d6c394f215150791fd1f692afd8e730a4178dda24107c8dfd9750a + checksum: 0e3624e32c5a8e7361e889db70b170876401b7d70f509a2538c31d5cd50deb0c1ae4b92dc63fe18a0902e0a48c590c21d53787a0df41a52b34fa7cab96c384d6 languageName: node linkType: hard -"@jest/core@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/core@npm:28.1.3" +"@jest/core@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/core@npm:29.7.0" dependencies: - "@jest/console": ^28.1.3 - "@jest/reporters": ^28.1.3 - "@jest/test-result": ^28.1.3 - "@jest/transform": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/console": ^29.7.0 + "@jest/reporters": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" ansi-escapes: ^4.2.1 chalk: ^4.0.0 ci-info: ^3.2.0 exit: ^0.1.2 graceful-fs: ^4.2.9 - jest-changed-files: ^28.1.3 - jest-config: ^28.1.3 - jest-haste-map: ^28.1.3 - jest-message-util: ^28.1.3 - jest-regex-util: ^28.0.2 - jest-resolve: ^28.1.3 - jest-resolve-dependencies: ^28.1.3 - jest-runner: ^28.1.3 - jest-runtime: ^28.1.3 - jest-snapshot: ^28.1.3 - jest-util: ^28.1.3 - jest-validate: ^28.1.3 - jest-watcher: ^28.1.3 + jest-changed-files: ^29.7.0 + jest-config: ^29.7.0 + jest-haste-map: ^29.7.0 + jest-message-util: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-resolve-dependencies: ^29.7.0 + jest-runner: ^29.7.0 + jest-runtime: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 + jest-watcher: ^29.7.0 micromatch: ^4.0.4 - pretty-format: ^28.1.3 - rimraf: ^3.0.0 + pretty-format: ^29.7.0 slash: ^3.0.0 strip-ansi: ^6.0.0 peerDependencies: @@ -2906,76 +3295,77 @@ __metadata: peerDependenciesMeta: node-notifier: optional: true - checksum: cb79f34bafc4637e7130df12257f5b29075892a2be2c7f45c6d4c0420853e80b5dae11016e652530eb234f4c44c00910cdca3c2cd86275721860725073f7d9b4 + checksum: af759c9781cfc914553320446ce4e47775ae42779e73621c438feb1e4231a5d4862f84b1d8565926f2d1aab29b3ec3dcfdc84db28608bdf5f29867124ebcfc0d languageName: node linkType: hard -"@jest/environment@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/environment@npm:28.1.3" +"@jest/environment@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/environment@npm:29.7.0" dependencies: - "@jest/fake-timers": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/fake-timers": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" - jest-mock: ^28.1.3 - checksum: 14c496b84aef951df33128cea68988e9de43b2e9d62be9f9c4308d4ac307fa345642813679f80d0a4cedeb900cf6f0b6bb2b92ce089528e8721f72295fdc727f + jest-mock: ^29.7.0 + checksum: 6fb398143b2543d4b9b8d1c6dbce83fa5247f84f550330604be744e24c2bd2178bb893657d62d1b97cf2f24baf85c450223f8237cccb71192c36a38ea2272934 languageName: node linkType: hard -"@jest/expect-utils@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/expect-utils@npm:28.1.3" +"@jest/expect-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect-utils@npm:29.7.0" dependencies: - jest-get-type: ^28.0.2 - checksum: 808ea3a68292a7e0b95490fdd55605c430b4cf209ea76b5b61bfb2a1badcb41bc046810fe4e364bd5fe04663978aa2bd73d8f8465a761dd7c655aeb44cf22987 + jest-get-type: ^29.6.3 + checksum: 75eb177f3d00b6331bcaa057e07c0ccb0733a1d0a1943e1d8db346779039cb7f103789f16e502f888a3096fb58c2300c38d1f3748b36a7fa762eb6f6d1b160ed languageName: node linkType: hard -"@jest/expect@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/expect@npm:28.1.3" +"@jest/expect@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect@npm:29.7.0" dependencies: - expect: ^28.1.3 - jest-snapshot: ^28.1.3 - checksum: 4197f6fdddc33dc45ba4e838f992fc61839c421d7aed0dfe665ef9c2f172bb1df8a8cac9cecee272b40e744a326da521d5e182709fe82a0b936055bfffa3b473 + expect: ^29.7.0 + jest-snapshot: ^29.7.0 + checksum: a01cb85fd9401bab3370618f4b9013b90c93536562222d920e702a0b575d239d74cecfe98010aaec7ad464f67cf534a353d92d181646a4b792acaa7e912ae55e languageName: node linkType: hard -"@jest/fake-timers@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/fake-timers@npm:28.1.3" +"@jest/fake-timers@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/fake-timers@npm:29.7.0" dependencies: - "@jest/types": ^28.1.3 - "@sinonjs/fake-timers": ^9.1.2 + "@jest/types": ^29.6.3 + "@sinonjs/fake-timers": ^10.0.2 "@types/node": "*" - jest-message-util: ^28.1.3 - jest-mock: ^28.1.3 - jest-util: ^28.1.3 - checksum: cec14d5b14913a54dce64a62912c5456235f5d90b509ceae19c727565073114dae1aaf960ac6be96b3eb94789a3a758b96b72c8fca7e49a6ccac415fbc0321e1 + jest-message-util: ^29.7.0 + jest-mock: ^29.7.0 + jest-util: ^29.7.0 + checksum: caf2bbd11f71c9241b458d1b5a66cbe95debc5a15d96442444b5d5c7ba774f523c76627c6931cca5e10e76f0d08761f6f1f01a608898f4751a0eee54fc3d8d00 languageName: node linkType: hard -"@jest/globals@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/globals@npm:28.1.3" +"@jest/globals@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/globals@npm:29.7.0" dependencies: - "@jest/environment": ^28.1.3 - "@jest/expect": ^28.1.3 - "@jest/types": ^28.1.3 - checksum: 3504bb23de629d466c6f2b6b75d2e1c1b10caccbbcfb7eaa82d22cc37711c8e364c243929581184846605c023b475ea6c42c2e3ea5994429a988d8d527af32cd + "@jest/environment": ^29.7.0 + "@jest/expect": ^29.7.0 + "@jest/types": ^29.6.3 + jest-mock: ^29.7.0 + checksum: 97dbb9459135693ad3a422e65ca1c250f03d82b2a77f6207e7fa0edd2c9d2015fbe4346f3dc9ebff1678b9d8da74754d4d440b7837497f8927059c0642a22123 languageName: node linkType: hard -"@jest/reporters@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/reporters@npm:28.1.3" +"@jest/reporters@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/reporters@npm:29.7.0" dependencies: "@bcoe/v8-coverage": ^0.2.3 - "@jest/console": ^28.1.3 - "@jest/test-result": ^28.1.3 - "@jest/transform": ^28.1.3 - "@jest/types": ^28.1.3 - "@jridgewell/trace-mapping": ^0.3.13 + "@jest/console": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + "@jridgewell/trace-mapping": ^0.3.18 "@types/node": "*" chalk: ^4.0.0 collect-v8-coverage: ^1.0.0 @@ -2983,33 +3373,23 @@ __metadata: glob: ^7.1.3 graceful-fs: ^4.2.9 istanbul-lib-coverage: ^3.0.0 - istanbul-lib-instrument: ^5.1.0 + istanbul-lib-instrument: ^6.0.0 istanbul-lib-report: ^3.0.0 istanbul-lib-source-maps: ^4.0.0 istanbul-reports: ^3.1.3 - jest-message-util: ^28.1.3 - jest-util: ^28.1.3 - jest-worker: ^28.1.3 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + jest-worker: ^29.7.0 slash: ^3.0.0 string-length: ^4.0.1 strip-ansi: ^6.0.0 - terminal-link: ^2.0.0 v8-to-istanbul: ^9.0.1 peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - checksum: a7440887ce837922cbeaa64c3232eb48aae02aa9123f29fc4280ad3e1afe4b35dcba171ba1d5fd219037c396c5152d9c2d102cff1798dd5ae3bd33ac4759ae0a - languageName: node - linkType: hard - -"@jest/schemas@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/schemas@npm:28.1.3" - dependencies: - "@sinclair/typebox": ^0.24.1 - checksum: 3cf1d4b66c9c4ffda58b246de1ddcba8e6ad085af63dccdf07922511f13b68c0cc480a7bc620cb4f3099a6f134801c747e1df7bfc7a4ef4dceefbdea3e31e1de + checksum: 7eadabd62cc344f629024b8a268ecc8367dba756152b761bdcb7b7e570a3864fc51b2a9810cd310d85e0a0173ef002ba4528d5ea0329fbf66ee2a3ada9c40455 languageName: node linkType: hard @@ -3022,75 +3402,75 @@ __metadata: languageName: node linkType: hard -"@jest/source-map@npm:^28.1.2": - version: 28.1.2 - resolution: "@jest/source-map@npm:28.1.2" +"@jest/source-map@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/source-map@npm:29.6.3" dependencies: - "@jridgewell/trace-mapping": ^0.3.13 + "@jridgewell/trace-mapping": ^0.3.18 callsites: ^3.0.0 graceful-fs: ^4.2.9 - checksum: b82a5c2e93d35d86779c61a02ccb967d1b5cd2e9dd67d26d8add44958637cbbb99daeeb8129c7653389cb440dc2a2f5ae4d2183dc453c67669ff98938b775a3a + checksum: bcc5a8697d471396c0003b0bfa09722c3cd879ad697eb9c431e6164e2ea7008238a01a07193dfe3cbb48b1d258eb7251f6efcea36f64e1ebc464ea3c03ae2deb languageName: node linkType: hard -"@jest/test-result@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/test-result@npm:28.1.3" +"@jest/test-result@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-result@npm:29.7.0" dependencies: - "@jest/console": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/console": ^29.7.0 + "@jest/types": ^29.6.3 "@types/istanbul-lib-coverage": ^2.0.0 collect-v8-coverage: ^1.0.0 - checksum: 957a5dd2fd2e84aabe86698f93c0825e96128ccaa23abf548b159a9b08ac74e4bde7acf4bec48479243dbdb27e4ea1b68c171846d21fb64855c6b55cead9ef27 + checksum: 67b6317d526e335212e5da0e768e3b8ab8a53df110361b80761353ad23b6aea4432b7c5665bdeb87658ea373b90fb1afe02ed3611ef6c858c7fba377505057fa languageName: node linkType: hard -"@jest/test-sequencer@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/test-sequencer@npm:28.1.3" +"@jest/test-sequencer@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-sequencer@npm:29.7.0" dependencies: - "@jest/test-result": ^28.1.3 + "@jest/test-result": ^29.7.0 graceful-fs: ^4.2.9 - jest-haste-map: ^28.1.3 + jest-haste-map: ^29.7.0 slash: ^3.0.0 - checksum: 13f8905e6d1ec8286694146f7be3cf90eff801bbdea5e5c403e6881444bb390ed15494c7b9948aa94bd7e9c9a851e0d3002ed6e7371d048b478596e5b23df953 + checksum: 73f43599017946be85c0b6357993b038f875b796e2f0950487a82f4ebcb115fa12131932dd9904026b4ad8be131fe6e28bd8d0aa93b1563705185f9804bff8bd languageName: node linkType: hard -"@jest/transform@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/transform@npm:28.1.3" +"@jest/transform@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/transform@npm:29.7.0" dependencies: "@babel/core": ^7.11.6 - "@jest/types": ^28.1.3 - "@jridgewell/trace-mapping": ^0.3.13 + "@jest/types": ^29.6.3 + "@jridgewell/trace-mapping": ^0.3.18 babel-plugin-istanbul: ^6.1.1 chalk: ^4.0.0 - convert-source-map: ^1.4.0 - fast-json-stable-stringify: ^2.0.0 + convert-source-map: ^2.0.0 + fast-json-stable-stringify: ^2.1.0 graceful-fs: ^4.2.9 - jest-haste-map: ^28.1.3 - jest-regex-util: ^28.0.2 - jest-util: ^28.1.3 + jest-haste-map: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-util: ^29.7.0 micromatch: ^4.0.4 pirates: ^4.0.4 slash: ^3.0.0 - write-file-atomic: ^4.0.1 - checksum: dadf618936e0aa84342f07f532801d5bed43cdf95d1417b929e4f8782c872cff1adc84096d5a287a796d0039a2691c06d8450cce5a713a8b52fbb9f872a1e760 + write-file-atomic: ^4.0.2 + checksum: 0f8ac9f413903b3cb6d240102db848f2a354f63971ab885833799a9964999dd51c388162106a807f810071f864302cdd8e3f0c241c29ce02d85a36f18f3f40ab languageName: node linkType: hard -"@jest/types@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/types@npm:28.1.3" +"@jest/types@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/types@npm:29.6.3" dependencies: - "@jest/schemas": ^28.1.3 + "@jest/schemas": ^29.6.3 "@types/istanbul-lib-coverage": ^2.0.0 "@types/istanbul-reports": ^3.0.0 "@types/node": "*" "@types/yargs": ^17.0.8 chalk: ^4.0.0 - checksum: 1e258d9c063fcf59ebc91e46d5ea5984674ac7ae6cae3e50aa780d22b4405bf2c925f40350bf30013839eb5d4b5e521d956ddf8f3b7c78debef0e75a07f57350 + checksum: a0bcf15dbb0eca6bdd8ce61a3fb055349d40268622a7670a3b2eb3c3dbafe9eb26af59938366d520b86907b9505b0f9b29b85cec11579a9e580694b87cd90fcc languageName: node linkType: hard @@ -3126,7 +3506,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.13, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": version: 0.3.25 resolution: "@jridgewell/trace-mapping@npm:0.3.25" dependencies: @@ -4582,6 +4962,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.18.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-android-arm64@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-android-arm64@npm:4.13.0" @@ -4589,6 +4976,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-android-arm64@npm:4.18.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-arm64@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-darwin-arm64@npm:4.13.0" @@ -4596,6 +4990,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.18.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-darwin-x64@npm:4.13.0" @@ -4603,13 +5004,34 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0": - version: 4.13.0 +"@rollup/rollup-darwin-x64@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.18.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0": + version: 4.13.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.13.0" conditions: os=linux & cpu=arm languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.18.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.18.0" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.13.0" @@ -4617,6 +5039,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-gnu@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.18.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-musl@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.13.0" @@ -4624,6 +5053,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.18.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.18.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-gnu@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.13.0" @@ -4631,6 +5074,20 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.18.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.18.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-gnu@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.13.0" @@ -4638,6 +5095,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-gnu@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.18.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-musl@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-linux-x64-musl@npm:4.13.0" @@ -4645,6 +5109,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.18.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-win32-arm64-msvc@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.13.0" @@ -4652,6 +5123,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.18.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-ia32-msvc@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.13.0" @@ -4659,6 +5137,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.18.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-msvc@npm:4.13.0": version: 4.13.0 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.13.0" @@ -4666,10 +5151,10 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.24.1": - version: 0.24.51 - resolution: "@sinclair/typebox@npm:0.24.51" - checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0 +"@rollup/rollup-win32-x64-msvc@npm:4.18.0": + version: 4.18.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.18.0" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4687,21 +5172,21 @@ __metadata: languageName: node linkType: hard -"@sinonjs/commons@npm:^1.7.0": - version: 1.8.6 - resolution: "@sinonjs/commons@npm:1.8.6" +"@sinonjs/commons@npm:^3.0.0": + version: 3.0.1 + resolution: "@sinonjs/commons@npm:3.0.1" dependencies: type-detect: 4.0.8 - checksum: 7d3f8c1e85f30cd4e83594fc19b7a657f14d49eb8d95a30095631ce15e906c869e0eff96c5b93dffea7490c00418b07f54582ba49c6560feb2a8c34c0b16832d + checksum: a7c3e7cc612352f4004873747d9d8b2d4d90b13a6d483f685598c945a70e734e255f1ca5dc49702515533c403b32725defff148177453b3f3915bcb60e9d4601 languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^9.1.2": - version: 9.1.2 - resolution: "@sinonjs/fake-timers@npm:9.1.2" +"@sinonjs/fake-timers@npm:^10.0.2": + version: 10.3.0 + resolution: "@sinonjs/fake-timers@npm:10.3.0" dependencies: - "@sinonjs/commons": ^1.7.0 - checksum: 7d3aef54e17c1073101cb64d953157c19d62a40e261a30923fa1ee337b049c5f29cc47b1f0c477880f42b5659848ba9ab897607ac8ea4acd5c30ddcfac57fca6 + "@sinonjs/commons": ^3.0.0 + checksum: 614d30cb4d5201550c940945d44c9e0b6d64a888ff2cd5b357f95ad6721070d6b8839cd10e15b76bf5e14af0bcc1d8f9ec00d49a46318f1f669a4bec1d7f3148 languageName: node linkType: hard @@ -4954,22 +5439,6 @@ __metadata: languageName: node linkType: hard -"@types/chai-subset@npm:^1.3.3": - version: 1.3.5 - resolution: "@types/chai-subset@npm:1.3.5" - dependencies: - "@types/chai": "*" - checksum: 715c46d3e90f87482c2769389d560456bb257b225716ff44c275c231bdb62c8a30629f355f412bac0ecab07ebc036c1806d9ed9dde9792254f8ef4f07f76033b - languageName: node - linkType: hard - -"@types/chai@npm:*, @types/chai@npm:^4.3.5": - version: 4.3.13 - resolution: "@types/chai@npm:4.3.13" - checksum: 90b4ce7fd61eeb5159409f1a06cce6383c64354ce287b5cc6b5562a3bae6fb248e377f48b4bdcc8e8c545fd41b9b9cfbe6caf8bc7236eafd557b6157db19b58d - languageName: node - linkType: hard - "@types/color-string@npm:^1.5.0": version: 1.5.5 resolution: "@types/color-string@npm:1.5.5" @@ -5322,13 +5791,6 @@ __metadata: languageName: node linkType: hard -"@types/prettier@npm:^2.1.5": - version: 2.7.3 - resolution: "@types/prettier@npm:2.7.3" - checksum: 705384209cea6d1433ff6c187c80dcc0b95d99d5c5ce21a46a9a58060c527973506822e428789d842761e0280d25e3359300f017fbe77b9755bc772ab3dc2f83 - languageName: node - linkType: hard - "@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.11": version: 15.7.11 resolution: "@types/prop-types@npm:15.7.11" @@ -5848,129 +6310,45 @@ __metadata: languageName: node linkType: hard -"@vitest/expect@npm:0.34.6": - version: 0.34.6 - resolution: "@vitest/expect@npm:0.34.6" - dependencies: - "@vitest/spy": 0.34.6 - "@vitest/utils": 0.34.6 - chai: ^4.3.10 - checksum: 37a526f4af7e73fc56b71ba1139d6d93ff1972315d0e0691de967179298d2ad086e8803d2b28defe0e97a1326d808cd886e4b802d1691d8894cb234e35ed5185 - languageName: node - linkType: hard - -"@vitest/expect@npm:1.4.0": - version: 1.4.0 - resolution: "@vitest/expect@npm:1.4.0" - dependencies: - "@vitest/spy": 1.4.0 - "@vitest/utils": 1.4.0 - chai: ^4.3.10 - checksum: aca8b0b592bc020febb08767a230a2f4118453904972df06b2a34c76a669e8eb260ddfd8b0cdc152e93dbf21e0d7ae98bdf09fa80477b21145ac21c01fc5a0d3 - languageName: node - linkType: hard - -"@vitest/expect@npm:1.5.0": - version: 1.5.0 - resolution: "@vitest/expect@npm:1.5.0" +"@vitest/expect@npm:1.6.0": + version: 1.6.0 + resolution: "@vitest/expect@npm:1.6.0" dependencies: - "@vitest/spy": 1.5.0 - "@vitest/utils": 1.5.0 + "@vitest/spy": 1.6.0 + "@vitest/utils": 1.6.0 chai: ^4.3.10 - checksum: a2a5659fbe7a2b7ff38dc9a43a75e0cf50c1a82ab98d1553ce114f48894937f34b541c620970b5afc5bd90a3c02a900f65f8b811fcd4ad77391cdd26d51285d0 - languageName: node - linkType: hard - -"@vitest/runner@npm:0.34.6": - version: 0.34.6 - resolution: "@vitest/runner@npm:0.34.6" - dependencies: - "@vitest/utils": 0.34.6 - p-limit: ^4.0.0 - pathe: ^1.1.1 - checksum: 0357f0a11f4e1e170099f9125e379bbe8049a59faa7b34b919b3e5ee8927f30824c2b3ebb814b6a77c75ec35a30bf9adb8ec2b5e051525b4edd0d17be15725cc + checksum: f3a9959ea387622297efed9e3689fd405044a813df5d5923302eaaea831e250d8d6a0ccd44fb387a95c19963242695ed803afc7c46ae06c48a8e06f194951984 languageName: node linkType: hard -"@vitest/runner@npm:1.4.0": - version: 1.4.0 - resolution: "@vitest/runner@npm:1.4.0" - dependencies: - "@vitest/utils": 1.4.0 - p-limit: ^5.0.0 - pathe: ^1.1.1 - checksum: 41a847d1ba916c64e482a69342222a40b81014ad06da7ccb7d8cd4119c5718564c22b00367574803642e6ca6ab5678509073b5c460bedc2b385d4e990351012f - languageName: node - linkType: hard - -"@vitest/runner@npm:1.5.0": - version: 1.5.0 - resolution: "@vitest/runner@npm:1.5.0" +"@vitest/runner@npm:1.6.0": + version: 1.6.0 + resolution: "@vitest/runner@npm:1.6.0" dependencies: - "@vitest/utils": 1.5.0 + "@vitest/utils": 1.6.0 p-limit: ^5.0.0 pathe: ^1.1.1 - checksum: 3680a9d4f16f635208d75aa2f62cdc02bcfe648771812febbe87a79e644e6e8fa58fbbdd0976693096929d59c9d672f5211131ef7103a1e9c250b7a61a9fd4fb - languageName: node - linkType: hard - -"@vitest/snapshot@npm:0.34.6": - version: 0.34.6 - resolution: "@vitest/snapshot@npm:0.34.6" - dependencies: - magic-string: ^0.30.1 - pathe: ^1.1.1 - pretty-format: ^29.5.0 - checksum: c2f164b23741cdf10f449575a0f9996cf385675d0f76d2eb696f53b614743811f2fbefdc5eb0fd3f9544ccfbb566d57a5c50a70595167458579d56429b09151f - languageName: node - linkType: hard - -"@vitest/snapshot@npm:1.4.0": - version: 1.4.0 - resolution: "@vitest/snapshot@npm:1.4.0" - dependencies: - magic-string: ^0.30.5 - pathe: ^1.1.1 - pretty-format: ^29.7.0 - checksum: fe495661d682534b41f3ac373c017ac84c04263087a715307715bb41a69c307d6f237b18cc8195bc22d82bf38a1a1a773b0c99715d5de5f40c6169e916b8f4a4 + checksum: 2dcd953477d5effc051376e35a7f2c2b28abbe07c54e61157c9a6d6f01c880e079592c959397b3a55471423256ab91709c150881a33632558b81b1e251a0bf9c languageName: node linkType: hard -"@vitest/snapshot@npm:1.5.0": - version: 1.5.0 - resolution: "@vitest/snapshot@npm:1.5.0" +"@vitest/snapshot@npm:1.6.0": + version: 1.6.0 + resolution: "@vitest/snapshot@npm:1.6.0" dependencies: magic-string: ^0.30.5 pathe: ^1.1.1 pretty-format: ^29.7.0 - checksum: fcf93d06c7bc781cc85b18120bf5da355d9ed6a44aa0bbaee88dc8aa27a33c51707504b3506dffb1476ad351fe84d47186641f07a6d28c484c7725747cdf0f2c - languageName: node - linkType: hard - -"@vitest/spy@npm:0.34.6": - version: 0.34.6 - resolution: "@vitest/spy@npm:0.34.6" - dependencies: - tinyspy: ^2.1.1 - checksum: b05e5906f2f489a3234a0380a21cb48635915aa7f28eac92a595e78e9ceefb95340311635e39684b32fff20f9c58fdc33488eeddee39a660cd94c9c6bc2febf7 - languageName: node - linkType: hard - -"@vitest/spy@npm:1.4.0": - version: 1.4.0 - resolution: "@vitest/spy@npm:1.4.0" - dependencies: - tinyspy: ^2.2.0 - checksum: 3b1c422760e5840e9e4aa804de7619f3d14e0b364b29f8f030df528206b84c5706792c5d680ac668077d5663f8648a17a783df11cd90ddf2a11000359f1a6286 + checksum: c4249fbf3ce310de86a19529a0a5c10b1bde4d8d8a678029c632335969b86cbdbf51cedc20d5e9c9328afee834d13cec1b8de5d0fd58139bf8e2dd8dcd0797f4 languageName: node linkType: hard -"@vitest/spy@npm:1.5.0": - version: 1.5.0 - resolution: "@vitest/spy@npm:1.5.0" +"@vitest/spy@npm:1.6.0": + version: 1.6.0 + resolution: "@vitest/spy@npm:1.6.0" dependencies: tinyspy: ^2.2.0 - checksum: 518c847bb129f266b9cd164c0021a4497c8a1ca8d2f1dd995b3aac55186f41926f7b0d966313b5093b0b32ad02547b58917376e71cd8a6f6b88845be8c8bd26f + checksum: 0201975232255e1197f70fc6b23a1ff5e606138a5b96598fff06077d5b747705391013ee98f951affcfd8f54322e4ae1416200393248bb6a9c794f4ef663a066 languageName: node linkType: hard @@ -5991,17 +6369,6 @@ __metadata: languageName: node linkType: hard -"@vitest/utils@npm:0.34.6": - version: 0.34.6 - resolution: "@vitest/utils@npm:0.34.6" - dependencies: - diff-sequences: ^29.4.3 - loupe: ^2.3.6 - pretty-format: ^29.5.0 - checksum: acf716af2bab66037e49bd6d3e8bae40b605b9bff515d4926c46d6f8cc2366decfac5a1756ea55029968e71fba1da1f992764c3a57c9b46eccce3f6db7197bd6 - languageName: node - linkType: hard - "@vitest/utils@npm:0.34.7": version: 0.34.7 resolution: "@vitest/utils@npm:0.34.7" @@ -6013,27 +6380,15 @@ __metadata: languageName: node linkType: hard -"@vitest/utils@npm:1.4.0": - version: 1.4.0 - resolution: "@vitest/utils@npm:1.4.0" - dependencies: - diff-sequences: ^29.6.3 - estree-walker: ^3.0.3 - loupe: ^2.3.7 - pretty-format: ^29.7.0 - checksum: 5b54e36e5ad236da1da548d31e3b080d1798179f787cfb9ac512d03e59401f8baaa96fec15b6de6b969ee0e057660289109a69a39bd988e89aa72625b5f78484 - languageName: node - linkType: hard - -"@vitest/utils@npm:1.5.0": - version: 1.5.0 - resolution: "@vitest/utils@npm:1.5.0" +"@vitest/utils@npm:1.6.0": + version: 1.6.0 + resolution: "@vitest/utils@npm:1.6.0" dependencies: diff-sequences: ^29.6.3 estree-walker: ^3.0.3 loupe: ^2.3.7 pretty-format: ^29.7.0 - checksum: 07a59b62b4d8110e6af6a709da2c0bb80bf60944186b544b02dfacc08bc26af36f4ec008e1ce7a0df4a8c27fd278938582241ccbd45dd7f4979cf5fec1f9f549 + checksum: a4749533a48e7e4bbc8eafee0fee0e9a0d4eaa4910fbdb490d34e16f8ebcce59a2b38529b9e6b4578e3b4510ea67b29384c93165712b0a19f2e71946922d2c56 languageName: node linkType: hard @@ -6159,7 +6514,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.2.0, acorn-walk@npm:^8.3.2": +"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.3.2": version: 8.3.2 resolution: "acorn-walk@npm:8.3.2" checksum: 3626b9d26a37b1b427796feaa5261faf712307a8920392c8dce9a5739fb31077667f4ad2ec71c7ac6aaf9f61f04a9d3d67ff56f459587206fc04aa31c27ef392 @@ -6175,7 +6530,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.1.0, acorn@npm:^8.10.0, acorn@npm:^8.11.3, acorn@npm:^8.4.0, acorn@npm:^8.8.1, acorn@npm:^8.9.0": +"acorn@npm:^8.1.0, acorn@npm:^8.11.3, acorn@npm:^8.4.0, acorn@npm:^8.8.1, acorn@npm:^8.9.0": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -6631,20 +6986,20 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^28.1.3": - version: 28.1.3 - resolution: "babel-jest@npm:28.1.3" +"babel-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "babel-jest@npm:29.7.0" dependencies: - "@jest/transform": ^28.1.3 + "@jest/transform": ^29.7.0 "@types/babel__core": ^7.1.14 babel-plugin-istanbul: ^6.1.1 - babel-preset-jest: ^28.1.3 + babel-preset-jest: ^29.6.3 chalk: ^4.0.0 graceful-fs: ^4.2.9 slash: ^3.0.0 peerDependencies: "@babel/core": ^7.8.0 - checksum: 57ccd2296e1839687b5df2fd138c3d00717e0369e385254b012ccd4ee70e75f5d5c8e6cfcdf92d155015b468cfebb847b38e69bb5805d8aaf730e20575127cc6 + checksum: ee6f8e0495afee07cac5e4ee167be705c711a8cc8a737e05a587a131fdae2b3c8f9aa55dfd4d9c03009ac2d27f2de63d8ba96d3e8460da4d00e8af19ef9a83f7 languageName: node linkType: hard @@ -6661,15 +7016,15 @@ __metadata: languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:^28.1.3": - version: 28.1.3 - resolution: "babel-plugin-jest-hoist@npm:28.1.3" +"babel-plugin-jest-hoist@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-plugin-jest-hoist@npm:29.6.3" dependencies: "@babel/template": ^7.3.3 "@babel/types": ^7.3.3 "@types/babel__core": ^7.1.14 "@types/babel__traverse": ^7.0.6 - checksum: 648d89f9d80f6450ce7e50d0c32eb91b7f26269b47c3e37aaf2e0f2f66a980978345bd6b8c9b8c3aa6a8252ad2bc2c9fb50630e9895622c9a0972af5f70ed20e + checksum: 51250f22815a7318f17214a9d44650ba89551e6d4f47a2dc259128428324b52f5a73979d010cefd921fd5a720d8c1d55ad74ff601cd94c7bd44d5f6292fde2d1 languageName: node linkType: hard @@ -6775,15 +7130,15 @@ __metadata: languageName: node linkType: hard -"babel-preset-jest@npm:^28.1.3": - version: 28.1.3 - resolution: "babel-preset-jest@npm:28.1.3" +"babel-preset-jest@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-preset-jest@npm:29.6.3" dependencies: - babel-plugin-jest-hoist: ^28.1.3 + babel-plugin-jest-hoist: ^29.6.3 babel-preset-current-node-syntax: ^1.0.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 8248a4a5ca4242cc06ad13b10b9183ad2664da8fb0da060c352223dcf286f0ce9c708fa17901dc44ecabec25e6d309e5e5b9830a61dd777c3925f187a345a47d + checksum: aa4ff2a8a728d9d698ed521e3461a109a1e66202b13d3494e41eea30729a5e7cc03b3a2d56c594423a135429c37bf63a9fa8b0b9ce275298be3095a88c69f6fb languageName: node linkType: hard @@ -7685,7 +8040,7 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.5.0": +"convert-source-map@npm:^1.5.0": version: 1.9.0 resolution: "convert-source-map@npm:1.9.0" checksum: dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8 @@ -7794,6 +8149,23 @@ __metadata: languageName: node linkType: hard +"create-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "create-jest@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + chalk: ^4.0.0 + exit: ^0.1.2 + graceful-fs: ^4.2.9 + jest-config: ^29.7.0 + jest-util: ^29.7.0 + prompts: ^2.0.1 + bin: + create-jest: bin/create-jest.js + checksum: 1427d49458adcd88547ef6fa39041e1fe9033a661293aa8d2c3aa1b4967cb5bf4f0c00436c7a61816558f28ba2ba81a94d5c962e8022ea9a883978fc8e1f2945 + languageName: node + linkType: hard + "cross-env@npm:^7.0.3": version: 7.0.3 resolution: "cross-env@npm:7.0.3" @@ -8359,10 +8731,15 @@ __metadata: languageName: node linkType: hard -"dedent@npm:^0.7.0": - version: 0.7.0 - resolution: "dedent@npm:0.7.0" - checksum: 87de191050d9a40dd70cad01159a0bcf05ecb59750951242070b6abf9569088684880d00ba92a955b4058804f16eeaf91d604f283929b4f614d181cd7ae633d2 +"dedent@npm:^1.0.0": + version: 1.5.3 + resolution: "dedent@npm:1.5.3" + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + checksum: 045b595557b2a8ea2eb9b0b4623d764e9a87326486fe2b61191b4342ed93dc01245644d8a09f3108a50c0ee7965f1eedd92e4a3a503ed89ea8e810566ea27f9a languageName: node linkType: hard @@ -8495,13 +8872,6 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^28.1.1": - version: 28.1.1 - resolution: "diff-sequences@npm:28.1.1" - checksum: e2529036505567c7ca5a2dea86b6bcd1ca0e3ae63bf8ebf529b8a99cfa915bbf194b7021dc1c57361a4017a6d95578d4ceb29fabc3232a4f4cb866a2726c7690 - languageName: node - linkType: hard - "diff-sequences@npm:^29.4.3, diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" @@ -8789,10 +9159,10 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^0.10.2": - version: 0.10.2 - resolution: "emittery@npm:0.10.2" - checksum: ee3e21788b043b90885b18ea756ec3105c1cedc50b29709c92b01e239c7e55345d4bb6d3aef4ddbaf528eef448a40b3bb831bad9ee0fc9c25cbf1367ab1ab5ac +"emittery@npm:^0.13.1": + version: 0.13.1 + resolution: "emittery@npm:0.13.1" + checksum: 2b089ab6306f38feaabf4f6f02792f9ec85fc054fda79f44f6790e61bbf6bc4e1616afb9b232e0c5ec5289a8a452f79bfa6d905a6fd64e94b49981f0934001c6 languageName: node linkType: hard @@ -9086,250 +9456,113 @@ __metadata: languageName: node linkType: hard -"esbuild-android-64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-android-64@npm:0.15.18" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - -"esbuild-android-arm64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-android-arm64@npm:0.15.18" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-darwin-64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-darwin-64@npm:0.15.18" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"esbuild-darwin-arm64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-darwin-arm64@npm:0.15.18" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-freebsd-64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-freebsd-64@npm:0.15.18" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-freebsd-arm64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-freebsd-arm64@npm:0.15.18" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-linux-32@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-linux-32@npm:0.15.18" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - -"esbuild-linux-64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-linux-64@npm:0.15.18" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"esbuild-linux-arm64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-linux-arm64@npm:0.15.18" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-linux-arm@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-linux-arm@npm:0.15.18" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"esbuild-linux-mips64le@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-linux-mips64le@npm:0.15.18" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"esbuild-linux-ppc64le@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-linux-ppc64le@npm:0.15.18" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"esbuild-linux-riscv64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-linux-riscv64@npm:0.15.18" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"esbuild-linux-s390x@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-linux-s390x@npm:0.15.18" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"esbuild-netbsd-64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-netbsd-64@npm:0.15.18" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-openbsd-64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-openbsd-64@npm:0.15.18" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-sunos-64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-sunos-64@npm:0.15.18" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"esbuild-windows-32@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-windows-32@npm:0.15.18" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"esbuild-windows-64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-windows-64@npm:0.15.18" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"esbuild-windows-arm64@npm:0.15.18": - version: 0.15.18 - resolution: "esbuild-windows-arm64@npm:0.15.18" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"esbuild@npm:^0.15.9": - version: 0.15.18 - resolution: "esbuild@npm:0.15.18" - dependencies: - "@esbuild/android-arm": 0.15.18 - "@esbuild/linux-loong64": 0.15.18 - esbuild-android-64: 0.15.18 - esbuild-android-arm64: 0.15.18 - esbuild-darwin-64: 0.15.18 - esbuild-darwin-arm64: 0.15.18 - esbuild-freebsd-64: 0.15.18 - esbuild-freebsd-arm64: 0.15.18 - esbuild-linux-32: 0.15.18 - esbuild-linux-64: 0.15.18 - esbuild-linux-arm: 0.15.18 - esbuild-linux-arm64: 0.15.18 - esbuild-linux-mips64le: 0.15.18 - esbuild-linux-ppc64le: 0.15.18 - esbuild-linux-riscv64: 0.15.18 - esbuild-linux-s390x: 0.15.18 - esbuild-netbsd-64: 0.15.18 - esbuild-openbsd-64: 0.15.18 - esbuild-sunos-64: 0.15.18 - esbuild-windows-32: 0.15.18 - esbuild-windows-64: 0.15.18 - esbuild-windows-arm64: 0.15.18 +"esbuild@npm:^0.19.3": + version: 0.19.12 + resolution: "esbuild@npm:0.19.12" + dependencies: + "@esbuild/aix-ppc64": 0.19.12 + "@esbuild/android-arm": 0.19.12 + "@esbuild/android-arm64": 0.19.12 + "@esbuild/android-x64": 0.19.12 + "@esbuild/darwin-arm64": 0.19.12 + "@esbuild/darwin-x64": 0.19.12 + "@esbuild/freebsd-arm64": 0.19.12 + "@esbuild/freebsd-x64": 0.19.12 + "@esbuild/linux-arm": 0.19.12 + "@esbuild/linux-arm64": 0.19.12 + "@esbuild/linux-ia32": 0.19.12 + "@esbuild/linux-loong64": 0.19.12 + "@esbuild/linux-mips64el": 0.19.12 + "@esbuild/linux-ppc64": 0.19.12 + "@esbuild/linux-riscv64": 0.19.12 + "@esbuild/linux-s390x": 0.19.12 + "@esbuild/linux-x64": 0.19.12 + "@esbuild/netbsd-x64": 0.19.12 + "@esbuild/openbsd-x64": 0.19.12 + "@esbuild/sunos-x64": 0.19.12 + "@esbuild/win32-arm64": 0.19.12 + "@esbuild/win32-ia32": 0.19.12 + "@esbuild/win32-x64": 0.19.12 dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true "@esbuild/android-arm": optional: true - "@esbuild/linux-loong64": + "@esbuild/android-arm64": optional: true - esbuild-android-64: + "@esbuild/android-x64": optional: true - esbuild-android-arm64: + "@esbuild/darwin-arm64": optional: true - esbuild-darwin-64: + "@esbuild/darwin-x64": optional: true - esbuild-darwin-arm64: + "@esbuild/freebsd-arm64": optional: true - esbuild-freebsd-64: + "@esbuild/freebsd-x64": optional: true - esbuild-freebsd-arm64: + "@esbuild/linux-arm": optional: true - esbuild-linux-32: + "@esbuild/linux-arm64": optional: true - esbuild-linux-64: + "@esbuild/linux-ia32": optional: true - esbuild-linux-arm: + "@esbuild/linux-loong64": optional: true - esbuild-linux-arm64: + "@esbuild/linux-mips64el": optional: true - esbuild-linux-mips64le: + "@esbuild/linux-ppc64": optional: true - esbuild-linux-ppc64le: + "@esbuild/linux-riscv64": optional: true - esbuild-linux-riscv64: + "@esbuild/linux-s390x": optional: true - esbuild-linux-s390x: + "@esbuild/linux-x64": optional: true - esbuild-netbsd-64: + "@esbuild/netbsd-x64": optional: true - esbuild-openbsd-64: + "@esbuild/openbsd-x64": optional: true - esbuild-sunos-64: + "@esbuild/sunos-x64": optional: true - esbuild-windows-32: + "@esbuild/win32-arm64": optional: true - esbuild-windows-64: + "@esbuild/win32-ia32": optional: true - esbuild-windows-arm64: + "@esbuild/win32-x64": optional: true bin: esbuild: bin/esbuild - checksum: ec12682b2cb2d4f0669d0e555028b87a9284ca7f6a1b26e35e69a8697165b35cc682ad598abc70f0bbcfdc12ca84ef888caf5ceee389237862e8f8c17da85f89 + checksum: 2936e29107b43e65a775b78b7bc66ddd7d76febd73840ac7e825fb22b65029422ff51038a08d19b05154f543584bd3afe7d1ef1c63900429475b17fbe61cb61f languageName: node linkType: hard - -"esbuild@npm:^0.19.3": - version: 0.19.12 - resolution: "esbuild@npm:0.19.12" - dependencies: - "@esbuild/aix-ppc64": 0.19.12 - "@esbuild/android-arm": 0.19.12 - "@esbuild/android-arm64": 0.19.12 - "@esbuild/android-x64": 0.19.12 - "@esbuild/darwin-arm64": 0.19.12 - "@esbuild/darwin-x64": 0.19.12 - "@esbuild/freebsd-arm64": 0.19.12 - "@esbuild/freebsd-x64": 0.19.12 - "@esbuild/linux-arm": 0.19.12 - "@esbuild/linux-arm64": 0.19.12 - "@esbuild/linux-ia32": 0.19.12 - "@esbuild/linux-loong64": 0.19.12 - "@esbuild/linux-mips64el": 0.19.12 - "@esbuild/linux-ppc64": 0.19.12 - "@esbuild/linux-riscv64": 0.19.12 - "@esbuild/linux-s390x": 0.19.12 - "@esbuild/linux-x64": 0.19.12 - "@esbuild/netbsd-x64": 0.19.12 - "@esbuild/openbsd-x64": 0.19.12 - "@esbuild/sunos-x64": 0.19.12 - "@esbuild/win32-arm64": 0.19.12 - "@esbuild/win32-ia32": 0.19.12 - "@esbuild/win32-x64": 0.19.12 + +"esbuild@npm:^0.20.1": + version: 0.20.2 + resolution: "esbuild@npm:0.20.2" + dependencies: + "@esbuild/aix-ppc64": 0.20.2 + "@esbuild/android-arm": 0.20.2 + "@esbuild/android-arm64": 0.20.2 + "@esbuild/android-x64": 0.20.2 + "@esbuild/darwin-arm64": 0.20.2 + "@esbuild/darwin-x64": 0.20.2 + "@esbuild/freebsd-arm64": 0.20.2 + "@esbuild/freebsd-x64": 0.20.2 + "@esbuild/linux-arm": 0.20.2 + "@esbuild/linux-arm64": 0.20.2 + "@esbuild/linux-ia32": 0.20.2 + "@esbuild/linux-loong64": 0.20.2 + "@esbuild/linux-mips64el": 0.20.2 + "@esbuild/linux-ppc64": 0.20.2 + "@esbuild/linux-riscv64": 0.20.2 + "@esbuild/linux-s390x": 0.20.2 + "@esbuild/linux-x64": 0.20.2 + "@esbuild/netbsd-x64": 0.20.2 + "@esbuild/openbsd-x64": 0.20.2 + "@esbuild/sunos-x64": 0.20.2 + "@esbuild/win32-arm64": 0.20.2 + "@esbuild/win32-ia32": 0.20.2 + "@esbuild/win32-x64": 0.20.2 dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -9379,7 +9612,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 2936e29107b43e65a775b78b7bc66ddd7d76febd73840ac7e825fb22b65029422ff51038a08d19b05154f543584bd3afe7d1ef1c63900429475b17fbe61cb61f + checksum: bc88050fc1ca5c1bd03648f9979e514bdefb956a63aa3974373bb7b9cbac0b3aac9b9da1b5bdca0b3490e39d6b451c72815dbd6b7d7f978c91fbe9c9e9aa4e4c languageName: node linkType: hard @@ -9748,16 +9981,16 @@ __metadata: languageName: node linkType: hard -"expect@npm:^28.1.3": - version: 28.1.3 - resolution: "expect@npm:28.1.3" +"expect@npm:^29.7.0": + version: 29.7.0 + resolution: "expect@npm:29.7.0" dependencies: - "@jest/expect-utils": ^28.1.3 - jest-get-type: ^28.0.2 - jest-matcher-utils: ^28.1.3 - jest-message-util: ^28.1.3 - jest-util: ^28.1.3 - checksum: 101e0090de300bcafedb7dbfd19223368a2251ce5fe0105bbb6de5720100b89fb6b64290ebfb42febc048324c76d6a4979cdc4b61eb77747857daf7a5de9b03d + "@jest/expect-utils": ^29.7.0 + jest-get-type: ^29.6.3 + jest-matcher-utils: ^29.7.0 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + checksum: 9257f10288e149b81254a0fda8ffe8d54a7061cd61d7515779998b012579d2b8c22354b0eb901daf0145f347403da582f75f359f4810c007182ad3fb318b5c0c languageName: node linkType: hard @@ -9880,7 +10113,7 @@ __metadata: languageName: node linkType: hard -"fast-json-stable-stringify@npm:^2.0.0": +"fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: b191531e36c607977e5b1c47811158733c34ccb3bfde92c44798929e9b4154884378536d26ad90dfecd32e1ffc09c545d23535ad91b3161a27ddbb8ebe0cbecb @@ -11882,7 +12115,7 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-instrument@npm:^5.0.4, istanbul-lib-instrument@npm:^5.1.0": +"istanbul-lib-instrument@npm:^5.0.4": version: 5.2.1 resolution: "istanbul-lib-instrument@npm:5.2.1" dependencies: @@ -11895,6 +12128,19 @@ __metadata: languageName: node linkType: hard +"istanbul-lib-instrument@npm:^6.0.0": + version: 6.0.2 + resolution: "istanbul-lib-instrument@npm:6.0.2" + dependencies: + "@babel/core": ^7.23.9 + "@babel/parser": ^7.23.9 + "@istanbuljs/schema": ^0.1.3 + istanbul-lib-coverage: ^3.2.0 + semver: ^7.5.4 + checksum: c10aa1e93a022f9767d7f41e6c07d244cc0a5c090fbb5522d70a5f21fcb98c52b7038850276c6fd1a7a17d1868c14a9d4eb8a24efe58a0ebb9a06f3da68131fe + languageName: node + linkType: hard + "istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1": version: 3.0.1 resolution: "istanbul-lib-report@npm:3.0.1" @@ -11985,58 +12231,59 @@ __metadata: languageName: node linkType: hard -"jest-changed-files@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-changed-files@npm:28.1.3" +"jest-changed-files@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-changed-files@npm:29.7.0" dependencies: execa: ^5.0.0 + jest-util: ^29.7.0 p-limit: ^3.1.0 - checksum: c78af14a68b9b19101623ae7fde15a2488f9b3dbe8cca12a05c4a223bc9bfd3bf41ee06830f20fb560c52434435d6153c9cc6cf450b1f7b03e5e7f96a953a6a6 + checksum: 963e203893c396c5dfc75e00a49426688efea7361b0f0e040035809cecd2d46b3c01c02be2d9e8d38b1138357d2de7719ea5b5be21f66c10f2e9685a5a73bb99 languageName: node linkType: hard -"jest-circus@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-circus@npm:28.1.3" +"jest-circus@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-circus@npm:29.7.0" dependencies: - "@jest/environment": ^28.1.3 - "@jest/expect": ^28.1.3 - "@jest/test-result": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/environment": ^29.7.0 + "@jest/expect": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 - dedent: ^0.7.0 + dedent: ^1.0.0 is-generator-fn: ^2.0.0 - jest-each: ^28.1.3 - jest-matcher-utils: ^28.1.3 - jest-message-util: ^28.1.3 - jest-runtime: ^28.1.3 - jest-snapshot: ^28.1.3 - jest-util: ^28.1.3 + jest-each: ^29.7.0 + jest-matcher-utils: ^29.7.0 + jest-message-util: ^29.7.0 + jest-runtime: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 p-limit: ^3.1.0 - pretty-format: ^28.1.3 + pretty-format: ^29.7.0 + pure-rand: ^6.0.0 slash: ^3.0.0 stack-utils: ^2.0.3 - checksum: b635e60a9c92adaefc3f24def8eba691e7c2fdcf6c9fa640cddf2eb8c8b26ee62eab73ebb88798fd7c52a74c1495a984e39b748429b610426f02e9d3d56e09b2 + checksum: 349437148924a5a109c9b8aad6d393a9591b4dac1918fc97d81b7fc515bc905af9918495055071404af1fab4e48e4b04ac3593477b1d5dcf48c4e71b527c70a7 languageName: node linkType: hard -"jest-cli@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-cli@npm:28.1.3" +"jest-cli@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-cli@npm:29.7.0" dependencies: - "@jest/core": ^28.1.3 - "@jest/test-result": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/core": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 chalk: ^4.0.0 + create-jest: ^29.7.0 exit: ^0.1.2 - graceful-fs: ^4.2.9 import-local: ^3.0.2 - jest-config: ^28.1.3 - jest-util: ^28.1.3 - jest-validate: ^28.1.3 - prompts: ^2.0.1 + jest-config: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 yargs: ^17.3.1 peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -12045,34 +12292,34 @@ __metadata: optional: true bin: jest: bin/jest.js - checksum: fb424576bf38346318daddee3fcc597cd78cb8dda1759d09c529d8ba1a748f2765c17b00671072a838826e59465a810ff8a232bc6ba2395c131bf3504425a363 + checksum: 664901277a3f5007ea4870632ed6e7889db9da35b2434e7cb488443e6bf5513889b344b7fddf15112135495b9875892b156faeb2d7391ddb9e2a849dcb7b6c36 languageName: node linkType: hard -"jest-config@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-config@npm:28.1.3" +"jest-config@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-config@npm:29.7.0" dependencies: "@babel/core": ^7.11.6 - "@jest/test-sequencer": ^28.1.3 - "@jest/types": ^28.1.3 - babel-jest: ^28.1.3 + "@jest/test-sequencer": ^29.7.0 + "@jest/types": ^29.6.3 + babel-jest: ^29.7.0 chalk: ^4.0.0 ci-info: ^3.2.0 deepmerge: ^4.2.2 glob: ^7.1.3 graceful-fs: ^4.2.9 - jest-circus: ^28.1.3 - jest-environment-node: ^28.1.3 - jest-get-type: ^28.0.2 - jest-regex-util: ^28.0.2 - jest-resolve: ^28.1.3 - jest-runner: ^28.1.3 - jest-util: ^28.1.3 - jest-validate: ^28.1.3 + jest-circus: ^29.7.0 + jest-environment-node: ^29.7.0 + jest-get-type: ^29.6.3 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-runner: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 micromatch: ^4.0.4 parse-json: ^5.2.0 - pretty-format: ^28.1.3 + pretty-format: ^29.7.0 slash: ^3.0.0 strip-json-comments: ^3.1.1 peerDependencies: @@ -12083,134 +12330,135 @@ __metadata: optional: true ts-node: optional: true - checksum: ddabffd3a3a8cb6c2f58f06cdf3535157dbf8c70bcde3e5c3de7bee6a8d617840ffc8cffb0083e38c6814f2a08c225ca19f58898efaf4f351af94679f22ce6bc + checksum: 4cabf8f894c180cac80b7df1038912a3fc88f96f2622de33832f4b3314f83e22b08fb751da570c0ab2b7988f21604bdabade95e3c0c041068ac578c085cf7dff languageName: node linkType: hard -"jest-diff@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-diff@npm:28.1.3" +"jest-diff@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-diff@npm:29.7.0" dependencies: chalk: ^4.0.0 - diff-sequences: ^28.1.1 - jest-get-type: ^28.0.2 - pretty-format: ^28.1.3 - checksum: fa8583e0ccbe775714ce850b009be1b0f6b17a4b6759f33ff47adef27942ebc610dbbcc8a5f7cfb7f12b3b3b05afc9fb41d5f766674616025032ff1e4f9866e0 + diff-sequences: ^29.6.3 + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: 08e24a9dd43bfba1ef07a6374e5af138f53137b79ec3d5cc71a2303515335898888fa5409959172e1e05de966c9e714368d15e8994b0af7441f0721ee8e1bb77 languageName: node linkType: hard -"jest-docblock@npm:^28.1.1": - version: 28.1.1 - resolution: "jest-docblock@npm:28.1.1" +"jest-docblock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-docblock@npm:29.7.0" dependencies: detect-newline: ^3.0.0 - checksum: 22fca68d988ecb2933bc65f448facdca85fc71b4bd0a188ea09a5ae1b0cc3a049a2a6ec7e7eaa2542c1d5cb5e5145e420a3df4fa280f5070f486c44da1d36151 + checksum: 66390c3e9451f8d96c5da62f577a1dad701180cfa9b071c5025acab2f94d7a3efc2515cfa1654ebe707213241541ce9c5530232cdc8017c91ed64eea1bd3b192 languageName: node linkType: hard -"jest-each@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-each@npm:28.1.3" +"jest-each@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-each@npm:29.7.0" dependencies: - "@jest/types": ^28.1.3 + "@jest/types": ^29.6.3 chalk: ^4.0.0 - jest-get-type: ^28.0.2 - jest-util: ^28.1.3 - pretty-format: ^28.1.3 - checksum: 5c5b8ccb1484e58b027bea682cfa020a45e5bf5379cc7c23bdec972576c1dc3c3bf03df2b78416cefc1a58859dd33b7cf5fff54c370bc3c0f14a3e509eb87282 + jest-get-type: ^29.6.3 + jest-util: ^29.7.0 + pretty-format: ^29.7.0 + checksum: e88f99f0184000fc8813f2a0aa79e29deeb63700a3b9b7928b8a418d7d93cd24933608591dbbdea732b473eb2021c72991b5cc51a17966842841c6e28e6f691c languageName: node linkType: hard -"jest-environment-node@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-environment-node@npm:28.1.3" +"jest-environment-node@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-environment-node@npm:29.7.0" dependencies: - "@jest/environment": ^28.1.3 - "@jest/fake-timers": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/environment": ^29.7.0 + "@jest/fake-timers": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" - jest-mock: ^28.1.3 - jest-util: ^28.1.3 - checksum: 1048fe306a6a8b0880a4c66278ebb57479f29c12cff89aab3aa79ab77a8859cf17ab8aa9919fd21c329a7db90e35581b43664e694ad453d5b04e00f3c6420469 + jest-mock: ^29.7.0 + jest-util: ^29.7.0 + checksum: 501a9966292cbe0ca3f40057a37587cb6def25e1e0c5e39ac6c650fe78d3c70a2428304341d084ac0cced5041483acef41c477abac47e9a290d5545fd2f15646 languageName: node linkType: hard -"jest-get-type@npm:^28.0.2": - version: 28.0.2 - resolution: "jest-get-type@npm:28.0.2" - checksum: 5281d7c89bc8156605f6d15784f45074f4548501195c26e9b188742768f72d40948252d13230ea905b5349038865a1a8eeff0e614cc530ff289dfc41fe843abd +"jest-get-type@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-get-type@npm:29.6.3" + checksum: 88ac9102d4679d768accae29f1e75f592b760b44277df288ad76ce5bf038c3f5ce3719dea8aa0f035dac30e9eb034b848ce716b9183ad7cc222d029f03e92205 languageName: node linkType: hard -"jest-haste-map@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-haste-map@npm:28.1.3" +"jest-haste-map@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-haste-map@npm:29.7.0" dependencies: - "@jest/types": ^28.1.3 + "@jest/types": ^29.6.3 "@types/graceful-fs": ^4.1.3 "@types/node": "*" anymatch: ^3.0.3 fb-watchman: ^2.0.0 fsevents: ^2.3.2 graceful-fs: ^4.2.9 - jest-regex-util: ^28.0.2 - jest-util: ^28.1.3 - jest-worker: ^28.1.3 + jest-regex-util: ^29.6.3 + jest-util: ^29.7.0 + jest-worker: ^29.7.0 micromatch: ^4.0.4 walker: ^1.0.8 dependenciesMeta: fsevents: optional: true - checksum: d05fdc108645fc2b39fcd4001952cc7a8cb550e93494e98c1e9ab1fc542686f6ac67177c132e564cf94fe8f81503f3f8db8b825b9b713dc8c5748aec63ba4688 + checksum: c2c8f2d3e792a963940fbdfa563ce14ef9e14d4d86da645b96d3cd346b8d35c5ce0b992ee08593939b5f718cf0a1f5a90011a056548a1dbf58397d4356786f01 languageName: node linkType: hard -"jest-leak-detector@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-leak-detector@npm:28.1.3" +"jest-leak-detector@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-leak-detector@npm:29.7.0" dependencies: - jest-get-type: ^28.0.2 - pretty-format: ^28.1.3 - checksum: 2e976a4880cf9af11f53a19f6a3820e0f90b635a900737a5427fc42e337d5628ba446dcd7c020ecea3806cf92bc0bbf6982ed62a9cd84e5a13d8751aa30fbbb7 + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: e3950e3ddd71e1d0c22924c51a300a1c2db6cf69ec1e51f95ccf424bcc070f78664813bef7aed4b16b96dfbdeea53fe358f8aeaaea84346ae15c3735758f1605 languageName: node linkType: hard -"jest-matcher-utils@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-matcher-utils@npm:28.1.3" +"jest-matcher-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-matcher-utils@npm:29.7.0" dependencies: chalk: ^4.0.0 - jest-diff: ^28.1.3 - jest-get-type: ^28.0.2 - pretty-format: ^28.1.3 - checksum: 6b34f0cf66f6781e92e3bec97bf27796bd2ba31121e5c5997218d9adba6deea38a30df5203937d6785b68023ed95cbad73663cc9aad6fb0cb59aeb5813a58daf + jest-diff: ^29.7.0 + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: d7259e5f995d915e8a37a8fd494cb7d6af24cd2a287b200f831717ba0d015190375f9f5dc35393b8ba2aae9b2ebd60984635269c7f8cff7d85b077543b7744cd languageName: node linkType: hard -"jest-message-util@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-message-util@npm:28.1.3" +"jest-message-util@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-message-util@npm:29.7.0" dependencies: "@babel/code-frame": ^7.12.13 - "@jest/types": ^28.1.3 + "@jest/types": ^29.6.3 "@types/stack-utils": ^2.0.0 chalk: ^4.0.0 graceful-fs: ^4.2.9 micromatch: ^4.0.4 - pretty-format: ^28.1.3 + pretty-format: ^29.7.0 slash: ^3.0.0 stack-utils: ^2.0.3 - checksum: 1f266854166dcc6900d75a88b54a25225a2f3710d463063ff1c99021569045c35c7d58557b25447a17eb3a65ce763b2f9b25550248b468a9d4657db365f39e96 + checksum: a9d025b1c6726a2ff17d54cc694de088b0489456c69106be6b615db7a51b7beb66788bea7a59991a019d924fbf20f67d085a445aedb9a4d6760363f4d7d09930 languageName: node linkType: hard -"jest-mock@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-mock@npm:28.1.3" +"jest-mock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-mock@npm:29.7.0" dependencies: - "@jest/types": ^28.1.3 + "@jest/types": ^29.6.3 "@types/node": "*" - checksum: a573bf8e5f12f4c29c661266c31b5c6b69a28d3195b83049983bce025b2b1a0152351567e89e63b102ef817034c2a3aa97eda4e776f3bae2aee54c5765573aa7 + jest-util: ^29.7.0 + checksum: 81ba9b68689a60be1482212878973700347cb72833c5e5af09895882b9eb5c4e02843a1bbdf23f94c52d42708bab53a30c45a3482952c9eec173d1eaac5b86c5 languageName: node linkType: hard @@ -12226,193 +12474,191 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^28.0.2": - version: 28.0.2 - resolution: "jest-regex-util@npm:28.0.2" - checksum: 0ea8c5c82ec88bc85e273c0ec82e0c0f35f7a1e2d055070e50f0cc2a2177f848eec55f73e37ae0d045c3db5014c42b2f90ac62c1ab3fdb354d2abd66a9e08add +"jest-regex-util@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-regex-util@npm:29.6.3" + checksum: 0518beeb9bf1228261695e54f0feaad3606df26a19764bc19541e0fc6e2a3737191904607fb72f3f2ce85d9c16b28df79b7b1ec9443aa08c3ef0e9efda6f8f2a languageName: node linkType: hard -"jest-resolve-dependencies@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-resolve-dependencies@npm:28.1.3" +"jest-resolve-dependencies@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve-dependencies@npm:29.7.0" dependencies: - jest-regex-util: ^28.0.2 - jest-snapshot: ^28.1.3 - checksum: 4eea9ec33aefc1c71dc5956391efbcc7be76bda986b366ab3931d99c5f7ed01c9ebd7520e405ea2c76e1bb2c7ce504be6eca2b9831df16564d1e625500f3bfe7 + jest-regex-util: ^29.6.3 + jest-snapshot: ^29.7.0 + checksum: aeb75d8150aaae60ca2bb345a0d198f23496494677cd6aefa26fc005faf354061f073982175daaf32b4b9d86b26ca928586344516e3e6969aa614cb13b883984 languageName: node linkType: hard -"jest-resolve@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-resolve@npm:28.1.3" +"jest-resolve@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve@npm:29.7.0" dependencies: chalk: ^4.0.0 graceful-fs: ^4.2.9 - jest-haste-map: ^28.1.3 + jest-haste-map: ^29.7.0 jest-pnp-resolver: ^1.2.2 - jest-util: ^28.1.3 - jest-validate: ^28.1.3 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 resolve: ^1.20.0 - resolve.exports: ^1.1.0 + resolve.exports: ^2.0.0 slash: ^3.0.0 - checksum: df61a490c93f4f4cf52135e43d6a4fcacb07b0b7d4acc6319e9289529c1d14f2d8e1638e095dbf96f156834802755e38db68caca69dba21a3261ee711d4426b6 + checksum: 0ca218e10731aa17920526ec39deaec59ab9b966237905ffc4545444481112cd422f01581230eceb7e82d86f44a543d520a71391ec66e1b4ef1a578bd5c73487 languageName: node linkType: hard -"jest-runner@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-runner@npm:28.1.3" +"jest-runner@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runner@npm:29.7.0" dependencies: - "@jest/console": ^28.1.3 - "@jest/environment": ^28.1.3 - "@jest/test-result": ^28.1.3 - "@jest/transform": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/console": ^29.7.0 + "@jest/environment": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 - emittery: ^0.10.2 + emittery: ^0.13.1 graceful-fs: ^4.2.9 - jest-docblock: ^28.1.1 - jest-environment-node: ^28.1.3 - jest-haste-map: ^28.1.3 - jest-leak-detector: ^28.1.3 - jest-message-util: ^28.1.3 - jest-resolve: ^28.1.3 - jest-runtime: ^28.1.3 - jest-util: ^28.1.3 - jest-watcher: ^28.1.3 - jest-worker: ^28.1.3 + jest-docblock: ^29.7.0 + jest-environment-node: ^29.7.0 + jest-haste-map: ^29.7.0 + jest-leak-detector: ^29.7.0 + jest-message-util: ^29.7.0 + jest-resolve: ^29.7.0 + jest-runtime: ^29.7.0 + jest-util: ^29.7.0 + jest-watcher: ^29.7.0 + jest-worker: ^29.7.0 p-limit: ^3.1.0 source-map-support: 0.5.13 - checksum: 32405cd970fa6b11e039192dae699fd1bcc6f61f67d50605af81d193f24dd4373b25f5fcc1c571a028ec1b02174e8a4b6d0d608772063fb06f08a5105693533b + checksum: f0405778ea64812bf9b5c50b598850d94ccf95d7ba21f090c64827b41decd680ee19fcbb494007cdd7f5d0d8906bfc9eceddd8fa583e753e736ecd462d4682fb languageName: node linkType: hard -"jest-runtime@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-runtime@npm:28.1.3" - dependencies: - "@jest/environment": ^28.1.3 - "@jest/fake-timers": ^28.1.3 - "@jest/globals": ^28.1.3 - "@jest/source-map": ^28.1.2 - "@jest/test-result": ^28.1.3 - "@jest/transform": ^28.1.3 - "@jest/types": ^28.1.3 +"jest-runtime@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runtime@npm:29.7.0" + dependencies: + "@jest/environment": ^29.7.0 + "@jest/fake-timers": ^29.7.0 + "@jest/globals": ^29.7.0 + "@jest/source-map": ^29.6.3 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/node": "*" chalk: ^4.0.0 cjs-module-lexer: ^1.0.0 collect-v8-coverage: ^1.0.0 - execa: ^5.0.0 glob: ^7.1.3 graceful-fs: ^4.2.9 - jest-haste-map: ^28.1.3 - jest-message-util: ^28.1.3 - jest-mock: ^28.1.3 - jest-regex-util: ^28.0.2 - jest-resolve: ^28.1.3 - jest-snapshot: ^28.1.3 - jest-util: ^28.1.3 + jest-haste-map: ^29.7.0 + jest-message-util: ^29.7.0 + jest-mock: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 slash: ^3.0.0 strip-bom: ^4.0.0 - checksum: b17c40af858e74dafa4f515ef3711c1e9ef3d4ad7d74534ee0745422534bc04fd166d4eceb62a3aa7dc951505d6f6d2a81d16e90bebb032be409ec0500974a36 + checksum: d19f113d013e80691e07047f68e1e3448ef024ff2c6b586ce4f90cd7d4c62a2cd1d460110491019719f3c59bfebe16f0e201ed005ef9f80e2cf798c374eed54e languageName: node linkType: hard -"jest-snapshot@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-snapshot@npm:28.1.3" +"jest-snapshot@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-snapshot@npm:29.7.0" dependencies: "@babel/core": ^7.11.6 "@babel/generator": ^7.7.2 + "@babel/plugin-syntax-jsx": ^7.7.2 "@babel/plugin-syntax-typescript": ^7.7.2 - "@babel/traverse": ^7.7.2 "@babel/types": ^7.3.3 - "@jest/expect-utils": ^28.1.3 - "@jest/transform": ^28.1.3 - "@jest/types": ^28.1.3 - "@types/babel__traverse": ^7.0.6 - "@types/prettier": ^2.1.5 + "@jest/expect-utils": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 babel-preset-current-node-syntax: ^1.0.0 chalk: ^4.0.0 - expect: ^28.1.3 + expect: ^29.7.0 graceful-fs: ^4.2.9 - jest-diff: ^28.1.3 - jest-get-type: ^28.0.2 - jest-haste-map: ^28.1.3 - jest-matcher-utils: ^28.1.3 - jest-message-util: ^28.1.3 - jest-util: ^28.1.3 + jest-diff: ^29.7.0 + jest-get-type: ^29.6.3 + jest-matcher-utils: ^29.7.0 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 natural-compare: ^1.4.0 - pretty-format: ^28.1.3 - semver: ^7.3.5 - checksum: 2a46a5493f1fb50b0a236a21f25045e7f46a244f9f3ae37ef4fbcd40249d0d68bb20c950ce77439e4e2cac985b05c3061c90b34739bf6069913a1199c8c716e1 + pretty-format: ^29.7.0 + semver: ^7.5.3 + checksum: 86821c3ad0b6899521ce75ee1ae7b01b17e6dfeff9166f2cf17f012e0c5d8c798f30f9e4f8f7f5bed01ea7b55a6bc159f5eda778311162cbfa48785447c237ad languageName: node linkType: hard -"jest-util@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-util@npm:28.1.3" +"jest-util@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-util@npm:29.7.0" dependencies: - "@jest/types": ^28.1.3 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 ci-info: ^3.2.0 graceful-fs: ^4.2.9 picomatch: ^2.2.3 - checksum: fd6459742c941f070223f25e38a2ac0719aad92561591e9fb2a50d602a5d19d754750b79b4074327a42b00055662b95da3b006542ceb8b54309da44d4a62e721 + checksum: 042ab4980f4ccd4d50226e01e5c7376a8556b472442ca6091a8f102488c0f22e6e8b89ea874111d2328a2080083bf3225c86f3788c52af0bd0345a00eb57a3ca languageName: node linkType: hard -"jest-validate@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-validate@npm:28.1.3" +"jest-validate@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-validate@npm:29.7.0" dependencies: - "@jest/types": ^28.1.3 + "@jest/types": ^29.6.3 camelcase: ^6.2.0 chalk: ^4.0.0 - jest-get-type: ^28.0.2 + jest-get-type: ^29.6.3 leven: ^3.1.0 - pretty-format: ^28.1.3 - checksum: 95e0513b3803c3372a145cda86edbdb33d9dfeaa18818176f2d581e821548ceac9a179f065b6d4671a941de211354efd67f1fff8789a4fb89962565c85f646db + pretty-format: ^29.7.0 + checksum: 191fcdc980f8a0de4dbdd879fa276435d00eb157a48683af7b3b1b98b0f7d9de7ffe12689b617779097ff1ed77601b9f7126b0871bba4f776e222c40f62e9dae languageName: node linkType: hard -"jest-watcher@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-watcher@npm:28.1.3" +"jest-watcher@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-watcher@npm:29.7.0" dependencies: - "@jest/test-result": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 "@types/node": "*" ansi-escapes: ^4.2.1 chalk: ^4.0.0 - emittery: ^0.10.2 - jest-util: ^28.1.3 + emittery: ^0.13.1 + jest-util: ^29.7.0 string-length: ^4.0.1 - checksum: 8f6d674a4865e7df251f71544f1b51f06fd36b5a3a61f2ac81aeb81fa2a196be354fba51d0f97911c88f67cd254583b3a22ee124bf2c5b6ee2fadec27356c207 + checksum: 67e6e7fe695416deff96b93a14a561a6db69389a0667e9489f24485bb85e5b54e12f3b2ba511ec0b777eca1e727235b073e3ebcdd473d68888650489f88df92f languageName: node linkType: hard -"jest-worker@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-worker@npm:28.1.3" +"jest-worker@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-worker@npm:29.7.0" dependencies: "@types/node": "*" + jest-util: ^29.7.0 merge-stream: ^2.0.0 supports-color: ^8.0.0 - checksum: e921c9a1b8f0909da9ea07dbf3592f95b653aef3a8bb0cbcd20fc7f9a795a1304adecac31eecb308992c167e8d7e75c522061fec38a5928ace0f9571c90169ca + checksum: 30fff60af49675273644d408b650fc2eb4b5dcafc5a0a455f238322a8f9d8a98d847baca9d51ff197b6747f54c7901daa2287799230b856a0f48287d131f8c13 languageName: node linkType: hard -"jest@npm:^28.1.1": - version: 28.1.3 - resolution: "jest@npm:28.1.3" +"jest@npm:^29.7.0": + version: 29.7.0 + resolution: "jest@npm:29.7.0" dependencies: - "@jest/core": ^28.1.3 - "@jest/types": ^28.1.3 + "@jest/core": ^29.7.0 + "@jest/types": ^29.6.3 import-local: ^3.0.2 - jest-cli: ^28.1.3 + jest-cli: ^29.7.0 peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: @@ -12420,7 +12666,7 @@ __metadata: optional: true bin: jest: bin/jest.js - checksum: b9dcb542eb7c16261c281cdc2bf37155dbb3f1205bae0b567f05051db362c85ddd4b765f126591efb88f6d298eb10336d0aa6c7d5373b4d53f918137a9a70182 + checksum: 17ca8d67504a7dbb1998cf3c3077ec9031ba3eb512da8d71cb91bcabb2b8995c4e4b292b740cb9bf1cbff5ce3e110b3f7c777b0cefb6f41ab05445f248d0ee0b languageName: node linkType: hard @@ -12896,13 +13142,6 @@ __metadata: languageName: node linkType: hard -"local-pkg@npm:^0.4.3": - version: 0.4.3 - resolution: "local-pkg@npm:0.4.3" - checksum: 7825aca531dd6afa3a3712a0208697aa4a5cd009065f32e3fb732aafcc42ed11f277b5ac67229222e96f4def55197171cdf3d5522d0381b489d2e5547b407d55 - languageName: node - linkType: hard - "local-pkg@npm:^0.5.0": version: 0.5.0 resolution: "local-pkg@npm:0.5.0" @@ -14006,7 +14245,7 @@ __metadata: languageName: node linkType: hard -"mlly@npm:^1.2.0, mlly@npm:^1.4.0, mlly@npm:^1.4.2": +"mlly@npm:^1.2.0, mlly@npm:^1.4.2": version: 1.6.1 resolution: "mlly@npm:1.6.1" dependencies: @@ -14583,15 +14822,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^4.0.0": - version: 4.0.0 - resolution: "p-limit@npm:4.0.0" - dependencies: - yocto-queue: ^1.0.0 - checksum: 01d9d70695187788f984226e16c903475ec6a947ee7b21948d6f597bed788e3112cc7ec2e171c1d37125057a5f45f3da21d8653e04a3a793589e12e9e80e756b - languageName: node - linkType: hard - "p-limit@npm:^5.0.0": version: 5.0.0 resolution: "p-limit@npm:5.0.0" @@ -15144,7 +15374,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.0.0, postcss@npm:^8.4.18, postcss@npm:^8.4.35": +"postcss@npm:^8.0.0, postcss@npm:^8.4.35": version: 8.4.37 resolution: "postcss@npm:8.4.37" dependencies: @@ -15155,6 +15385,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.4.38": + version: 8.4.38 + resolution: "postcss@npm:8.4.38" + dependencies: + nanoid: ^3.3.7 + picocolors: ^1.0.0 + source-map-js: ^1.2.0 + checksum: 649f9e60a763ca4b5a7bbec446a069edf07f057f6d780a5a0070576b841538d1ecf7dd888f2fbfd1f76200e26c969e405aeeae66332e6927dbdc8bdcb90b9451 + languageName: node + linkType: hard + "potpack@npm:^1.0.1": version: 1.0.2 resolution: "potpack@npm:1.0.2" @@ -15214,18 +15455,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^28.1.3": - version: 28.1.3 - resolution: "pretty-format@npm:28.1.3" - dependencies: - "@jest/schemas": ^28.1.3 - ansi-regex: ^5.0.1 - ansi-styles: ^5.0.0 - react-is: ^18.0.0 - checksum: e69f857358a3e03d271252d7524bec758c35e44680287f36c1cb905187fbc82da9981a6eb07edfd8a03bc3cbeebfa6f5234c13a3d5b59f2bbdf9b4c4053e0a7f - languageName: node - linkType: hard - "pretty-format@npm:^29.5.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" @@ -15394,6 +15623,13 @@ __metadata: languageName: node linkType: hard +"pure-rand@npm:^6.0.0": + version: 6.1.0 + resolution: "pure-rand@npm:6.1.0" + checksum: 8d53bc02bed99eca0b65b505090152ee7e9bd67dd74f8ff32ba1c883b87234067c5bf68d2614759fb217d82594d7a92919e6df80f97885e7b12b42af4bd3316a + languageName: node + linkType: hard + "querystringify@npm:^2.1.1": version: 2.2.0 resolution: "querystringify@npm:2.2.0" @@ -16313,10 +16549,10 @@ __metadata: languageName: node linkType: hard -"resolve.exports@npm:^1.1.0": - version: 1.1.1 - resolution: "resolve.exports@npm:1.1.1" - checksum: 485aa10082eb388a569d696e17ad7b16f4186efc97dd34eadd029d95b811f21ffee13b1b733198bb4584dbb3cb296aa6f141835221fb7613b9606b84f1386655 +"resolve.exports@npm:^2.0.0": + version: 2.0.2 + resolution: "resolve.exports@npm:2.0.2" + checksum: 1c7778ca1b86a94f8ab4055d196c7d87d1874b96df4d7c3e67bbf793140f0717fd506dcafd62785b079cd6086b9264424ad634fb904409764c3509c3df1653f2 languageName: node linkType: hard @@ -16327,7 +16563,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.0.0, resolve@npm:^1.1.10, resolve@npm:^1.1.5, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0, resolve@npm:^1.22.1": +"resolve@npm:^1.0.0, resolve@npm:^1.1.10, resolve@npm:^1.1.5, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -16360,7 +16596,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.0.0#~builtin, resolve@patch:resolve@^1.1.10#~builtin, resolve@patch:resolve@^1.1.5#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin": +"resolve@patch:resolve@^1.0.0#~builtin, resolve@patch:resolve@^1.1.10#~builtin, resolve@patch:resolve@^1.1.5#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=07638b" dependencies: @@ -16427,7 +16663,7 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": +"rimraf@npm:^3.0.2": version: 3.0.2 resolution: "rimraf@npm:3.0.2" dependencies: @@ -16511,7 +16747,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^2.77.2, rollup@npm:^2.79.1": +"rollup@npm:^2.77.2": version: 2.79.1 resolution: "rollup@npm:2.79.1" dependencies: @@ -16525,6 +16761,69 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.13.0": + version: 4.18.0 + resolution: "rollup@npm:4.18.0" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.18.0 + "@rollup/rollup-android-arm64": 4.18.0 + "@rollup/rollup-darwin-arm64": 4.18.0 + "@rollup/rollup-darwin-x64": 4.18.0 + "@rollup/rollup-linux-arm-gnueabihf": 4.18.0 + "@rollup/rollup-linux-arm-musleabihf": 4.18.0 + "@rollup/rollup-linux-arm64-gnu": 4.18.0 + "@rollup/rollup-linux-arm64-musl": 4.18.0 + "@rollup/rollup-linux-powerpc64le-gnu": 4.18.0 + "@rollup/rollup-linux-riscv64-gnu": 4.18.0 + "@rollup/rollup-linux-s390x-gnu": 4.18.0 + "@rollup/rollup-linux-x64-gnu": 4.18.0 + "@rollup/rollup-linux-x64-musl": 4.18.0 + "@rollup/rollup-win32-arm64-msvc": 4.18.0 + "@rollup/rollup-win32-ia32-msvc": 4.18.0 + "@rollup/rollup-win32-x64-msvc": 4.18.0 + "@types/estree": 1.0.5 + fsevents: ~2.3.2 + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 54cde921e763017ce952ba76ec77d58dd9c01e3536c3be628d4af8c59d9b2f0e1e6a11b30fda44845c7b74098646cd972feb3bcd2f4a35d3293366f2eeb0a39e + languageName: node + linkType: hard + "rollup@npm:^4.2.0": version: 4.13.0 resolution: "rollup@npm:4.13.0" @@ -16772,6 +17071,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.5.4": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 40f6a95101e8d854357a644da1b8dd9d93ce786d5c6a77227bc69dbb17bea83d0d1d1d7c4cd5920a6df909f48e8bd8a5909869535007f90278289f2451d0292d + languageName: node + linkType: hard + "serialize-error@npm:^7.0.1": version: 7.0.1 resolution: "serialize-error@npm:7.0.1" @@ -17476,15 +17784,6 @@ __metadata: languageName: node linkType: hard -"strip-literal@npm:^1.0.1": - version: 1.3.0 - resolution: "strip-literal@npm:1.3.0" - dependencies: - acorn: ^8.10.0 - checksum: f5fa7e289df8ebe82e90091fd393974faf8871be087ca50114327506519323cf15f2f8fee6ebe68b5e58bfc795269cae8bdc7cb5a83e27b02b3fe953f37b0a89 - languageName: node - linkType: hard - "strip-literal@npm:^2.0.0": version: 2.0.0 resolution: "strip-literal@npm:2.0.0" @@ -17612,7 +17911,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^7.0.0, supports-color@npm:^7.1.0": +"supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" dependencies: @@ -17630,16 +17929,6 @@ __metadata: languageName: node linkType: hard -"supports-hyperlinks@npm:^2.0.0": - version: 2.3.0 - resolution: "supports-hyperlinks@npm:2.3.0" - dependencies: - has-flag: ^4.0.0 - supports-color: ^7.0.0 - checksum: 9ee0de3c8ce919d453511b2b1588a8205bd429d98af94a01df87411391010fe22ca463f268c84b2ce2abad019dfff8452aa02806eeb5c905a8d7ad5c4f4c52b8 - languageName: node - linkType: hard - "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" @@ -17719,16 +18008,6 @@ __metadata: languageName: node linkType: hard -"terminal-link@npm:^2.0.0": - version: 2.1.1 - resolution: "terminal-link@npm:2.1.1" - dependencies: - ansi-escapes: ^4.2.1 - supports-hyperlinks: ^2.0.0 - checksum: ce3d2cd3a438c4a9453947aa664581519173ea40e77e2534d08c088ee6dda449eabdbe0a76d2a516b8b73c33262fedd10d5270ccf7576ae316e3db170ce6562f - languageName: node - linkType: hard - "test-exclude@npm:^6.0.0": version: 6.0.0 resolution: "test-exclude@npm:6.0.0" @@ -17843,7 +18122,7 @@ __metadata: languageName: node linkType: hard -"tinybench@npm:^2.5.0, tinybench@npm:^2.5.1": +"tinybench@npm:^2.5.1": version: 2.6.0 resolution: "tinybench@npm:2.6.0" checksum: a621ac66ac17ec5da7e9ac10b3c27040e58c3cd843ccedd8e1e3fab5702d6337b80d02b7bfbf420ab5f029dcb7895657fb80ce21181896e170fa4e6d2c2eebc4 @@ -17857,20 +18136,6 @@ __metadata: languageName: node linkType: hard -"tinypool@npm:^0.7.0": - version: 0.7.0 - resolution: "tinypool@npm:0.7.0" - checksum: fdcccd5c750574fce51f8801a877f8284e145d12b79cd5f2d72bfbddfe20c895e915555bc848e122bb6aa968098e7ac4fe1e8e88104904d518dc01cccd18a510 - languageName: node - linkType: hard - -"tinypool@npm:^0.8.2": - version: 0.8.2 - resolution: "tinypool@npm:0.8.2" - checksum: b0993207b89ab8ab565e1eb03287aa3f15bc648c2e1da889bcfad003244271a5efe5c215d8074c3b8798ae7ea9c54678b6c9b09e7e5c8e82285177792e7ac30a - languageName: node - linkType: hard - "tinypool@npm:^0.8.3": version: 0.8.4 resolution: "tinypool@npm:0.8.4" @@ -17885,7 +18150,7 @@ __metadata: languageName: node linkType: hard -"tinyspy@npm:^2.1.1, tinyspy@npm:^2.2.0": +"tinyspy@npm:^2.2.0": version: 2.2.1 resolution: "tinyspy@npm:2.2.1" checksum: 170d6232e87f9044f537b50b406a38fbfd6f79a261cd12b92879947bd340939a833a678632ce4f5c4a6feab4477e9c21cd43faac3b90b68b77dd0536c4149736 @@ -18851,40 +19116,9 @@ __metadata: languageName: node linkType: hard -"vite-node@npm:0.34.6": - version: 0.34.6 - resolution: "vite-node@npm:0.34.6" - dependencies: - cac: ^6.7.14 - debug: ^4.3.4 - mlly: ^1.4.0 - pathe: ^1.1.1 - picocolors: ^1.0.0 - vite: ^3.0.0 || ^4.0.0 || ^5.0.0-0 - bin: - vite-node: vite-node.mjs - checksum: 46eba82bf8b69c7dfeed901502533b172cc6303212f0f49f82c2f64758fa4b60acd1b1e37cb96aff944e36b510b0d1beedb50d9cb25ef39e0159b2b9d1136b1f - languageName: node - linkType: hard - -"vite-node@npm:1.4.0": - version: 1.4.0 - resolution: "vite-node@npm:1.4.0" - dependencies: - cac: ^6.7.14 - debug: ^4.3.4 - pathe: ^1.1.1 - picocolors: ^1.0.0 - vite: ^5.0.0 - bin: - vite-node: vite-node.mjs - checksum: 1abbeac935a5e1e3b6161974ae28b6a3ec88766b06bc082ab3f2883345ee74f5643f3004df1c7808c2b52d445ffbd067bb79a1a3920c2eaa7ca8084b11b7de46 - languageName: node - linkType: hard - -"vite-node@npm:1.5.0": - version: 1.5.0 - resolution: "vite-node@npm:1.5.0" +"vite-node@npm:1.6.0": + version: 1.6.0 + resolution: "vite-node@npm:1.6.0" dependencies: cac: ^6.7.14 debug: ^4.3.4 @@ -18893,7 +19127,7 @@ __metadata: vite: ^5.0.0 bin: vite-node: vite-node.mjs - checksum: 7313d1f616638959425280e95116e9ca9f7601ac709205fc3847a29a8ec00ecc5933911dab2e4545ea8c5a61b02c84e85a46039afaec684fa74ef5456f1b6bb1 + checksum: ce111c5c7a4cf65b722baa15cbc065b7bfdbf1b65576dd6372995f6a72b2b93773ec5df59f6c5f08cfe1284806597b44b832efcea50d5971102428159ff4379f languageName: node linkType: hard @@ -18960,7 +19194,7 @@ __metadata: languageName: node linkType: hard -"vite@npm:^3.0.0 || ^4.0.0 || ^5.0.0-0, vite@npm:^3.1.0 || ^4.0.0 || ^5.0.0-0, vite@npm:^5.0.0": +"vite@npm:^5.0.0": version: 5.1.6 resolution: "vite@npm:5.1.6" dependencies: @@ -19000,18 +19234,18 @@ __metadata: languageName: node linkType: hard -"vite@npm:^3.2.10": - version: 3.2.10 - resolution: "vite@npm:3.2.10" +"vite@npm:^5.2.12": + version: 5.2.12 + resolution: "vite@npm:5.2.12" dependencies: - esbuild: ^0.15.9 - fsevents: ~2.3.2 - postcss: ^8.4.18 - resolve: ^1.22.1 - rollup: ^2.79.1 + esbuild: ^0.20.1 + fsevents: ~2.3.3 + postcss: ^8.4.38 + rollup: ^4.13.0 peerDependencies: - "@types/node": ">= 14" + "@types/node": ^18.0.0 || >=20.0.0 less: "*" + lightningcss: ^1.21.0 sass: "*" stylus: "*" sugarss: "*" @@ -19024,6 +19258,8 @@ __metadata: optional: true less: optional: true + lightningcss: + optional: true sass: optional: true stylus: @@ -19034,129 +19270,19 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 6772a0fce62d56d2d4480439a63a43a33ccb111aba981633947c7991bbba5414ad54711d835af464f851a176c3b0a93d8b07952d52fa52bcd5507220f83df443 - languageName: node - linkType: hard - -"vitest@npm:^0.34.6": - version: 0.34.6 - resolution: "vitest@npm:0.34.6" - dependencies: - "@types/chai": ^4.3.5 - "@types/chai-subset": ^1.3.3 - "@types/node": "*" - "@vitest/expect": 0.34.6 - "@vitest/runner": 0.34.6 - "@vitest/snapshot": 0.34.6 - "@vitest/spy": 0.34.6 - "@vitest/utils": 0.34.6 - acorn: ^8.9.0 - acorn-walk: ^8.2.0 - cac: ^6.7.14 - chai: ^4.3.10 - debug: ^4.3.4 - local-pkg: ^0.4.3 - magic-string: ^0.30.1 - pathe: ^1.1.1 - picocolors: ^1.0.0 - std-env: ^3.3.3 - strip-literal: ^1.0.1 - tinybench: ^2.5.0 - tinypool: ^0.7.0 - vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 - vite-node: 0.34.6 - why-is-node-running: ^2.2.2 - peerDependencies: - "@edge-runtime/vm": "*" - "@vitest/browser": "*" - "@vitest/ui": "*" - happy-dom: "*" - jsdom: "*" - playwright: "*" - safaridriver: "*" - webdriverio: "*" - peerDependenciesMeta: - "@edge-runtime/vm": - optional: true - "@vitest/browser": - optional: true - "@vitest/ui": - optional: true - happy-dom: - optional: true - jsdom: - optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true - bin: - vitest: vitest.mjs - checksum: 45f5c1987fa8c76dbaf5db379bbdb4f6e3713c484e850149af38247b627e70016c1863286fd7fcfab08a1d98430f66ba1f45af6f14f5c467ded4b1ea6f26afa3 - languageName: node - linkType: hard - -"vitest@npm:^1.4.0": - version: 1.4.0 - resolution: "vitest@npm:1.4.0" - dependencies: - "@vitest/expect": 1.4.0 - "@vitest/runner": 1.4.0 - "@vitest/snapshot": 1.4.0 - "@vitest/spy": 1.4.0 - "@vitest/utils": 1.4.0 - acorn-walk: ^8.3.2 - chai: ^4.3.10 - debug: ^4.3.4 - execa: ^8.0.1 - local-pkg: ^0.5.0 - magic-string: ^0.30.5 - pathe: ^1.1.1 - picocolors: ^1.0.0 - std-env: ^3.5.0 - strip-literal: ^2.0.0 - tinybench: ^2.5.1 - tinypool: ^0.8.2 - vite: ^5.0.0 - vite-node: 1.4.0 - why-is-node-running: ^2.2.2 - peerDependencies: - "@edge-runtime/vm": "*" - "@types/node": ^18.0.0 || >=20.0.0 - "@vitest/browser": 1.4.0 - "@vitest/ui": 1.4.0 - happy-dom: "*" - jsdom: "*" - peerDependenciesMeta: - "@edge-runtime/vm": - optional: true - "@types/node": - optional: true - "@vitest/browser": - optional: true - "@vitest/ui": - optional: true - happy-dom: - optional: true - jsdom: - optional: true - bin: - vitest: vitest.mjs - checksum: e7141c0ecc629c350d8c718051fb19219ca88a100d335fedbe481c4320f285380e3235316a69a330514c34663fcafa37c801151162d0a538e92821e7faad71a6 + checksum: 908b8a09460c031fe94c2038a46743a73a70fe76fd1991ae8b51a56eb88dec75128bc7da7ab37d8f84c0e1e3063ce268bdd81cc27d79229f8ea756e752bc83d9 languageName: node linkType: hard -"vitest@npm:^1.5.0": - version: 1.5.0 - resolution: "vitest@npm:1.5.0" +"vitest@npm:^1.6.0": + version: 1.6.0 + resolution: "vitest@npm:1.6.0" dependencies: - "@vitest/expect": 1.5.0 - "@vitest/runner": 1.5.0 - "@vitest/snapshot": 1.5.0 - "@vitest/spy": 1.5.0 - "@vitest/utils": 1.5.0 + "@vitest/expect": 1.6.0 + "@vitest/runner": 1.6.0 + "@vitest/snapshot": 1.6.0 + "@vitest/spy": 1.6.0 + "@vitest/utils": 1.6.0 acorn-walk: ^8.3.2 chai: ^4.3.10 debug: ^4.3.4 @@ -19170,13 +19296,13 @@ __metadata: tinybench: ^2.5.1 tinypool: ^0.8.3 vite: ^5.0.0 - vite-node: 1.5.0 + vite-node: 1.6.0 why-is-node-running: ^2.2.2 peerDependencies: "@edge-runtime/vm": "*" "@types/node": ^18.0.0 || >=20.0.0 - "@vitest/browser": 1.5.0 - "@vitest/ui": 1.5.0 + "@vitest/browser": 1.6.0 + "@vitest/ui": 1.6.0 happy-dom: "*" jsdom: "*" peerDependenciesMeta: @@ -19194,7 +19320,7 @@ __metadata: optional: true bin: vitest: vitest.mjs - checksum: 566d81639e89f60893f99ec8adcf051c3a62f51025eeed8cf399e80f4cdf7ef818e3c82bb348aa5ca3a21f7e9fd5ab180d585a3f5d3ffe5c292cfd01700be787 + checksum: a9b9b97e5685d630e5d8d221e6d6cd2e1e9b5b2dd61e82042839ef11549c8d2d780cf696307de406dce804bf41c1219398cb20b4df570b3b47ad1e53af6bfe51 languageName: node linkType: hard @@ -19469,7 +19595,7 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^4.0.1": +"write-file-atomic@npm:^4.0.2": version: 4.0.2 resolution: "write-file-atomic@npm:4.0.2" dependencies: From 8471d1f87e371f9366cc30535954b1fbf43889bf Mon Sep 17 00:00:00 2001 From: imanjra Date: Tue, 4 Jun 2024 13:30:51 -0400 Subject: [PATCH 02/26] bump version for v0.24.1 (#4446) * bump version for v0.24.1 * bump desktop * Teams integration (#4386) * teams merge step * add merge event * skip merge call, use pull number * add assignee * use actor * only develop for now * use branch * rm teams requirement * bump interval * add fetch depth * add bot author * use develop * alphabetize --------- Co-authored-by: Benjamin Kane --- .github/workflows/pr.yml | 18 +++++++++++++++++ .github/workflows/push-release.yml | 32 ++++++++++++++++++++++++++++++ package/desktop/setup.py | 2 +- setup.py | 4 ++-- 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/push-release.yml diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index bcd3c19946..f6e915fbdd 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -16,6 +16,24 @@ jobs: e2e: uses: ./.github/workflows/e2e.yml + teams: + runs-on: ubuntu-latest + if: github.base_ref == 'develop' + steps: + - uses: convictional/trigger-workflow-and-wait@v1.6.1 + with: + owner: voxel51 + repo: fiftyone-teams + github_token: ${{ secrets.FIFTYONE_GITHUB_TOKEN }} + github_user: voxel51-bot + workflow_file_name: merge-oss.yml + ref: develop + wait_interval: 20 + client_payload: '{ "branch": "${{ github.head_ref || github.ref_name }}" }' + propagate_failure: true + trigger_workflow: true + wait_workflow: true + test: uses: ./.github/workflows/test.yml diff --git a/.github/workflows/push-release.yml b/.github/workflows/push-release.yml new file mode 100644 index 0000000000..fb79401fef --- /dev/null +++ b/.github/workflows/push-release.yml @@ -0,0 +1,32 @@ +name: Push Release + +on: + push: + branches: + - main + - release/v[0-9]+.[0-9]+.[0-9]+ + workflow_dispatch: + inputs: + ref_name: + type: string + +jobs: + pr: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: develop + fetch-depth: 0 + - run: | + git config user.name 'voxel51-bot' + git config user.email 'bot@voxel51.com' + git pull origin ${{ inputs.ref_name || github.ref_name }} --no-rebase + - uses: peter-evans/create-pull-request@v6 + with: + author: voxel51-bot + token: ${{ secrets.FIFTYONE_GITHUB_TOKEN }} + base: develop + body: Merge `${{ inputs.ref_name || github.ref_name }}` to `develop` + branch: merge/${{ inputs.ref_name || github.ref_name }} + title: Merge `${{ inputs.ref_name || github.ref_name }}` to `develop` diff --git a/package/desktop/setup.py b/package/desktop/setup.py index c782a0b99a..7e9b84e2ec 100644 --- a/package/desktop/setup.py +++ b/package/desktop/setup.py @@ -16,7 +16,7 @@ import shutil -VERSION = "0.34.0" +VERSION = "0.34.1" def get_version(): diff --git a/setup.py b/setup.py index b76b18096a..f8ac8e32f3 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ from setuptools import setup, find_packages -VERSION = "0.24.0" +VERSION = "0.24.1" def get_version(): @@ -115,7 +115,7 @@ def get_install_requirements(install_requires, choose_install_requires): return install_requires -EXTRAS_REQUIREMENTS = {"desktop": ["fiftyone-desktop~=0.34.0"]} +EXTRAS_REQUIREMENTS = {"desktop": ["fiftyone-desktop~=0.34.1"]} with open("README.md", "r") as fh: From d2ca5f7137729d88be9cce0f53701018c06a6c29 Mon Sep 17 00:00:00 2001 From: imanjra Date: Tue, 4 Jun 2024 14:12:55 -0400 Subject: [PATCH 03/26] fix operator prompt hidden for executing, output, and error (#4445) * fix operator prompt hidden for executing, output, and error * add e2e tests for operators prompt * operator drawer prompt tweaks * mv to asserter * lint --------- Co-authored-by: Benjamin Kane --- .../OperatorPrompt/OperatorDrawerPrompt.tsx | 20 ++- .../OperatorPrompt/OperatorModalPrompt.tsx | 22 +-- .../src/OperatorPrompt/OperatorViewModal.tsx | 1 + .../operators/src/OperatorPrompt/index.tsx | 2 - app/packages/operators/src/utils.ts | 10 ++ .../oss/poms/operators/operators-prompt.ts | 79 ++++++++++ .../operators/built-in-operators.spec.ts | 7 +- e2e-pw/src/oss/specs/operators/prompt.spec.ts | 138 ++++++++++++++++++ .../src/shared/assets/plugins/e2e/__init__.py | 76 ++++++++++ .../shared/assets/plugins/e2e/fiftyone.yml | 3 + 10 files changed, 328 insertions(+), 30 deletions(-) create mode 100644 e2e-pw/src/oss/poms/operators/operators-prompt.ts create mode 100644 e2e-pw/src/oss/specs/operators/prompt.spec.ts diff --git a/app/packages/operators/src/OperatorPrompt/OperatorDrawerPrompt.tsx b/app/packages/operators/src/OperatorPrompt/OperatorDrawerPrompt.tsx index ac24937b08..f313447c86 100644 --- a/app/packages/operators/src/OperatorPrompt/OperatorDrawerPrompt.tsx +++ b/app/packages/operators/src/OperatorPrompt/OperatorDrawerPrompt.tsx @@ -1,4 +1,4 @@ -import { Resizable } from "@fiftyone/components"; +import { Resizable, scrollable } from "@fiftyone/components"; import { Close } from "@mui/icons-material"; import { Box, IconButton, Stack } from "@mui/material"; import { useState } from "react"; @@ -32,6 +32,7 @@ export default function OperatorDrawerPrompt(props: OperatorPromptPropsType) { onResizeReset={() => { setWidth(DEFAULT_WIDTH); }} + data-cy="operators-prompt-drawer" > - - + + + + diff --git a/app/packages/operators/src/OperatorPrompt/OperatorModalPrompt.tsx b/app/packages/operators/src/OperatorPrompt/OperatorModalPrompt.tsx index 4b45428536..e9b3df95b6 100644 --- a/app/packages/operators/src/OperatorPrompt/OperatorModalPrompt.tsx +++ b/app/packages/operators/src/OperatorPrompt/OperatorModalPrompt.tsx @@ -6,28 +6,12 @@ import { getOperatorPromptConfigs } from "../utils"; export default function OperatorModalPrompt(props: OperatorPromptPropsType) { const { prompt } = props; - const { - title, - hasValidationErrors, - resolving, - pendingResolve, - validationErrorsStr, - ...otherConfigs - } = getOperatorPromptConfigs(prompt); + const promptConfig = getOperatorPromptConfigs(prompt); return ( diff --git a/app/packages/operators/src/OperatorPrompt/OperatorViewModal.tsx b/app/packages/operators/src/OperatorPrompt/OperatorViewModal.tsx index a82f65d7f2..e0317190e4 100644 --- a/app/packages/operators/src/OperatorPrompt/OperatorViewModal.tsx +++ b/app/packages/operators/src/OperatorPrompt/OperatorViewModal.tsx @@ -13,6 +13,7 @@ export default function OperatorViewModal() { onSubmit={io.hide} onClose={io.hide} submitButtonText="Done" + dialogProps={{ PaperProps: { "data-cy": "operators-prompt-view-modal" } }} > diff --git a/app/packages/operators/src/OperatorPrompt/index.tsx b/app/packages/operators/src/OperatorPrompt/index.tsx index ac883ddc83..4a0482f858 100644 --- a/app/packages/operators/src/OperatorPrompt/index.tsx +++ b/app/packages/operators/src/OperatorPrompt/index.tsx @@ -25,8 +25,6 @@ function DynamicOperatorPrompt() { const target = getPromptTarget(prompt); const Component = getPromptComponent(prompt); - if (!prompt.resolvedIO.input && !prompt.resolvedIO.output) return null; - return createPortal(, target); } diff --git a/app/packages/operators/src/utils.ts b/app/packages/operators/src/utils.ts index 4fef7928b4..2c1ba6056a 100644 --- a/app/packages/operators/src/utils.ts +++ b/app/packages/operators/src/utils.ts @@ -77,6 +77,12 @@ export function getOperatorPromptConfigs(operatorPrompt: OperatorPromptType) { const validationErrorsStr = formatValidationErrors( operatorPrompt.validationErrors ); + const loading = resolving || pendingResolve; + const disableSubmit = hasValidationErrors || resolving || pendingResolve; + const disabledReason = hasValidationErrors + ? "Cannot execute operator with validation errors\n\n" + validationErrorsStr + : "Cannot execute operator while validating form"; + const onClose = onCancel || operatorPrompt.close; return { title, @@ -99,6 +105,10 @@ export function getOperatorPromptConfigs(operatorPrompt: OperatorPromptType) { cancelButtonText, onSubmit, onCancel, + loading, + disableSubmit, + disabledReason, + onClose, }; } diff --git a/e2e-pw/src/oss/poms/operators/operators-prompt.ts b/e2e-pw/src/oss/poms/operators/operators-prompt.ts new file mode 100644 index 0000000000..993c7864e8 --- /dev/null +++ b/e2e-pw/src/oss/poms/operators/operators-prompt.ts @@ -0,0 +1,79 @@ +import { Locator, Page, expect } from "src/oss/fixtures"; + +export class OperatorsPromptPom { + readonly page: Page; + readonly locator: Locator; + readonly assert: OperatorsPromptAsserter; + readonly selectionCount: Locator; + readonly type: PromptType; + + constructor(page: Page, type: PromptType = "modal") { + this.page = page; + this.assert = new OperatorsPromptAsserter(this); + this.locator = this.page.getByTestId(`operators-prompt-${type}`); + this.type = type; + } + + get content() { + if (this.type === "drawer") { + return this.locator.getByTestId("operators-prompt-drawer-content"); + } + return this.locator.locator(".MuiDialogContent-root").first(); + } + + get footer() { + if (this.type === "drawer") { + return this.locator.getByTestId("operators-prompt-drawer-footer"); + } + return this.locator.locator(".MuiDialogActions-root").first(); + } + + get executeButton() { + return this.footer.locator('button:text("Execute")'); + } + + async execute() { + await this.assert.canExecute(); + return this.executeButton.click(); + } + + cancel() { + return this.footer.locator('button:text("Cancel")').click(); + } + + close() { + return this.footer.locator('button:text("Close")').click(); + } + + done() { + return this.footer.locator('button:text("Done")').click(); + } +} + +class OperatorsPromptAsserter { + constructor(private readonly panelPom: OperatorsPromptPom) {} + + async isOpen() { + await expect(this.panelPom.locator).toBeVisible(); + } + async isClosed() { + await expect(this.panelPom.locator).not.toBeVisible(); + } + async isExecuting() { + await expect(this.panelPom.locator).toContainText("Executing..."); + } + async canExecute() { + await expect(this.panelPom.executeButton).toBeEnabled(); + } + + async isValidated() { + await expect( + this.panelPom.footer.locator(".MuiCircularProgress-root") + ).toBeHidden(); + await expect( + this.panelPom.footer.locator(".MuiCircularProgress-root") + ).toBeHidden(); + } +} + +type PromptType = "modal" | "drawer" | "view-modal"; diff --git a/e2e-pw/src/oss/specs/operators/built-in-operators.spec.ts b/e2e-pw/src/oss/specs/operators/built-in-operators.spec.ts index 8225b7e413..0a535aff52 100644 --- a/e2e-pw/src/oss/specs/operators/built-in-operators.spec.ts +++ b/e2e-pw/src/oss/specs/operators/built-in-operators.spec.ts @@ -1,14 +1,12 @@ import { test as base } from "src/oss/fixtures"; import { OperatorsBrowserPom } from "src/oss/poms/operators/operators-browser"; -import { HistogramPom } from "src/oss/poms/panels/histogram-panel"; import { ViewBarPom } from "src/oss/poms/viewbar/viewbar"; import { getUniqueDatasetNameWithPrefix } from "src/oss/utils"; -const datasetName = getUniqueDatasetNameWithPrefix(`built-in-operators`); +const datasetName = getUniqueDatasetNameWithPrefix("built-in-operators"); const test = base.extend<{ operatorsBrowser: OperatorsBrowserPom; viewBar: ViewBarPom; - histogramPanel: HistogramPom; }>({ operatorsBrowser: async ({ page }, use) => { await use(new OperatorsBrowserPom(page)); @@ -16,9 +14,6 @@ const test = base.extend<{ viewBar: async ({ page }, use) => { await use(new ViewBarPom(page)); }, - histogramPanel: async ({ page, eventUtils }, use) => { - await use(new HistogramPom(page, eventUtils)); - }, }); test.beforeAll(async ({ fiftyoneLoader }) => { diff --git a/e2e-pw/src/oss/specs/operators/prompt.spec.ts b/e2e-pw/src/oss/specs/operators/prompt.spec.ts new file mode 100644 index 0000000000..8a3bc9f74a --- /dev/null +++ b/e2e-pw/src/oss/specs/operators/prompt.spec.ts @@ -0,0 +1,138 @@ +import { test as base, expect } from "src/oss/fixtures"; +import { OperatorsBrowserPom } from "src/oss/poms/operators/operators-browser"; +import { OperatorsPromptPom } from "src/oss/poms/operators/operators-prompt"; +import { getUniqueDatasetNameWithPrefix } from "src/oss/utils"; + +const datasetName = getUniqueDatasetNameWithPrefix("operators-prompt"); +const test = base.extend<{ + operatorsBrowser: OperatorsBrowserPom; + operatorsPrompt: OperatorsPromptPom; + operatorsPromptViewModal: OperatorsPromptPom; + operatorsPromptDrawer: OperatorsPromptPom; +}>({ + operatorsBrowser: async ({ page }, use) => { + await use(new OperatorsBrowserPom(page)); + }, + operatorsPrompt: async ({ page }, use) => { + await use(new OperatorsPromptPom(page)); + }, + operatorsPromptViewModal: async ({ page }, use) => { + await use(new OperatorsPromptPom(page, "view-modal")); + }, + operatorsPromptDrawer: async ({ page }, use) => { + await use(new OperatorsPromptPom(page, "drawer")); + }, +}); + +test.beforeAll(async ({ fiftyoneLoader }) => { + await fiftyoneLoader.executePythonCode(` + import fiftyone as fo + dataset = fo.Dataset("${datasetName}") + dataset.persistent = True + + samples = [] + for i in range(0, 10): + sample = fo.Sample( + filepath=f"{i}.png", + detections=fo.Detections(detections=[fo.Detection(label=f"label-{i}")]), + classification=fo.Classification(label=f"label-{i}"), + bool=i % 2 == 0, + str=f"{i}", + int=i % 2, + float=i / 2, + list_str=[f"{i}"], + list_int=[i % 2], + list_float=[i / 2], + list_bool=[i % 2 == 0], + ) + samples.append(sample) + + dataset.add_samples(samples)`); +}); + +test.beforeEach(async ({ page, fiftyoneLoader }) => { + await fiftyoneLoader.waitUntilGridVisible(page, datasetName); +}); + +test("Prompt: Cancel modal", async ({ operatorsBrowser, operatorsPrompt }) => { + await operatorsBrowser.show(); + await operatorsBrowser.search("E2E"); + await operatorsBrowser.choose("E2E: Say hello in modal"); + await operatorsPrompt.locator.locator("input").first().fill("E2E"); + await operatorsPrompt.assert.isOpen(); + await operatorsPrompt.cancel(); + await operatorsPrompt.assert.isClosed(); +}); + +test("Prompt: Say hello in modal", async ({ + operatorsBrowser, + operatorsPrompt, +}) => { + await operatorsBrowser.show(); + await operatorsBrowser.search("E2E"); + await operatorsBrowser.choose("E2E: Say hello in modal"); + await operatorsPrompt.assert.isOpen(); + await operatorsPrompt.locator + .locator("input") + .first() + .pressSequentially("E2E"); + await operatorsPrompt.assert.isValidated(); + await operatorsPrompt.execute(); + await operatorsPrompt.assert.isExecuting(); + await expect(operatorsPrompt.content).toContainText("Message:Hi E2E!"); + await operatorsPrompt.close(); + await operatorsPrompt.assert.isClosed(); +}); + +test("Prompt: Cancel drawer", async ({ + operatorsBrowser, + operatorsPromptDrawer, +}) => { + await operatorsBrowser.show(); + await operatorsBrowser.search("E2E"); + await operatorsBrowser.choose("E2E: Say hello in drawer"); + await operatorsPromptDrawer.locator.locator("input").first().fill("E2E"); + await operatorsPromptDrawer.assert.isOpen(); + await operatorsPromptDrawer.cancel(); + await operatorsPromptDrawer.assert.isClosed(); +}); + +test("Prompt: Say hello in drawer", async ({ + operatorsBrowser, + operatorsPromptDrawer, +}) => { + await operatorsBrowser.show(); + await operatorsBrowser.search("E2E"); + await operatorsBrowser.choose("E2E: Say hello in drawer"); + await operatorsPromptDrawer.assert.isOpen(); + await operatorsPromptDrawer.locator + .locator("input") + .first() + .pressSequentially("E2E"); + await operatorsPromptDrawer.assert.isValidated(); + await operatorsPromptDrawer.execute(); + await operatorsPromptDrawer.assert.isExecuting(); + await expect(operatorsPromptDrawer.content).toContainText("Message:Hi E2E!"); + await operatorsPromptDrawer.close(); + await operatorsPromptDrawer.assert.isClosed(); +}); + +test("Prompt: Progress", async ({ + operatorsBrowser, + operatorsPrompt, + operatorsPromptViewModal, +}) => { + await operatorsBrowser.show(); + await operatorsBrowser.search("E2E"); + await operatorsBrowser.choose("E2E: Progress"); + await operatorsPrompt.assert.isExecuting(); + await expect(operatorsPromptViewModal.content).toContainText( + "Loading 1 of 2" + ); + await expect(operatorsPromptViewModal.content).toContainText( + "Loading 2 of 2" + ); + await operatorsPromptViewModal.done(); + await operatorsPrompt.assert.isClosed(); + await operatorsPromptViewModal.assert.isClosed(); +}); diff --git a/e2e-pw/src/shared/assets/plugins/e2e/__init__.py b/e2e-pw/src/shared/assets/plugins/e2e/__init__.py index 6b0cbc4b3b..185c2614da 100644 --- a/e2e-pw/src/shared/assets/plugins/e2e/__init__.py +++ b/e2e-pw/src/shared/assets/plugins/e2e/__init__.py @@ -1,5 +1,7 @@ import fiftyone.operators as foo +import fiftyone.operators.types as types import json +import asyncio from bson import json_util @@ -21,5 +23,79 @@ def execute(self, ctx): return {} +class E2ESayHelloInModal(foo.Operator): + @property + def config(self): + return foo.OperatorConfig( + name="e2e_say_hello_in_modal", + label="E2E: Say hello in modal", + ) + + def resolve_input(self, ctx): + inputs = types.Object() + inputs.str("name", label="Name") + return types.Property(inputs) + + def execute(self, ctx): + name = ctx.params.get("name", "Anonymous") + return {"message": f"Hi {name}!"} + + def resolve_output(self, ctx): + outputs = types.Object() + outputs.str("message", label="Message") + return types.Property(outputs) + + +class E2ESayHelloInDrawer(foo.Operator): + @property + def config(self): + return foo.OperatorConfig( + name="e2e_say_hello_in_drawer", + label="E2E: Say hello in drawer", + ) + + def resolve_input(self, ctx): + inputs = types.Object() + inputs.str("name", label="Name") + return types.Property(inputs, view=types.DrawerView(placement="left")) + + def execute(self, ctx): + name = ctx.params.get("name", "Anonymous") + return {"message": f"Hi {name}!"} + + def resolve_output(self, ctx): + outputs = types.Object() + outputs.str("message", label="Message") + return types.Property(outputs) + + +class E2EProgress(foo.Operator): + @property + def config(self): + return foo.OperatorConfig( + name="e2e_progress", + label="E2E: Progress", + execute_as_generator=True, + ) + + async def execute(self, ctx): + MAX = 2 + for i in range(MAX + 1): + progress_label = f"Loading {i} of {MAX}" + progress_view = types.ProgressView(label=progress_label) + loading_schema = types.Object() + loading_schema.int("percent_complete", view=progress_view) + show_output_params = { + "outputs": types.Property(loading_schema).to_json(), + "results": {"percent_complete": i / MAX}, + } + yield ctx.trigger("show_output", show_output_params) + # simulate computation + await asyncio.sleep(0.5) + + def register(p): p.register(E2ESetView) + p.register(E2ESayHelloInModal) + p.register(E2ESayHelloInDrawer) + p.register(E2EProgress) diff --git a/e2e-pw/src/shared/assets/plugins/e2e/fiftyone.yml b/e2e-pw/src/shared/assets/plugins/e2e/fiftyone.yml index 328225f884..e46971d543 100644 --- a/e2e-pw/src/shared/assets/plugins/e2e/fiftyone.yml +++ b/e2e-pw/src/shared/assets/plugins/e2e/fiftyone.yml @@ -5,3 +5,6 @@ version: "1.0.0" description: "Operators for E2E tests" operators: - e2e_set_view + - e2e_say_hello_in_modal + - e2e_say_hello_in_drawer + - e2e_progress From cbb7c00b7217ccd80e5e3a95d2b33301d672acee Mon Sep 17 00:00:00 2001 From: brimoor Date: Thu, 23 May 2024 10:19:14 -0400 Subject: [PATCH 04/26] allow generated datasets to be directly created --- fiftyone/core/clips.py | 26 ++++++- fiftyone/core/dataset.py | 2 +- fiftyone/core/patches.py | 27 ++++++- fiftyone/core/stages.py | 25 ++++-- fiftyone/core/video.py | 11 ++- tests/unittests/patches_tests.py | 60 ++++++++++++++ tests/unittests/video_tests.py | 129 +++++++++++++++++++++++++++++++ 7 files changed, 264 insertions(+), 16 deletions(-) diff --git a/fiftyone/core/clips.py b/fiftyone/core/clips.py index 0dcd13dc30..8a385ba186 100644 --- a/fiftyone/core/clips.py +++ b/fiftyone/core/clips.py @@ -586,6 +586,8 @@ def make_clips_dataset( min_len=0, trajectories=False, name=None, + persistent=False, + _generated=False, ): """Creates a dataset that contains one sample per clip defined by the given field or expression in the collection. @@ -650,6 +652,8 @@ def make_clips_dataset( trajectory defined by their ``(label, index)``. Only applicable when ``field_or_expr`` is a frame-level field name (None): a name for the dataset + persistent (False): whether the dataset should persist in the database + after the session terminates Returns: a :class:`fiftyone.core.dataset.Dataset` @@ -675,9 +679,22 @@ def make_clips_dataset( else: clips_type = "manual" + if _generated: + _name = name + _persistent = persistent + else: + # We first create a temporary dataset with samples representing the + # clips; then we clone it to pull in the corresponding frames + _name = None + _persistent = False + dataset = fod.Dataset( - name=name, _clips=True, _src_collection=sample_collection + name=_name, + persistent=_persistent, + _clips=True, + _src_collection=sample_collection, ) + dataset.media_type = fom.VIDEO dataset.add_sample_field("sample_id", fof.ObjectIdField) dataset.add_sample_field("support", fof.FrameSupportField) @@ -750,6 +767,13 @@ def make_clips_dataset( other_fields=other_fields, ) + if not _generated: + # Clone so that dataset no longer shares the same underlying frames + # collection as the input collection + _dataset = dataset + dataset = _dataset.clone(name=name, persistent=persistent) + _dataset.delete() + return dataset diff --git a/fiftyone/core/dataset.py b/fiftyone/core/dataset.py index 333b3fd436..453fef59c8 100644 --- a/fiftyone/core/dataset.py +++ b/fiftyone/core/dataset.py @@ -7806,7 +7806,7 @@ def _get_frames_pipeline(sample_collection): view = None if dataset._is_clips: - # Clips datasets use `sample_id` to associated with frames, but now as + # Clips datasets use `sample_id` to associate with frames, but now as # a standalone collection, they must use `_id` coll = dataset._sample_collection pipeline = sample_collection._pipeline(attach_frames=True) + [ diff --git a/fiftyone/core/patches.py b/fiftyone/core/patches.py index fe7cdc17d7..a6dd410752 100644 --- a/fiftyone/core/patches.py +++ b/fiftyone/core/patches.py @@ -558,6 +558,8 @@ def make_patches_dataset( other_fields=None, keep_label_lists=False, name=None, + persistent=False, + _generated=False, ): """Creates a dataset that contains one sample per object patch in the specified field of the collection. @@ -586,6 +588,8 @@ def make_patches_dataset( fields of the same type as the input collection rather than using their single label variants name (None): a name for the dataset + persistent (False): whether the dataset should persist in the database + after the session terminates Returns: a :class:`fiftyone.core.dataset.Dataset` @@ -606,7 +610,12 @@ def make_patches_dataset( sample_collection, field, keep_label_lists ) - dataset = fod.Dataset(name=name, _patches=True, _frames=is_frame_patches) + dataset = fod.Dataset( + name=name, + persistent=persistent, + _patches=_generated, + _frames=is_frame_patches and _generated, + ) dataset.media_type = fom.IMAGE dataset.add_sample_field("sample_id", fof.ObjectIdField) dataset.create_index("sample_id") @@ -671,7 +680,12 @@ def _get_patches_field(sample_collection, field_name, keep_label_lists): def make_evaluation_patches_dataset( - sample_collection, eval_key, other_fields=None, name=None + sample_collection, + eval_key, + other_fields=None, + name=None, + persistent=False, + _generated=False, ): """Creates a dataset based on the results of the evaluation with the given key that contains one sample for each true positive, false positive, and @@ -720,6 +734,8 @@ def make_evaluation_patches_dataset( - ``True`` to include all other fields - ``None``/``False`` to include no other fields name (None): a name for the dataset + persistent (False): whether the dataset should persist in the database + after the session terminates Returns: a :class:`fiftyone.core.dataset.Dataset` @@ -757,7 +773,12 @@ def make_evaluation_patches_dataset( _pred_field = sample_collection.get_field(pred_field) # Setup dataset with correct schema - dataset = fod.Dataset(name=name, _patches=True, _frames=is_frame_patches) + dataset = fod.Dataset( + name=name, + persistent=persistent, + _patches=_generated, + _frames=is_frame_patches and _generated, + ) dataset.media_type = fom.IMAGE dataset.add_sample_field("sample_id", fof.ObjectIdField) dataset.create_index("sample_id") diff --git a/fiftyone/core/stages.py b/fiftyone/core/stages.py index 7aeeb53464..1bf6d080b6 100644 --- a/fiftyone/core/stages.py +++ b/fiftyone/core/stages.py @@ -7479,7 +7479,10 @@ def load_view(self, sample_collection): if state != last_state or not fod.dataset_exists(name): kwargs = self._config or {} patches_dataset = fop.make_patches_dataset( - sample_collection, self._field, **kwargs + sample_collection, + self._field, + _generated=True, + **kwargs, ) # Other views may use the same generated dataset, so reuse the old @@ -7623,7 +7626,10 @@ def load_view(self, sample_collection): if state != last_state or not fod.dataset_exists(name): kwargs = self._config or {} eval_patches_dataset = fop.make_evaluation_patches_dataset( - sample_collection, self._eval_key, **kwargs + sample_collection, + self._eval_key, + _generated=True, + **kwargs, ) # Other views may use the same generated dataset, so reuse the old @@ -7780,7 +7786,10 @@ def load_view(self, sample_collection): if state != last_state or not fod.dataset_exists(name): kwargs = self._config or {} clips_dataset = focl.make_clips_dataset( - sample_collection, self._field_or_expr, **kwargs + sample_collection, + self._field_or_expr, + _generated=True, + **kwargs, ) # Other views may use the same generated dataset, so reuse the old @@ -7914,7 +7923,11 @@ def load_view(self, sample_collection): if state != last_state or not fod.dataset_exists(name): kwargs = self._config or {} clips_dataset = focl.make_clips_dataset( - sample_collection, self._field, trajectories=True, **kwargs + sample_collection, + self._field, + trajectories=True, + _generated=True, + **kwargs, ) state["name"] = clips_dataset.name @@ -8098,7 +8111,9 @@ def load_view(self, sample_collection): if state != last_state or not fod.dataset_exists(name): kwargs = self._config or {} frames_dataset = fovi.make_frames_dataset( - sample_collection, **kwargs + sample_collection, + _generated=True, + **kwargs, ) # Other views may use the same generated dataset, so reuse the old diff --git a/fiftyone/core/video.py b/fiftyone/core/video.py index e267adbc02..7bca080645 100644 --- a/fiftyone/core/video.py +++ b/fiftyone/core/video.py @@ -484,6 +484,8 @@ def make_frames_dataset( skip_failures=True, verbose=False, name=None, + persistent=False, + _generated=False, ): """Creates a dataset that contains one sample per frame in the video collection. @@ -556,11 +558,6 @@ def make_frames_dataset( True, existing frames will not be resampled unless you set ``force_sample`` to True. - .. note:: - - The returned dataset is independent from the source collection; - modifying it will not affect the source collection. - Args: sample_collection: a :class:`fiftyone.core.collections.SampleCollection` @@ -609,6 +606,8 @@ def make_frames_dataset( verbose (False): whether to log information about the frames that will be sampled, if any name (None): a name for the dataset + persistent (False): whether the dataset should persist in the database + after the session terminates Returns: a :class:`fiftyone.core.dataset.Dataset` @@ -632,7 +631,7 @@ def make_frames_dataset( # Create dataset with proper schema # - dataset = fod.Dataset(name=name, _frames=True) + dataset = fod.Dataset(name=name, persistent=persistent, _frames=_generated) dataset.media_type = fom.IMAGE dataset.add_sample_field("sample_id", fof.ObjectIdField) diff --git a/tests/unittests/patches_tests.py b/tests/unittests/patches_tests.py index 1c7fb834d2..7e3d33f3ef 100644 --- a/tests/unittests/patches_tests.py +++ b/tests/unittests/patches_tests.py @@ -11,6 +11,7 @@ import unittest import fiftyone as fo +import fiftyone.core.patches as fop from fiftyone import ViewField as F from decorators import drop_datasets @@ -658,6 +659,65 @@ def test_to_evaluation_patches(self): self.assertTrue(still_view.is_saved) self.assertEqual(still_view, view) + @drop_datasets + def test_make_patches_dataset(self): + dataset = fo.Dataset() + + sample1 = fo.Sample( + filepath="image1.png", + tags=["sample1"], + ground_truth=fo.Detections( + detections=[ + fo.Detection(label="cat"), + fo.Detection(label="dog"), + fo.Detection(label="rabbit"), + fo.Detection(label="squirrel"), + ] + ), + predictions=fo.Detections( + detections=[ + fo.Detection(label="cat"), + fo.Detection(label="dog"), + fo.Detection(label="rabbit"), + fo.Detection(label="squirrel"), + ] + ), + ) + + sample2 = fo.Sample( + filepath="image2.png", + tags=["sample2"], + ground_truth=fo.Detections( + detections=[ + fo.Detection(label="cat"), + fo.Detection(label="dog"), + ] + ), + predictions=fo.Detections( + detections=[ + fo.Detection(label="cat"), + fo.Detection(label="dog"), + ] + ), + ) + + dataset.add_samples([sample1, sample2]) + + patches_view = dataset.to_patches("ground_truth") + patches_dataset = fop.make_patches_dataset(dataset, "ground_truth") + + self.assertNotEqual( + patches_dataset._sample_collection_name, + dataset._sample_collection_name, + ) + self.assertIsNone(patches_dataset._frame_collection_name) + self.assertTrue(patches_view._is_generated) + self.assertFalse(patches_dataset._is_generated) + self.assertEqual( + len(patches_dataset), dataset.count("ground_truth.detections") + ) + self.assertEqual(len(patches_dataset), len(patches_view)) + if __name__ == "__main__": fo.config.show_progress_bars = False diff --git a/tests/unittests/video_tests.py b/tests/unittests/video_tests.py index c7d7a4af42..1548fd0d5b 100644 --- a/tests/unittests/video_tests.py +++ b/tests/unittests/video_tests.py @@ -13,7 +13,9 @@ import unittest import fiftyone as fo +import fiftyone.core.clips as foc import fiftyone.core.odm as foo +import fiftyone.core.video as fov from fiftyone import ViewField as F from decorators import drop_datasets @@ -2197,6 +2199,62 @@ def test_to_frames_filepaths(self): self.assertEqual(frames.first().filepath, "BAR.JPG") self.assertEqual(dataset.first().frames.first().filepath, "BAR.JPG") + @drop_datasets + def test_make_frames_dataset(self): + dataset = fo.Dataset() + + sample1 = fo.Sample( + filepath="video1.mp4", + metadata=fo.VideoMetadata(total_frame_count=4), + tags=["test"], + weather="sunny", + ) + sample1.frames[1] = fo.Frame(filepath="frame11.jpg", hello="world") + sample1.frames[2] = fo.Frame( + filepath="frame12.jpg", + ground_truth=fo.Detections( + detections=[ + fo.Detection(label="cat"), + fo.Detection(label="dog"), + ] + ), + ) + sample1.frames[3] = fo.Frame(filepath="frame13.jpg", hello="goodbye") + + sample2 = fo.Sample( + filepath="video2.mp4", + metadata=fo.VideoMetadata(total_frame_count=5), + tags=["test"], + weather="cloudy", + ) + sample2.frames[1] = fo.Frame( + filepath="frame21.jpg", + hello="goodbye", + ground_truth=fo.Detections( + detections=[ + fo.Detection(label="dog"), + fo.Detection(label="rabbit"), + ] + ), + ) + sample2.frames[3] = fo.Frame(filepath="frame23.jpg") + sample2.frames[5] = fo.Frame(filepath="frame25.jpg", hello="there") + + dataset.add_samples([sample1, sample2]) + + frames_view = dataset.to_frames() + frames_dataset = fov.make_frames_dataset(dataset) + + self.assertNotEqual( + frames_dataset._sample_collection_name, + dataset._sample_collection_name, + ) + self.assertIsNone(frames_dataset._frame_collection_name) + self.assertTrue(frames_view._is_generated) + self.assertFalse(frames_dataset._is_generated) + self.assertEqual(len(frames_dataset), dataset.count("frames")) + self.assertEqual(len(frames_dataset), len(frames_view)) + @drop_datasets def test_to_clip_frames(self): dataset = fo.Dataset() @@ -3224,6 +3282,77 @@ def test_to_trajectories(self): schema = trajectories.get_frame_field_schema() self.assertIn("detections", schema) + @drop_datasets + def test_make_clips_dataset(self): + dataset = fo.Dataset() + + sample1 = fo.Sample( + filepath="video1.mp4", + metadata=fo.VideoMetadata(total_frame_count=4), + tags=["test"], + weather="sunny", + events=fo.TemporalDetections( + detections=[ + fo.TemporalDetection(label="meeting", support=[1, 3]), + fo.TemporalDetection(label="party", support=[2, 4]), + ] + ), + ) + sample1.frames[1] = fo.Frame(hello="world") + sample1.frames[2] = fo.Frame( + ground_truth=fo.Detections( + detections=[ + fo.Detection(label="cat"), + fo.Detection(label="dog"), + ] + ) + ) + sample1.frames[3] = fo.Frame(hello="goodbye") + + sample2 = fo.Sample( + filepath="video2.mp4", + metadata=fo.VideoMetadata(total_frame_count=5), + tags=["test"], + weather="cloudy", + events=fo.TemporalDetections( + detections=[ + fo.TemporalDetection(label="party", support=[3, 5]), + fo.TemporalDetection(label="meeting", support=[1, 3]), + ] + ), + ) + sample2.frames[1] = fo.Frame( + hello="goodbye", + ground_truth=fo.Detections( + detections=[ + fo.Detection(label="dog"), + fo.Detection(label="rabbit"), + ] + ), + ) + sample2.frames[3] = fo.Frame() + sample2.frames[5] = fo.Frame(hello="there") + + dataset.add_samples([sample1, sample2]) + + clips_view = dataset.to_clips("events") + clips_dataset = foc.make_clips_dataset(dataset, "events") + + self.assertNotEqual( + clips_dataset._sample_collection_name, + dataset._sample_collection_name, + ) + self.assertNotEqual( + clips_dataset._frame_collection_name, + dataset._frame_collection_name, + ) + self.assertTrue(clips_view._is_generated) + self.assertFalse(clips_dataset._is_generated) + self.assertEqual(len(clips_dataset), len(clips_view)) + self.assertEqual( + clips_dataset.count("frames"), clips_view.count("frames") + ) + if __name__ == "__main__": fo.config.show_progress_bars = False From 6cd7b0c3a3b9dd9d82de2f78c9caf6d324be6fb4 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 10 May 2024 17:19:24 -0400 Subject: [PATCH 05/26] load individual cvat job annotations instead of entire task --- fiftyone/utils/cvat.py | 280 +++++++++++++++++++++-------------------- 1 file changed, 145 insertions(+), 135 deletions(-) diff --git a/fiftyone/utils/cvat.py b/fiftyone/utils/cvat.py index 06cd6921c4..04501a3b9f 100644 --- a/fiftyone/utils/cvat.py +++ b/fiftyone/utils/cvat.py @@ -3671,6 +3671,9 @@ def job_url(self, task_id, job_id): else: return "%s/%d" % (self.jobs_url(task_id), job_id) + def job_annotation_url(self, job_id): + return "%s/annotations" % self.taskless_job_url(job_id) + def taskless_job_url(self, job_id): return "%s/jobs/%d" % (self.base_api_url, job_id) @@ -4263,16 +4266,7 @@ def upload_data( # It can take a bit for jobs to show up, so we poll job_ids = [] while not job_ids: - url = self.jobs_url(task_id) - if self._server_version >= Version("2.4"): - job_resp_json = self._get_paginated_results(url) - else: - job_resp = self.get(url) - job_resp_json = job_resp.json() - if "results" in job_resp_json: - job_resp_json = job_resp_json["results"] - - job_ids = [j["id"] for j in job_resp_json] + job_ids = self._get_job_ids(task_id) if not job_ids: time.sleep(1) @@ -4641,119 +4635,92 @@ def download_annotations(self, results): attr_id_map, _class_map_rev = self._get_attr_class_maps( task_id ) - task_resp = self.get(self.task_annotation_url(task_id)).json() - all_shapes = task_resp["shapes"] - all_tags = task_resp["tags"] - all_tracks = task_resp["tracks"] - - # For videos that were subsampled, remap the frame numbers to - # those on the original video - all_shapes = _remap_annotation_frames( - all_shapes, frame_start, frame_stop, frame_step - ) - all_tags = _remap_annotation_frames( - all_tags, frame_start, frame_stop, frame_step - ) - all_tracks = _remap_annotation_frames( - all_tracks, frame_start, frame_stop, frame_step - ) - label_fields = labels_task_map_rev[task_id] - label_types = self._get_return_label_types( - label_schema, label_fields - ) - - for lf_ind, label_field in enumerate(label_fields): - label_info = label_schema[label_field] - label_type = label_info.get("type", None) - scalar_attrs = assigned_scalar_attrs.get( - label_field, False + job_ids = self._get_job_ids(task_id) + for job_id in job_ids: + job_resp = self.get(self.job_annotation_url(job_id)).json() + all_shapes = job_resp["shapes"] + all_tags = job_resp["tags"] + all_tracks = job_resp["tracks"] + + # For videos that were subsampled, remap the frame numbers to + # those on the original video + all_shapes = _remap_annotation_frames( + all_shapes, frame_start, frame_stop, frame_step + ) + all_tags = _remap_annotation_frames( + all_tags, frame_start, frame_stop, frame_step + ) + all_tracks = _remap_annotation_frames( + all_tracks, frame_start, frame_stop, frame_step ) - _occluded_attrs = occluded_attrs.get(label_field, {}) - _group_id_attrs = group_id_attrs.get(label_field, {}) - _id_map = id_map.get(label_field, {}) - - label_field_results = {} - # Dict mapping class labels to the classes used in CVAT. - # These are equal unless a class appears in multiple fields - _classes = label_field_classes[label_field] + label_fields = labels_task_map_rev[task_id] + label_types = self._get_return_label_types( + label_schema, label_fields + ) - # Maps CVAT IDs to FiftyOne labels - class_map = { - _class_map_rev[name_lf]: name - for name, name_lf in _classes.items() - } + for lf_ind, label_field in enumerate(label_fields): + label_info = label_schema[label_field] + label_type = label_info.get("type", None) + scalar_attrs = assigned_scalar_attrs.get( + label_field, False + ) + _occluded_attrs = occluded_attrs.get(label_field, {}) + _group_id_attrs = group_id_attrs.get(label_field, {}) + _id_map = id_map.get(label_field, {}) - _cvat_classes = class_map.keys() - tags, shapes, tracks = self._filter_field_classes( - all_tags, - all_shapes, - all_tracks, - _cvat_classes, - ) + label_field_results = {} - is_last_field = lf_ind == len(label_fields) - 1 - ignore_types = self._get_ignored_types( - project_id, label_types, label_type, is_last_field - ) + # Dict mapping class labels to the classes used in CVAT. + # These are equal unless a class appears in multiple fields + _classes = label_field_classes[label_field] - tag_results = self._parse_shapes_tags( - "tags", - tags, - frame_id_map[task_id], - label_type, - _id_map, - server_id_map.get("tags", {}), - class_map, - attr_id_map, - frames, - ignore_types, - frame_stop, - frame_step, - assigned_scalar_attrs=scalar_attrs, - ) - label_field_results = self._merge_results( - label_field_results, tag_results - ) + # Maps CVAT IDs to FiftyOne labels + class_map = { + _class_map_rev[name_lf]: name + for name, name_lf in _classes.items() + } - shape_results = self._parse_shapes_tags( - "shapes", - shapes, - frame_id_map[task_id], - label_type, - _id_map, - server_id_map.get("shapes", {}), - class_map, - attr_id_map, - frames, - ignore_types, - frame_stop, - frame_step, - assigned_scalar_attrs=scalar_attrs, - occluded_attrs=_occluded_attrs, - group_id_attrs=_group_id_attrs, - ) - label_field_results = self._merge_results( - label_field_results, shape_results - ) + _cvat_classes = class_map.keys() + tags, shapes, tracks = self._filter_field_classes( + all_tags, + all_shapes, + all_tracks, + _cvat_classes, + ) - for track_index, track in enumerate(tracks, 1): - label_id = track["label_id"] - shapes = track["shapes"] - track_group_id = track.get("group", None) - for shape in shapes: - shape["label_id"] = label_id + is_last_field = lf_ind == len(label_fields) - 1 + ignore_types = self._get_ignored_types( + project_id, label_types, label_type, is_last_field + ) - immutable_attrs = track["attributes"] + tag_results = self._parse_shapes_tags( + "tags", + tags, + frame_id_map[task_id], + label_type, + _id_map, + server_id_map.get("tags", {}), + class_map, + attr_id_map, + frames, + ignore_types, + frame_stop, + frame_step, + assigned_scalar_attrs=scalar_attrs, + ) + label_field_results = self._merge_results( + label_field_results, tag_results + ) - track_shape_results = self._parse_shapes_tags( - "track", + shape_results = self._parse_shapes_tags( + "shapes", shapes, frame_id_map[task_id], label_type, _id_map, - server_id_map.get("tracks", {}), + server_id_map.get("shapes", {}), class_map, attr_id_map, frames, @@ -4761,41 +4728,71 @@ def download_annotations(self, results): frame_stop, frame_step, assigned_scalar_attrs=scalar_attrs, - track_index=track_index, - track_group_id=track_group_id, - immutable_attrs=immutable_attrs, occluded_attrs=_occluded_attrs, group_id_attrs=_group_id_attrs, ) label_field_results = self._merge_results( - label_field_results, track_shape_results + label_field_results, shape_results ) - frames_metadata = {} - for cvat_frame_id, frame_data in frame_id_map[ - task_id - ].items(): - sample_id = frame_data["sample_id"] - if "frame_id" in frame_data and len(frames) == 1: - frames_metadata[sample_id] = frames[0] - break - - if len(frames) > cvat_frame_id: - frame_metadata = frames[cvat_frame_id] - else: - frame_metadata = None - - frames_metadata[sample_id] = frame_metadata + for track_index, track in enumerate(tracks, 1): + label_id = track["label_id"] + shapes = track["shapes"] + track_group_id = track.get("group", None) + for shape in shapes: + shape["label_id"] = label_id + + immutable_attrs = track["attributes"] + + track_shape_results = self._parse_shapes_tags( + "track", + shapes, + frame_id_map[task_id], + label_type, + _id_map, + server_id_map.get("tracks", {}), + class_map, + attr_id_map, + frames, + ignore_types, + frame_stop, + frame_step, + assigned_scalar_attrs=scalar_attrs, + track_index=track_index, + track_group_id=track_group_id, + immutable_attrs=immutable_attrs, + occluded_attrs=_occluded_attrs, + group_id_attrs=_group_id_attrs, + ) + label_field_results = self._merge_results( + label_field_results, track_shape_results + ) - # Polyline(s) corresponding to instance/semantic masks need to - # be converted to their final format - self._convert_polylines_to_masks( - label_field_results, label_info, frames_metadata - ) + frames_metadata = {} + for cvat_frame_id, frame_data in frame_id_map[ + task_id + ].items(): + sample_id = frame_data["sample_id"] + if "frame_id" in frame_data and len(frames) == 1: + frames_metadata[sample_id] = frames[0] + break + + if len(frames) > cvat_frame_id: + frame_metadata = frames[cvat_frame_id] + else: + frame_metadata = None + + frames_metadata[sample_id] = frame_metadata + + # Polyline(s) corresponding to instance/semantic masks need to + # be converted to their final format + self._convert_polylines_to_masks( + label_field_results, label_info, frames_metadata + ) - annotations = self._merge_results( - annotations, {label_field: label_field_results} - ) + annotations = self._merge_results( + annotations, {label_field: label_field_results} + ) if deleted_tasks: results._forget_tasks(deleted_tasks) @@ -4903,6 +4900,19 @@ def _get_task_id_labels_json(self, task_json): return task_id, labels + def _get_job_ids(self, task_id): + url = self.jobs_url(task_id) + if self._server_version >= Version("2.4"): + job_resp_json = self._get_paginated_results(url) + else: + job_resp = self.get(url) + job_resp_json = job_resp.json() + if "results" in job_resp_json: + job_resp_json = job_resp_json["results"] + + job_ids = [j["id"] for j in job_resp_json] + return job_ids + def _parse_project_details(self, project_name, project_id): if project_id is not None: project_name = self.get_project_name(project_id) From b726dcb7ac381bfccda07c27a34e2fb7ccd4912f Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 10 May 2024 17:23:54 -0400 Subject: [PATCH 06/26] update test to create multiple jobs --- tests/intensive/cvat_tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/intensive/cvat_tests.py b/tests/intensive/cvat_tests.py index ad56cca11f..a77adb8530 100644 --- a/tests/intensive/cvat_tests.py +++ b/tests/intensive/cvat_tests.py @@ -306,6 +306,7 @@ def test_detection_labelling(self): backend="cvat", label_field="ground_truth", attributes=attributes, + segment_size=1, ) with results: From 88627a41570c57b4a18f3eaba5fcdf047bc95c74 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 10 May 2024 17:58:02 -0400 Subject: [PATCH 07/26] lint --- fiftyone/utils/cvat.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/fiftyone/utils/cvat.py b/fiftyone/utils/cvat.py index 04501a3b9f..8e1e27905f 100644 --- a/fiftyone/utils/cvat.py +++ b/fiftyone/utils/cvat.py @@ -3052,8 +3052,8 @@ class CVATBackendConfig(foua.AnnotationBackendConfig): task. Videos are always uploaded one per task segment_size (None): maximum number of images per job. Not applicable to videos - image_quality (75): an int in ``[0, 100]`` determining the image quality - to upload to CVAT + image_quality (75): an int in ``[0, 100]`` determining the image + quality to upload to CVAT use_cache (True): whether to use a cache when uploading data. Using a cache reduces task creation time as data will be processed on-the-fly and stored in the cache when requested @@ -3074,7 +3074,8 @@ class CVATBackendConfig(foua.AnnotationBackendConfig): default, no project is used project_id (None): an optional ID of an existing CVAT project to which to upload the annotation tasks. By default, no project is used - task_name (None): an optional task name to use for the created CVAT task + task_name (None): an optional task name to use for the created CVAT + task occluded_attr (None): an optional attribute name containing existing occluded values and/or in which to store downloaded occluded values for all objects in the annotation run @@ -4311,7 +4312,8 @@ def _parse_local_files(self, paths): if self._server_version < Version("2.4.6"): # IMPORTANT: older versions of CVAT organizes media within # a task alphabetically by filename, so we must give CVAT - # filenames whose alphabetical order matches the order of `paths` + # filenames whose alphabetical order matches the order of + # `paths` filename = "%06d_%s" % (idx, os.path.basename(path)) if self._server_version >= Version("2.3"): @@ -4643,8 +4645,8 @@ def download_annotations(self, results): all_tags = job_resp["tags"] all_tracks = job_resp["tracks"] - # For videos that were subsampled, remap the frame numbers to - # those on the original video + # For videos that were subsampled, remap the frame numbers + # to those on the original video all_shapes = _remap_annotation_frames( all_shapes, frame_start, frame_stop, frame_step ) @@ -4672,8 +4674,9 @@ def download_annotations(self, results): label_field_results = {} - # Dict mapping class labels to the classes used in CVAT. - # These are equal unless a class appears in multiple fields + # Dict mapping class labels to the classes used in + # CVAT. These are equal unless a class appears in + # multiple fields _classes = label_field_classes[label_field] # Maps CVAT IDs to FiftyOne labels @@ -4784,8 +4787,8 @@ def download_annotations(self, results): frames_metadata[sample_id] = frame_metadata - # Polyline(s) corresponding to instance/semantic masks need to - # be converted to their final format + # Polyline(s) corresponding to instance/semantic masks + # need to be converted to their final format self._convert_polylines_to_masks( label_field_results, label_info, frames_metadata ) From 584f6b6232c24bf5023915251f82c32cb33244d5 Mon Sep 17 00:00:00 2001 From: brimoor Date: Wed, 5 Jun 2024 11:08:19 -0400 Subject: [PATCH 08/26] add ultralytics yolov8 open images v7 pretrained models into zoo --- fiftyone/zoo/models/manifest-torch.json | 160 ++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/fiftyone/zoo/models/manifest-torch.json b/fiftyone/zoo/models/manifest-torch.json index e154afe1ef..bff58f24fe 100644 --- a/fiftyone/zoo/models/manifest-torch.json +++ b/fiftyone/zoo/models/manifest-torch.json @@ -3087,6 +3087,166 @@ "tags": ["detection", "torch", "yolo", "polylines", "obb"], "date_added": "2024-04-05 19:22:51" }, + { + "base_name": "yolov8n-oiv7-torch", + "base_filename": "yolov8n-oiv7.pt", + "description": "Ultralytics YOLOv8n model trained on Open Images v7", + "source": "https://docs.ultralytics.com/datasets/detect/open-images-v7", + "size_bytes": 6534387, + "manager": { + "type": "fiftyone.core.models.ModelManager", + "config": { + "url": "https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8n-oiv7.pt" + } + }, + "default_deployment_config_dict": { + "type": "fiftyone.utils.ultralytics.FiftyOneYOLODetectionModel", + "config": {} + }, + "requirements": { + "packages": [ + "torch>=1.7.0", + "torchvision>=0.8.1", + "ultralytics" + ], + "cpu": { + "support": true + }, + "gpu": { + "support": true + } + }, + "tags": ["detection", "oiv7", "torch", "yolo"], + "date_added": "2024-05-20 19:22:51" + }, + { + "base_name": "yolov8s-oiv7-torch", + "base_filename": "yolov8s-oiv7.pt", + "description": "Ultralytics YOLOv8s model trained on Open Images v7", + "source": "https://docs.ultralytics.com/datasets/detect/open-images-v7", + "size_bytes": 22573363, + "manager": { + "type": "fiftyone.core.models.ModelManager", + "config": { + "url": "https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8s-oiv7.pt" + } + }, + "default_deployment_config_dict": { + "type": "fiftyone.utils.ultralytics.FiftyOneYOLODetectionModel", + "config": {} + }, + "requirements": { + "packages": [ + "torch>=1.7.0", + "torchvision>=0.8.1", + "ultralytics" + ], + "cpu": { + "support": true + }, + "gpu": { + "support": true + } + }, + "tags": ["detection", "oiv7", "torch", "yolo"], + "date_added": "2024-05-20 19:22:51" + }, + { + "base_name": "yolov8m-oiv7-torch", + "base_filename": "yolov8m-oiv7.pt", + "description": "Ultralytics YOLOv8m model trained Open Images v7", + "source": "https://docs.ultralytics.com/datasets/detect/open-images-v7", + "size_bytes": 52117635, + "manager": { + "type": "fiftyone.core.models.ModelManager", + "config": { + "url": "https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8m-oiv7.pt" + } + }, + "default_deployment_config_dict": { + "type": "fiftyone.utils.ultralytics.FiftyOneYOLODetectionModel", + "config": {} + }, + "requirements": { + "packages": [ + "torch>=1.7.0", + "torchvision>=0.8.1", + "ultralytics" + ], + "cpu": { + "support": true + }, + "gpu": { + "support": true + } + }, + "tags": ["detection", "oiv7", "torch", "yolo"], + "date_added": "2024-05-20 19:22:51" + }, + { + "base_name": "yolov8l-oiv7-torch", + "base_filename": "yolov8l-oiv7.pt", + "description": "Ultralytics YOLOv8l model trained Open Images v7", + "source": "https://docs.ultralytics.com/datasets/detect/open-images-v7", + "size_bytes": 87769683, + "manager": { + "type": "fiftyone.core.models.ModelManager", + "config": { + "url": "https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8l-oiv7.pt" + } + }, + "default_deployment_config_dict": { + "type": "fiftyone.utils.ultralytics.FiftyOneYOLODetectionModel", + "config": {} + }, + "requirements": { + "packages": [ + "torch>=1.7.0", + "torchvision>=0.8.1", + "ultralytics" + ], + "cpu": { + "support": true + }, + "gpu": { + "support": true + } + }, + "tags": ["detection", "oiv7", "torch", "yolo"], + "date_added": "2024-05-20 19:22:51" + }, + { + "base_name": "yolov8x-oiv7-torch", + "base_filename": "yolov8x-oiv7.pt", + "description": "Ultralytics YOLOv8x model trained Open Images v7", + "source": "https://docs.ultralytics.com/datasets/detect/open-images-v7", + "size_bytes": 136867539, + "manager": { + "type": "fiftyone.core.models.ModelManager", + "config": { + "url": "https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8x-oiv7.pt" + } + }, + "default_deployment_config_dict": { + "type": "fiftyone.utils.ultralytics.FiftyOneYOLODetectionModel", + "config": {} + }, + "requirements": { + "packages": [ + "torch>=1.7.0", + "torchvision>=0.8.1", + "ultralytics" + ], + "cpu": { + "support": true + }, + "gpu": { + "support": true + } + }, + "tags": ["detection", "oiv7", "torch", "yolo"], + "date_added": "2024-05-20 19:22:51" + }, { "base_name": "yolo-nas-torch", "base_filename": null, From 8883b5ab92fdf0878a0fc9429a3ec0eb0b9e9967 Mon Sep 17 00:00:00 2001 From: brimoor Date: Thu, 30 May 2024 10:03:43 -0400 Subject: [PATCH 09/26] handle partial maps when updating Scene asset paths --- fiftyone/core/threed/scene_3d.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fiftyone/core/threed/scene_3d.py b/fiftyone/core/threed/scene_3d.py index 1eec4993b1..d07cec127a 100644 --- a/fiftyone/core/threed/scene_3d.py +++ b/fiftyone/core/threed/scene_3d.py @@ -276,7 +276,7 @@ def update_asset_paths(self, asset_rewrite_paths: dict): asset_path = getattr(node, path_attribute, None) new_asset_path = asset_rewrite_paths.get(asset_path) - if asset_path is not None and asset_path != new_asset_path: + if new_asset_path is not None and asset_path != new_asset_path: setattr(node, path_attribute, new_asset_path) scene_modified = True @@ -284,13 +284,16 @@ def update_asset_paths(self, asset_rewrite_paths: dict): if self.background is not None: if self.background.image is not None: new_asset_path = asset_rewrite_paths.get(self.background.image) - if new_asset_path != self.background.image: + if ( + new_asset_path is not None + and new_asset_path != self.background.image + ): self.background.image = new_asset_path scene_modified = True if self.background.cube is not None: new_cube = [ - asset_rewrite_paths.get(face) + asset_rewrite_paths.get(face, face) for face in self.background.cube ] if new_cube != self.background.cube: From 56fc86be99593dd74e2385f3ee384b25476ad949 Mon Sep 17 00:00:00 2001 From: brimoor Date: Thu, 30 May 2024 10:35:48 -0400 Subject: [PATCH 10/26] adding unit test for updating asset paths --- fiftyone/core/threed/object_3d.py | 6 ++--- fiftyone/core/threed/scene_3d.py | 2 +- tests/unittests/threed/scene_3d_tests.py | 30 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/fiftyone/core/threed/object_3d.py b/fiftyone/core/threed/object_3d.py index a82d8c5e87..8ee213322f 100644 --- a/fiftyone/core/threed/object_3d.py +++ b/fiftyone/core/threed/object_3d.py @@ -26,7 +26,7 @@ threed = fou.lazy_import("fiftyone.core.threed") -class Object3D: +class Object3D(object): """The base class for all 3D objects in the scene. Args: @@ -37,7 +37,7 @@ class Object3D: scale (None): the scale of the object in object space """ - _asset_path_fields = None + _asset_path_fields = [] def __init__( self, @@ -227,7 +227,7 @@ def _get_asset_paths(self) -> List[str]: """Get asset paths for this node""" return [ getattr(self, f, None) - for f in (self._asset_path_fields or []) + for f in self._asset_path_fields if getattr(self, f, None) is not None ] diff --git a/fiftyone/core/threed/scene_3d.py b/fiftyone/core/threed/scene_3d.py index d07cec127a..48745647e7 100644 --- a/fiftyone/core/threed/scene_3d.py +++ b/fiftyone/core/threed/scene_3d.py @@ -186,7 +186,7 @@ def copy(self): return Scene._from_fo3d_dict(self.as_dict()) def _resolve_node_asset_paths(self, node, fo3d_path_dir): - for asset_path_field in node._asset_path_fields or []: + for asset_path_field in node._asset_path_fields: asset_path = getattr(node, asset_path_field, None) if asset_path: resolved_asset_path = self._resolve_asset_path( diff --git a/tests/unittests/threed/scene_3d_tests.py b/tests/unittests/threed/scene_3d_tests.py index fe6162ac4f..0af72e442d 100644 --- a/tests/unittests/threed/scene_3d_tests.py +++ b/tests/unittests/threed/scene_3d_tests.py @@ -71,6 +71,36 @@ def test_get_asset_paths(self): }, ) + def test_update_asset_paths(self): + d = { + "/path/to/pcd.pcd": "new.pcd", + "../background.jpeg": "new_background.jpeg", + "n3.jpeg": "new_n3.jpeg", + } + + self.scene.update_asset_paths(d) + + asset_paths = set(self.scene.get_asset_paths()) + self.assertSetEqual( + asset_paths, + { + "/path/to/gltf.gltf", + "new.pcd", + "new_background.jpeg", + "/path/to/stl.stl", + "/path/to/fbx.fbx", + "/path/to/ply.ply", + "/path/to/obj.obj", + "relative.gltf", + "n1.jpeg", + "n2.jpeg", + "new_n3.jpeg", + "n4.jpeg", + "n5.jpeg", + "n6.jpeg", + }, + ) + def test_write(self): with tempfile.TemporaryDirectory() as temp_dir: path = os.path.join(temp_dir, "blah.fo3d") From 3914ced609db977cc2c4492cdf7b17c8daea8512 Mon Sep 17 00:00:00 2001 From: brimoor Date: Mon, 3 Jun 2024 09:29:06 -0400 Subject: [PATCH 11/26] optimize 3D operations --- fiftyone/core/metadata.py | 194 ++++++++++++++++++------------- fiftyone/core/storage.py | 4 +- fiftyone/core/threed/scene_3d.py | 10 +- fiftyone/utils/data/exporters.py | 44 +++---- fiftyone/utils/utils3d.py | 4 +- 5 files changed, 142 insertions(+), 114 deletions(-) diff --git a/fiftyone/core/metadata.py b/fiftyone/core/metadata.py index 63e716429e..e3dbcdb714 100644 --- a/fiftyone/core/metadata.py +++ b/fiftyone/core/metadata.py @@ -5,23 +5,21 @@ | `voxel51.com `_ | """ -import collections -import json +from collections import defaultdict +import itertools import logging import multiprocessing.dummy import os -import pathlib import requests - from PIL import Image import eta.core.utils as etau import eta.core.video as etav -from fiftyone.core.odm import DynamicEmbeddedDocument import fiftyone.core.fields as fof import fiftyone.core.media as fom +from fiftyone.core.odm import DynamicEmbeddedDocument import fiftyone.core.storage as fos import fiftyone.core.threed as fo3d import fiftyone.core.utils as fou @@ -78,71 +76,6 @@ def _build_for_url(cls, url, mime_type=None): return cls(size_bytes=size_bytes, mime_type=mime_type) -class SceneMetadata(Metadata): - """Class for storing metadata about 3D scene samples. - - Args: - size_bytes (None): the size of scene definition and all children - assets on disk, in bytes - mime_type (None): the MIME type of the scene media. Always set to - application/octet-stream - asset_counts (None): dict of child asset file type to count - """ - - asset_counts = fof.DictField - - @classmethod - def build_for(cls, scene_path, mime_type=None): - """Builds a :class:`SceneMetadata` object for the given 3D Scene. - - Args: - scene_path: a scene path or URL - mime_type (None): Ignored. mime_type always set to - application/octet-stream - - Returns: - a :class:`SceneMetadata` - """ - if not etau.is_str(scene_path): - raise ValueError("Invalid scene or path:", scene_path) - - scene = fo3d.Scene.from_fo3d(scene_path) - scene_dict = scene.as_dict() - total_size = len(json.dumps(scene_dict)) - asset_counts = collections.defaultdict(int) - mime_type = "application/octet-stream" - - # Get asset paths and resolve all to absolute - asset_paths = scene.get_asset_paths() - scene_dir = os.path.dirname(scene_path) - for i, asset_path in enumerate(asset_paths): - if not fos.isabs(asset_path): - asset_path = fos.join(scene_dir, asset_path) - asset_paths[i] = fos.resolve(asset_path) - file_type = pathlib.Path(asset_path).suffix[1:] - asset_counts[file_type] += 1 - - # Dedupe asset paths within this single scene - asset_paths = list(set(asset_paths)) - - # compute metadata for all asset paths - asset_metadatas = fos.run( - _do_compute_metadata, - [ - (i, asset_path, fom.MIXED) - for i, asset_path in enumerate(asset_paths) - ], - progress=False, - ) - total_size += sum(m[1].size_bytes for m in asset_metadatas) - - return cls( - size_bytes=total_size, - mime_type=mime_type, - asset_counts=asset_counts, - ) - - class ImageMetadata(Metadata): """Class for storing metadata about image samples. @@ -279,6 +212,100 @@ def build_for(cls, video_path_or_url, mime_type=None): ) +class SceneMetadata(Metadata): + """Class for storing metadata about 3D scene samples. + + Args: + size_bytes (None): the size of scene definition and all children + assets on disk, in bytes + mime_type (None): the MIME type of the scene + asset_counts (None): dict of child asset file type to count + """ + + asset_counts = fof.DictField() + + @classmethod + def build_for(cls, scene_path, mime_type=None): + """Builds a :class:`SceneMetadata` object for the given 3D scene. + + Args: + scene_path: a scene path + mime_type (None): the MIME type of the scene. If not provided, + defaults to ``application/octet-stream`` + + Returns: + a :class:`SceneMetadata` + """ + return cls._build_for(scene_path, mime_type=mime_type) + + @classmethod + def _build_for(cls, scene_path, mime_type=None, cache=None): + if mime_type is None: + mime_type = "application/octet-stream" + + # Unclear how asset paths should be handled; the rest of the library is + # not equipped to handle URL asset paths + if scene_path.startswith("http"): + raise ValueError("Scene URLs are not currently supported") + + total_size = os.path.getsize(scene_path) + + scene = fo3d.Scene.from_fo3d(scene_path) + asset_paths = scene.get_asset_paths() + + asset_counts = defaultdict(int) + scene_dir = os.path.dirname(scene_path) + for i, asset_path in enumerate(asset_paths): + if not fos.isabs(asset_path): + asset_path = fos.resolve(fos.join(scene_dir, asset_path)) + asset_paths[i] = asset_path + + file_type = os.path.splitext(asset_path)[1][1:] + asset_counts[file_type] += 1 + + asset_counts = dict(asset_counts) + total_size += _compute_asset_sizes(asset_paths, cache=cache) + + return cls( + size_bytes=total_size, + mime_type=mime_type, + asset_counts=asset_counts, + ) + + +def _compute_asset_sizes(asset_paths, cache=None): + total_size = 0 + + tasks = [] + for asset_path in asset_paths: + if cache is not None: + metadata = cache.get(asset_path, None) + if metadata is not None: + total_size += metadata.size_bytes + continue + + tasks.append((None, asset_path, fom.MIXED, cache)) + + results = [] + if len(tasks) <= 1: + for task in tasks: + results.append(_do_compute_metadata(task)) + else: + num_workers = fou.recommend_thread_pool_workers(min(len(tasks), 8)) + with multiprocessing.dummy.Pool(processes=num_workers) as pool: + results.extend(pool.imap(_do_compute_metadata, tasks)) + + for task, result in zip(tasks, results): + metadata = result[1] + total_size += metadata.size_bytes + + if cache is not None: + scene_path = task[1] + cache[scene_path] = metadata + + return total_size + + def compute_sample_metadata(sample, overwrite=False, skip_failures=False): """Populates the ``metadata`` field of the sample. @@ -444,8 +471,9 @@ def _compute_metadata( logger.info("Computing metadata...") - inputs = zip(ids, filepaths, media_types) + cache = {} values = {} + inputs = zip(ids, filepaths, media_types, itertools.repeat(cache)) try: with fou.ProgressBar(total=num_samples, progress=progress) as pb: @@ -482,8 +510,9 @@ def _compute_metadata_multi( logger.info("Computing metadata...") - inputs = zip(ids, filepaths, media_types) + cache = {} values = {} + inputs = zip(ids, filepaths, media_types, itertools.repeat(cache)) try: with multiprocessing.dummy.Pool(processes=num_workers) as pool: @@ -502,30 +531,37 @@ def _compute_metadata_multi( def _do_compute_metadata(args): - sample_id, filepath, media_type = args + sample_id, filepath, media_type, cache = args metadata = _compute_sample_metadata( - filepath, media_type, skip_failures=True + filepath, media_type, skip_failures=True, cache=cache ) return sample_id, metadata -def _compute_sample_metadata(filepath, media_type, skip_failures=False): +def _compute_sample_metadata( + filepath, media_type, skip_failures=False, cache=None +): if not skip_failures: - return _get_metadata(filepath, media_type) + return _get_metadata(filepath, media_type, cache=cache) try: - return _get_metadata(filepath, media_type) + return _get_metadata(filepath, media_type, cache=cache) except: return None -def _get_metadata(filepath, media_type): +def _get_metadata(filepath, media_type, cache=None): + if cache is not None: + metadata = cache.get(filepath, None) + if metadata is not None: + return metadata + if media_type == fom.IMAGE: metadata = ImageMetadata.build_for(filepath) elif media_type == fom.VIDEO: metadata = VideoMetadata.build_for(filepath) elif media_type == fom.THREE_D: - metadata = SceneMetadata.build_for(filepath) + metadata = SceneMetadata._build_for(filepath, cache=cache) else: metadata = Metadata.build_for(filepath) diff --git a/fiftyone/core/storage.py b/fiftyone/core/storage.py index 7335d02e05..53d8a9f1ce 100644 --- a/fiftyone/core/storage.py +++ b/fiftyone/core/storage.py @@ -282,8 +282,8 @@ def join(a, *p): def resolve(path): - """Resolves path to absolute, resolving symlinks and relative path - indicators such as `.` and `..`. + """Resolves the given path to absolute, resolving symlinks and relative + path indicators such as ``.`` and ``..``. Args: path: the filepath diff --git a/fiftyone/core/threed/scene_3d.py b/fiftyone/core/threed/scene_3d.py index 48745647e7..220efb16a4 100644 --- a/fiftyone/core/threed/scene_3d.py +++ b/fiftyone/core/threed/scene_3d.py @@ -323,19 +323,19 @@ def get_asset_paths(self): Returns: a list of asset paths """ - asset_paths = list( + asset_paths = set( itertools.chain.from_iterable( node._get_asset_paths() for node in self.traverse() ) ) - # append paths in scene background, if any if self.background is not None: if self.background.image is not None: - asset_paths.append(self.background.image) + asset_paths.add(self.background.image) if self.background.cube is not None: - asset_paths.extend(self.background.cube) - return asset_paths + asset_paths.update(self.background.cube) + + return list(asset_paths) def _resolve_asset_path(self, root: str, path: str): if path is None: diff --git a/fiftyone/utils/data/exporters.py b/fiftyone/utils/data/exporters.py index 3d5ca399fc..3bf0b8aa77 100644 --- a/fiftyone/utils/data/exporters.py +++ b/fiftyone/utils/data/exporters.py @@ -1164,8 +1164,8 @@ def __init__( self._manifest = None self._manifest_path = None - def _handle_fo3d_file(self, fo3d_path, fo3d_output_path, export_mode): - if export_mode in (False, "manifest"): + def _handle_fo3d_file(self, fo3d_path, fo3d_output_path): + if self.export_mode in (False, "manifest"): return scene = fo3d.Scene.from_fo3d(fo3d_path) @@ -1192,27 +1192,26 @@ def _handle_fo3d_file(self, fo3d_path, fo3d_output_path, export_mode): if seen: continue - if export_mode is True: + if self.export_mode is True: etau.copy_file(absolute_asset_path, asset_output_path) - elif export_mode == "move": + elif self.export_mode == "move": etau.move_file(absolute_asset_path, asset_output_path) - elif export_mode == "symlink": + elif self.export_mode == "symlink": etau.symlink_file(absolute_asset_path, asset_output_path) is_scene_modified = scene.update_asset_paths(input_to_output_paths) if is_scene_modified: - # note: we can't have different behavior for "symlink" because - # scene is modified, so we just copy the file regardless scene.write(fo3d_output_path) + if self.export_mode == "move": + etau.delete_file(fo3d_path) else: - if export_mode == "symlink": - etau.symlink_file(fo3d_path, fo3d_output_path) - else: + if self.export_mode is True: etau.copy_file(fo3d_path, fo3d_output_path) - - if export_mode == "move": - etau.delete_file(fo3d_path) + elif self.export_mode == "move": + etau.move_file(fo3d_path, fo3d_output_path) + elif self.export_mode == "symlink": + etau.symlink_file(fo3d_path, fo3d_output_path) def __enter__(self): self.setup() @@ -1302,21 +1301,16 @@ def export(self, media_or_path, outpath=None): uuid = self._get_uuid(outpath) if not seen: - is_fo3d_file = media_path.endswith(".fo3d") - - if self.export_mode is True and not is_fo3d_file: + if self.export_mode == "manifest": + self._manifest[uuid] = media_path + elif media_path.endswith(".fo3d"): + self._handle_fo3d_file(media_path, outpath) + elif self.export_mode is True: etau.copy_file(media_path, outpath) - elif self.export_mode == "move" and not is_fo3d_file: + elif self.export_mode == "move": etau.move_file(media_path, outpath) - elif self.export_mode == "symlink" and not is_fo3d_file: + elif self.export_mode == "symlink": etau.symlink_file(media_path, outpath) - elif self.export_mode == "manifest": - self._manifest[uuid] = media_path - - if is_fo3d_file: - self._handle_fo3d_file( - media_path, outpath, self.export_mode - ) else: media = media_or_path diff --git a/fiftyone/utils/utils3d.py b/fiftyone/utils/utils3d.py index a9ed6b894b..5d6c4d4089 100644 --- a/fiftyone/utils/utils3d.py +++ b/fiftyone/utils/utils3d.py @@ -468,12 +468,10 @@ def _get_scene_asset_paths_single(task, abs_paths=False, skip_failures=True): asset_paths = scene.get_asset_paths() if abs_paths: - # Convert any relative-to-scene paths to absolute scene_dir = os.path.dirname(original_scene_path) for i, asset_path in enumerate(asset_paths): if not fos.isabs(asset_path): - asset_path = fos.join(scene_dir, asset_path) - asset_paths[i] = fos.resolve(asset_path) + asset_paths[i] = fos.resolve(fos.join(scene_dir, asset_path)) return asset_paths From 164069619c8bd2f28f52cb323fa7c1611b46f8c0 Mon Sep 17 00:00:00 2001 From: brimoor Date: Mon, 3 Jun 2024 11:20:29 -0400 Subject: [PATCH 12/26] consistent structure --- fiftyone/core/metadata.py | 72 +++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/fiftyone/core/metadata.py b/fiftyone/core/metadata.py index e3dbcdb714..7657836d4f 100644 --- a/fiftyone/core/metadata.py +++ b/fiftyone/core/metadata.py @@ -71,6 +71,7 @@ def _build_for_url(cls, url, mime_type=None): mime_type = etau.guess_mime_type(url) with requests.get(url, stream=True) as r: + r.raise_for_status() size_bytes = int(r.headers["Content-Length"]) return cls(size_bytes=size_bytes, mime_type=mime_type) @@ -135,6 +136,7 @@ def _build_for_url(cls, url, mime_type=None): mime_type = etau.guess_mime_type(url) with requests.get(url, stream=True) as r: + r.raise_for_status() size_bytes = int(r.headers["Content-Length"]) width, height, num_channels = get_image_info(fou.ResponseStream(r)) @@ -225,7 +227,7 @@ class SceneMetadata(Metadata): asset_counts = fof.DictField() @classmethod - def build_for(cls, scene_path, mime_type=None): + def build_for(cls, scene_path, mime_type=None, _cache=None): """Builds a :class:`SceneMetadata` object for the given 3D scene. Args: @@ -236,52 +238,62 @@ def build_for(cls, scene_path, mime_type=None): Returns: a :class:`SceneMetadata` """ - return cls._build_for(scene_path, mime_type=mime_type) + if scene_path.startswith("http"): + return cls._build_for_url( + scene_path, mime_type=mime_type, cache=_cache + ) + + return cls._build_for_local( + scene_path, mime_type=mime_type, cache=_cache + ) @classmethod - def _build_for(cls, scene_path, mime_type=None, cache=None): + def _build_for_local(cls, scene_path, mime_type=None, cache=None): if mime_type is None: mime_type = "application/octet-stream" - # Unclear how asset paths should be handled; the rest of the library is - # not equipped to handle URL asset paths - if scene_path.startswith("http"): - raise ValueError("Scene URLs are not currently supported") - - total_size = os.path.getsize(scene_path) - + scene_size = os.path.getsize(scene_path) scene = fo3d.Scene.from_fo3d(scene_path) - asset_paths = scene.get_asset_paths() - - asset_counts = defaultdict(int) - scene_dir = os.path.dirname(scene_path) - for i, asset_path in enumerate(asset_paths): - if not fos.isabs(asset_path): - asset_path = fos.resolve(fos.join(scene_dir, asset_path)) - asset_paths[i] = asset_path - - file_type = os.path.splitext(asset_path)[1][1:] - asset_counts[file_type] += 1 - asset_counts = dict(asset_counts) - total_size += _compute_asset_sizes(asset_paths, cache=cache) + asset_counts, asset_size = _parse_assets( + scene, scene_path, cache=cache + ) + size_bytes = scene_size + asset_size return cls( - size_bytes=total_size, + size_bytes=size_bytes, mime_type=mime_type, asset_counts=asset_counts, ) + @classmethod + def _build_for_url(cls, scene_path, mime_type=None, cache=None): + # Unclear how asset paths should be handled; the rest of the library is + # not equipped to handle URL asset paths + raise ValueError("Scene URLs are not currently supported") + + +def _parse_assets(scene, scene_path, cache=None): + asset_paths = scene.get_asset_paths() + + asset_counts = defaultdict(int) + scene_dir = os.path.dirname(scene_path) + for i, asset_path in enumerate(asset_paths): + if not fos.isabs(asset_path): + asset_path = fos.resolve(fos.join(scene_dir, asset_path)) + asset_paths[i] = asset_path + + file_type = os.path.splitext(asset_path)[1][1:] + asset_counts[file_type] += 1 -def _compute_asset_sizes(asset_paths, cache=None): - total_size = 0 + asset_size = 0 tasks = [] for asset_path in asset_paths: if cache is not None: metadata = cache.get(asset_path, None) if metadata is not None: - total_size += metadata.size_bytes + asset_size += metadata.size_bytes continue tasks.append((None, asset_path, fom.MIXED, cache)) @@ -297,13 +309,13 @@ def _compute_asset_sizes(asset_paths, cache=None): for task, result in zip(tasks, results): metadata = result[1] - total_size += metadata.size_bytes + asset_size += metadata.size_bytes if cache is not None: scene_path = task[1] cache[scene_path] = metadata - return total_size + return dict(asset_counts), asset_size def compute_sample_metadata(sample, overwrite=False, skip_failures=False): @@ -561,7 +573,7 @@ def _get_metadata(filepath, media_type, cache=None): elif media_type == fom.VIDEO: metadata = VideoMetadata.build_for(filepath) elif media_type == fom.THREE_D: - metadata = SceneMetadata._build_for(filepath, cache=cache) + metadata = SceneMetadata.build_for(filepath, _cache=cache) else: metadata = Metadata.build_for(filepath) From 6e663c33af88ae4851c7b5db71d7272a50564f69 Mon Sep 17 00:00:00 2001 From: brimoor Date: Tue, 4 Jun 2024 08:29:37 -0400 Subject: [PATCH 13/26] cleanup --- fiftyone/utils/data/exporters.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/fiftyone/utils/data/exporters.py b/fiftyone/utils/data/exporters.py index 3bf0b8aa77..3a423fcc0a 100644 --- a/fiftyone/utils/data/exporters.py +++ b/fiftyone/utils/data/exporters.py @@ -238,13 +238,13 @@ def export_samples( sample_collection = samples - if isinstance(dataset_exporter, BatchDatasetExporter): - _write_batch_dataset(dataset_exporter, samples, progress=progress) - return - if isinstance( dataset_exporter, - (GenericSampleDatasetExporter, GroupDatasetExporter), + ( + BatchDatasetExporter, + GenericSampleDatasetExporter, + GroupDatasetExporter, + ), ): sample_parser = None elif isinstance(dataset_exporter, UnlabeledImageDatasetExporter): @@ -406,7 +406,9 @@ def write_dataset( if sample_collection is None and isinstance(samples, foc.SampleCollection): sample_collection = samples - if isinstance(dataset_exporter, GenericSampleDatasetExporter): + if isinstance(dataset_exporter, BatchDatasetExporter): + _write_batch_dataset(dataset_exporter, samples, progress=progress) + elif isinstance(dataset_exporter, GenericSampleDatasetExporter): _write_generic_sample_dataset( dataset_exporter, samples, From 4d74e08560099fe769ef11cd33703e61cbcb065c Mon Sep 17 00:00:00 2001 From: brimoor Date: Wed, 5 Jun 2024 10:40:13 -0400 Subject: [PATCH 14/26] abspath vs realpath --- fiftyone/core/metadata.py | 2 +- fiftyone/core/storage.py | 11 ++++------- fiftyone/core/threed/scene_3d.py | 4 ++-- fiftyone/utils/data/exporters.py | 5 +++-- fiftyone/utils/utils3d.py | 7 +++---- tests/unittests/metadata_tests.py | 17 +++++++---------- tests/unittests/utils3d_tests.py | 10 +++++----- 7 files changed, 25 insertions(+), 31 deletions(-) diff --git a/fiftyone/core/metadata.py b/fiftyone/core/metadata.py index 7657836d4f..f71f735001 100644 --- a/fiftyone/core/metadata.py +++ b/fiftyone/core/metadata.py @@ -280,7 +280,7 @@ def _parse_assets(scene, scene_path, cache=None): scene_dir = os.path.dirname(scene_path) for i, asset_path in enumerate(asset_paths): if not fos.isabs(asset_path): - asset_path = fos.resolve(fos.join(scene_dir, asset_path)) + asset_path = fos.abspath(fos.join(scene_dir, asset_path)) asset_paths[i] = asset_path file_type = os.path.splitext(asset_path)[1][1:] diff --git a/fiftyone/core/storage.py b/fiftyone/core/storage.py index 53d8a9f1ce..236c32f1f7 100644 --- a/fiftyone/core/storage.py +++ b/fiftyone/core/storage.py @@ -281,8 +281,8 @@ def join(a, *p): return os.path.join(a, *p) -def resolve(path): - """Resolves the given path to absolute, resolving symlinks and relative +def realpath(path): + """Converts the given path to absolute, resolving symlinks and relative path indicators such as ``.`` and ``..``. Args: @@ -297,8 +297,6 @@ def resolve(path): def isabs(path): """Determines whether the given path is absolute. - Remote paths are always considered absolute. - Args: path: the filepath @@ -309,9 +307,8 @@ def isabs(path): def abspath(path): - """Converts the given path to an absolute path. - - Remote paths are returned unchanged. + """Converts the given path to an absolute path, resolving relative path + indicators such as ``.`` and ``..``. Args: path: the filepath diff --git a/fiftyone/core/threed/scene_3d.py b/fiftyone/core/threed/scene_3d.py index 220efb16a4..8f5ddf6fc7 100644 --- a/fiftyone/core/threed/scene_3d.py +++ b/fiftyone/core/threed/scene_3d.py @@ -342,9 +342,9 @@ def _resolve_asset_path(self, root: str, path: str): return None if not fos.isabs(path): - path = fos.join(root, path) + path = fos.abspath(fos.join(root, path)) - return fos.resolve(path) + return path def _to_dict_extra(self): return { diff --git a/fiftyone/utils/data/exporters.py b/fiftyone/utils/data/exporters.py index 3a423fcc0a..a532a3036b 100644 --- a/fiftyone/utils/data/exporters.py +++ b/fiftyone/utils/data/exporters.py @@ -1176,8 +1176,8 @@ def _handle_fo3d_file(self, fo3d_path, fo3d_output_path): input_to_output_paths = {} for asset_path in asset_paths: if not os.path.isabs(asset_path): - absolute_asset_path = os.path.join( - os.path.dirname(fo3d_path), asset_path + absolute_asset_path = fos.abspath( + os.path.join(os.path.dirname(fo3d_path), asset_path) ) else: absolute_asset_path = asset_path @@ -1187,6 +1187,7 @@ def _handle_fo3d_file(self, fo3d_path, fo3d_output_path): asset_output_path = self._filename_maker.get_output_path( absolute_asset_path ) + # By convention, we always write *relative* asset paths input_to_output_paths[asset_path] = os.path.relpath( asset_output_path, os.path.dirname(fo3d_output_path) ) diff --git a/fiftyone/utils/utils3d.py b/fiftyone/utils/utils3d.py index 5d6c4d4089..1aebb13bef 100644 --- a/fiftyone/utils/utils3d.py +++ b/fiftyone/utils/utils3d.py @@ -452,7 +452,6 @@ def _get_scene_paths(scene_paths): def _get_scene_asset_paths_single(task, abs_paths=False, skip_failures=True): scene_path, original_scene_path = task - # Read scene file which is JSON try: scene = Scene.from_fo3d(scene_path) except Exception as e: @@ -471,7 +470,7 @@ def _get_scene_asset_paths_single(task, abs_paths=False, skip_failures=True): scene_dir = os.path.dirname(original_scene_path) for i, asset_path in enumerate(asset_paths): if not fos.isabs(asset_path): - asset_paths[i] = fos.resolve(fos.join(scene_dir, asset_path)) + asset_paths[i] = fos.abspath(fos.join(scene_dir, asset_path)) return asset_paths @@ -833,9 +832,9 @@ def _visit_node_dfs(node): return None if not fos.isabs(pcd_path): - pcd_path = fos.join(os.path.dirname(scene_path), pcd_path) + pcd_path = fos.abspath(fos.join(os.path.dirname(scene_path), pcd_path)) - return fos.resolve(pcd_path) + return pcd_path def _parse_point_cloud( diff --git a/tests/unittests/metadata_tests.py b/tests/unittests/metadata_tests.py index a47ca8b557..091850815a 100644 --- a/tests/unittests/metadata_tests.py +++ b/tests/unittests/metadata_tests.py @@ -30,11 +30,9 @@ def test_build_for(self): scene.add(fo3d.ObjMesh("blah-obj", "obj.obj", "mtl.mtl")) scene.add(fo3d.StlMesh("blah-stl", "stl.stl")) - # Add same file again - should not add to size_bytes though, - # even though this is abs and the other was relative - scene.add( - fo3d.ObjMesh("blah-obj2", os.path.join(temp_dir, "obj.obj")) - ) + # Add same file again. This should not be counted in `size_bytes` + # or `asset_counts` + scene.add(fo3d.ObjMesh("blah-obj2", "obj.obj")) scene.write(scene_path) @@ -42,12 +40,11 @@ def test_build_for(self): self.assertEqual(metadata.mime_type, "application/octet-stream") - # Read the scene back again so we'll compare more accurately - expected_size = len( - json.dumps(fo3d.Scene.from_fo3d(scene_path).as_dict()) - ) + sum(t[1] for t in files) + expected_size = os.path.getsize(scene_path) + expected_size += sum(t[1] for t in files) + self.assertEqual(metadata.size_bytes, expected_size) self.assertDictEqual( metadata.asset_counts, - {"obj": 2, "jpeg": 1, "stl": 1, "mtl": 1}, + {"obj": 1, "jpeg": 1, "stl": 1, "mtl": 1}, ) diff --git a/tests/unittests/utils3d_tests.py b/tests/unittests/utils3d_tests.py index e27b49ced0..a949ade397 100644 --- a/tests/unittests/utils3d_tests.py +++ b/tests/unittests/utils3d_tests.py @@ -375,16 +375,16 @@ def test_get_scene_asset_paths(self): self.assertSetEqual( set(asset_paths[scene_paths[0]]), { - os.path.realpath(f"{temp_dir}/back/ground.jpeg"), - os.path.realpath(f"{temp_dir}/relative.obj"), - os.path.realpath(f"{temp_dir}/absolute.pcd"), + f"{temp_dir}/back/ground.jpeg", + f"{temp_dir}/relative.obj", + f"{temp_dir}/absolute.pcd", }, ) self.assertSetEqual( set(asset_paths[scene_paths[1]]), { - os.path.realpath(f"{temp_dir}/back/ground.jpeg"), - os.path.realpath(f"{temp_dir}/relative2.stl"), + f"{temp_dir}/back/ground.jpeg", + f"{temp_dir}/relative2.stl", }, ) From 1dd6b80402e4c7521be1052435b0695856d84668 Mon Sep 17 00:00:00 2001 From: brimoor Date: Wed, 5 Jun 2024 10:45:57 -0400 Subject: [PATCH 15/26] consistency --- fiftyone/utils/data/exporters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fiftyone/utils/data/exporters.py b/fiftyone/utils/data/exporters.py index a532a3036b..e2a0780380 100644 --- a/fiftyone/utils/data/exporters.py +++ b/fiftyone/utils/data/exporters.py @@ -1176,7 +1176,7 @@ def _handle_fo3d_file(self, fo3d_path, fo3d_output_path): input_to_output_paths = {} for asset_path in asset_paths: if not os.path.isabs(asset_path): - absolute_asset_path = fos.abspath( + absolute_asset_path = os.path.abspath( os.path.join(os.path.dirname(fo3d_path), asset_path) ) else: From 94c52ba648e4cf030cde9966f2627afc71f85dcf Mon Sep 17 00:00:00 2001 From: brimoor Date: Wed, 5 Jun 2024 22:42:23 -0400 Subject: [PATCH 16/26] abspath --- tests/unittests/threed/scene_3d_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unittests/threed/scene_3d_tests.py b/tests/unittests/threed/scene_3d_tests.py index 0af72e442d..6344d750f8 100644 --- a/tests/unittests/threed/scene_3d_tests.py +++ b/tests/unittests/threed/scene_3d_tests.py @@ -116,12 +116,12 @@ def test_write_resolve_relative(self): resolve_relative_paths=True, ) scene2 = threed.Scene.from_fo3d(path) - real_background = os.path.realpath( + real_background = os.path.abspath( os.path.join(temp_dir, "../background.jpeg") ) self.assertEqual(scene2.background.image, real_background) real_cubes = [ - os.path.realpath(os.path.join(temp_dir, ci)) + os.path.abspath(os.path.join(temp_dir, ci)) for ci in self.scene.background.cube ] self.assertListEqual(scene2.background.cube, real_cubes) @@ -129,7 +129,7 @@ def test_write_resolve_relative(self): if node.name == "gltf2": self.assertEqual( node.gltf_path, - os.path.realpath( + os.path.abspath( os.path.join(temp_dir, "relative.gltf") ), ) From 2350e7420791ae9b8120b7dec1c97f877cdc94bb Mon Sep 17 00:00:00 2001 From: brimoor Date: Thu, 6 Jun 2024 09:18:02 -0400 Subject: [PATCH 17/26] updating Teams docs --- docs/source/teams/cloud_media.rst | 55 +++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/docs/source/teams/cloud_media.rst b/docs/source/teams/cloud_media.rst index f28522fc6b..c9cac450d4 100644 --- a/docs/source/teams/cloud_media.rst +++ b/docs/source/teams/cloud_media.rst @@ -391,6 +391,7 @@ _____________ import fiftyone as fo fo.Dataset.download_media? + fo.Dataset.download_scenes? fo.Dataset.download_context? fo.Dataset.get_local_paths? fo.Dataset.cache_stats? @@ -402,6 +403,7 @@ _____________ self, media_fields=None, group_slices=None, + include_assets=True, update=False, skip_failures=True, progress=None, @@ -420,6 +422,7 @@ _____________ group_slices (None): an optional subset of group slices for which to download media. Only applicable when the collection contains groups + include_assets (True): whether to include 3D scene assets update (False): whether to re-download media whose checksums no longer match skip_failures (True): whether to gracefully continue without @@ -430,6 +433,32 @@ _____________ callback function to invoke instead """ +.. code-block:: python + + fo.Dataset.download_scenes( + self, + update=False, + skip_failures=True, + progress=None, + ): + """Downloads all ``.fo3d`` files for the samples in the collection. + + This method is only useful for collections that contain remote media. + + Any existing files are not re-downloaded, unless ``update == True`` and + their checksums no longer match. + + Args: + update (False): whether to re-download files whose checksums no + longer match + skip_failures (True): whether to gracefully continue without + raising an error if a remote file cannot be downloaded + progress (None): whether to render a progress bar tracking the + progress of any downloads (True/False), use the default value + ``fiftyone.config.show_progress_bars`` (None), or a progress + callback function to invoke instead + """ + .. code-block:: python fo.Dataset.download_context( @@ -438,6 +467,7 @@ _____________ target_size_bytes=None, media_fields=None, group_slices=None, + include_assets=True, update=False, skip_failures=True, clear=False, @@ -446,6 +476,12 @@ _____________ """Returns a context that can be used to pre-download media in batches when iterating over samples in this collection. + This method is only useful for collections that contain remote media. + + By default, all media will be downloaded when the context is entered, + but you can configure a batching strategy via the `batch_size` or + `target_size_bytes` parameters. + If no ``batch_size`` or ``target_size_bytes`` is provided, media are downloaded in batches of ``fo.media_cache_config.download_size_bytes``. @@ -459,6 +495,7 @@ _____________ :meth:`app_config` are used group_slices (None): an optional subset of group slices to download media for. Only applicable when the collection contains groups + include_assets (True): whether to include 3D scene assets update (False): whether to re-download media whose checksums no longer match skip_failures (True): whether to gracefully continue without @@ -480,6 +517,7 @@ _____________ fo.Dataset.get_local_paths( self, media_field="filepath", + include_assets=True, download=True, skip_failures=True, progress=None, @@ -490,6 +528,7 @@ _____________ Args: media_field ("filepath"): the field containing the media paths + include_assets (True): whether to include 3D scene assets download (True): whether to download any non-cached media files skip_failures (True): whether to gracefully continue without raising an error if a remote file cannot be downloaded @@ -504,7 +543,12 @@ _____________ .. code-block:: python - fo.Dataset.cache_stats(self, media_fields=None, group_slices=None): + fo.Dataset.cache_stats( + self, + media_fields=None, + group_slices=None, + include_assets=True, + ): """Returns a dictionary of stats about the cached media files in this collection. @@ -516,6 +560,7 @@ _____________ :meth:`app_config` are included group_slices (None): an optional subset of group slices to include. Only applicable when the collection contains groups + include_assets (True): whether to include 3D scene assets Returns: a stats dict @@ -523,7 +568,12 @@ _____________ .. code-block:: python - fo.Dataset.clear_media(self, media_fields=None, group_slices=None): + fo.Dataset.clear_media( + self, + media_fields=None, + group_slices=None, + include_assets=True, + ): """Deletes any local copies of media files in this collection from the media cache. @@ -536,6 +586,7 @@ _____________ group_slices (None): an optional subset of group slices for which to clear media. Only applicable when the collection contains groups + include_assets (True): whether to include 3D scene assets """ `fiftyone.core.storage` From 74cc85d5bfa6cadaa8673bc0e8511a05e12025ec Mon Sep 17 00:00:00 2001 From: brimoor Date: Fri, 31 May 2024 10:28:45 -0400 Subject: [PATCH 18/26] fixing anomaly detection tutorial title level --- docs/source/tutorials/anomaly_detection.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/tutorials/anomaly_detection.ipynb b/docs/source/tutorials/anomaly_detection.ipynb index 4bbae3b077..5b30700630 100644 --- a/docs/source/tutorials/anomaly_detection.ipynb +++ b/docs/source/tutorials/anomaly_detection.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Anomaly Detection with FiftyOne and Anomalib" + "# Anomaly Detection with FiftyOne and Anomalib" ] }, { From 1d7672409cc7efcdb83d47929663a6d6c541e53f Mon Sep 17 00:00:00 2001 From: Benjamin Kane Date: Thu, 6 Jun 2024 10:01:09 -0400 Subject: [PATCH 19/26] use existing merge branch (#4453) --- .github/workflows/push-release.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/push-release.yml b/.github/workflows/push-release.yml index fb79401fef..50882445b6 100644 --- a/.github/workflows/push-release.yml +++ b/.github/workflows/push-release.yml @@ -21,6 +21,11 @@ jobs: - run: | git config user.name 'voxel51-bot' git config user.email 'bot@voxel51.com' + git checkout merge/${{ inputs.ref_name || github.ref_name }} \ + || git checkout -b merge/${{ inputs.ref_name || github.ref_name }} + git push -u origin merge/${{ inputs.ref_name || github.ref_name }} + git checkout develop + git pull origin merge/${{ inputs.ref_name || github.ref_name }} --no-rebase git pull origin ${{ inputs.ref_name || github.ref_name }} --no-rebase - uses: peter-evans/create-pull-request@v6 with: From 12613497f13b8670399296e9d317840f5d5ff28a Mon Sep 17 00:00:00 2001 From: brimoor Date: Wed, 5 Jun 2024 11:27:18 -0400 Subject: [PATCH 20/26] adding 0.24.1 release notes --- docs/source/release-notes.rst | 58 +++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/docs/source/release-notes.rst b/docs/source/release-notes.rst index 4000e83b77..696a144112 100644 --- a/docs/source/release-notes.rst +++ b/docs/source/release-notes.rst @@ -3,6 +3,55 @@ FiftyOne Release Notes .. default-role:: code +FiftyOne Teams 1.7.1 +-------------------- +*Released June X, 2024* + +Includes all updates from :ref:`FiftyOne 0.24.1 `, plus: + +- Improved stability of loading/navigating to saved views in the App +- Fixed a notification error when deleting users from the Team Settings page +- Improved stability of the Team Groups page after deleting users + +.. _release-notes-v0.24.1: + +FiftyOne 0.24.1 +--------------- +*Released June X, 2024* + +What's New + +- Added :ref:`Ultralytics YOLOv8 models ` trained on + Open Images v7 to the model zoo! + `#4398 `_ + +App + +- Fixed a regression from FiftyOne 0.24.0 that would prevent operator outputs + and error states from displaying in the App + `#4445 `_ + +Core + +- Optimized metadata computation for 3D scenes + `#4442 `_ +- Fixed a bug that could cause 3D assets to be omitted when exporting 3D scenes + `#4442 `_ + +Utils + +- The + :func:`make_patches_dataset() `, + :func:`make_frames_dataset() `, + and :func:`make_clips_dataset() ` + utilities can now be directly called + `#4416 `_ + +Annotation + +- Added support loading annotations for large CVAT tasks with many jobs + `#4392 `_ + FiftyOne Teams 1.7.0 -------------------- *Released May 29, 2024* @@ -38,9 +87,6 @@ What's New `#4254 `_ - FiftyOne now lazily connects to the database only when needed `#4236 `_ -- Added :ref:`Ultralytics YOLOv8 models ` trained on - Open Images v7 to the model zoo! - `#4398 `_ - Added :ref:`Grounding DINO ` as an option for zero shot object detection `#4292 `_ @@ -93,12 +139,6 @@ Utils tracking utility `#4372 `_, `#4296 `_ -- The - :func:`make_patches_dataset() `, - :func:`make_frames_dataset() `, - and :func:`make_clips_dataset() ` - utilities can now be directly called - `#4416 `_ Plugins From f692120e8c8f60ac1ba7e5bdf8e0612f1ebb371a Mon Sep 17 00:00:00 2001 From: brimoor Date: Thu, 6 Jun 2024 10:30:09 -0400 Subject: [PATCH 21/26] date --- docs/source/release-notes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/release-notes.rst b/docs/source/release-notes.rst index 696a144112..c1c9ab8491 100644 --- a/docs/source/release-notes.rst +++ b/docs/source/release-notes.rst @@ -5,7 +5,7 @@ FiftyOne Release Notes FiftyOne Teams 1.7.1 -------------------- -*Released June X, 2024* +*Released June 7, 2024* Includes all updates from :ref:`FiftyOne 0.24.1 `, plus: @@ -17,7 +17,7 @@ Includes all updates from :ref:`FiftyOne 0.24.1 `, plus: FiftyOne 0.24.1 --------------- -*Released June X, 2024* +*Released June 7, 2024* What's New From 44c44e5d140bed2026a0341486abe06399c219b1 Mon Sep 17 00:00:00 2001 From: brimoor Date: Thu, 6 Jun 2024 11:38:31 -0400 Subject: [PATCH 22/26] fixing docs bugs --- docs/source/plugins/index.rst | 8 ++++---- docs/source/user_guide/config.rst | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/source/plugins/index.rst b/docs/source/plugins/index.rst index 401006eb39..c1aee357e1 100644 --- a/docs/source/plugins/index.rst +++ b/docs/source/plugins/index.rst @@ -39,15 +39,15 @@ these plugins available in the +-------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+ | `@voxel51/annotation `_ | ✏️ Utilities for integrating FiftyOne with annotation tools | +-------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+ - | `@voxel51/brain `_ | 🧠 Utilities for working with the FiftyOne Brain | + | `@voxel51/brain `_ | 🧠 Utilities for working with the FiftyOne Brain | +-------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+ - | `@voxel51/evaluation `_ | ✅ Utilities for evaluating models with FiftyOne | + | `@voxel51/evaluation `_ | ✅ Utilities for evaluating models with FiftyOne | +-------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+ | `@voxel51/io `_ | 📁 A collection of import/export utilities | +-------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+ - | `@voxel51/indexes `_ | 📈 Utilities for working with FiftyOne database indexes | + | `@voxel51/indexes `_ | 📈 Utilities for working with FiftyOne database indexes | +-------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+ - | `@voxel51/runs `_ | 📈 Utilities for working with custom runs | + | `@voxel51/runs `_ | 📈 Utilities for working with custom runs | +-------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+ | `@voxel51/utils `_ | ⚒️ Call your favorite SDK utilities from the App | +-------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+ diff --git a/docs/source/user_guide/config.rst b/docs/source/user_guide/config.rst index fcbddef5b3..1ae939b08e 100644 --- a/docs/source/user_guide/config.rst +++ b/docs/source/user_guide/config.rst @@ -705,7 +705,7 @@ The FiftyOne App can be configured in the ways described below: +---------------------------+----------------------------------------+-----------------------------+-------------------------------------------------------------------------------------------+ | `sidebar_mode` | `FIFTYONE_APP_SIDEBAR_MODE` | `fast` | The default loading behavior of the App's sidebar. Supported values are | | | | | `{"fast", "all", "best", "disabled"}`. See :ref:`this section ` | -| | | | more details. | +| | | | more details. | +---------------------------+----------------------------------------+-----------------------------+-------------------------------------------------------------------------------------------+ | `theme` | `FIFTYONE_APP_THEME` | `"browser"` | The default theme to use in the App. Supported values are `{"browser", "dark", "light"}`. | | | | | If `"browser"`, your current theme will be persisted in your browser's storage. | From 547a1ffb6c503326a4d9c80c86066a67b5a5d768 Mon Sep 17 00:00:00 2001 From: imanjra Date: Mon, 10 Jun 2024 12:37:14 -0400 Subject: [PATCH 23/26] fix workspace persistence issue (#4471) --- .../core/src/components/MainSpace/MainSpace.tsx | 7 ++++++- .../src/OperatorInvocationRequestExecutor.tsx | 10 ++++++++-- app/packages/operators/src/constants.ts | 6 ++++++ app/packages/operators/src/operators.ts | 11 +---------- app/packages/spaces/src/hooks.ts | 15 +++++++++------ app/packages/spaces/src/state.ts | 4 +++- 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/app/packages/core/src/components/MainSpace/MainSpace.tsx b/app/packages/core/src/components/MainSpace/MainSpace.tsx index 7d672d1b6c..efc752a755 100644 --- a/app/packages/core/src/components/MainSpace/MainSpace.tsx +++ b/app/packages/core/src/components/MainSpace/MainSpace.tsx @@ -8,12 +8,17 @@ const { FIFTYONE_SPACE_ID } = constants; function MainSpace() { const [sessionSpaces, setSessionSpaces, sessionPanelsState] = useSessionSpaces(); - const { spaces, updateSpaces } = useSpaces(FIFTYONE_SPACE_ID, sessionSpaces); + const { spaces, updateSpaces, clearSpaces } = useSpaces( + FIFTYONE_SPACE_ID, + sessionSpaces + ); const [panelsState, setPanelsState] = usePanelsState(); const oldSpaces = useRef(spaces); const oldPanelsState = useRef(panelsState); const isMounted = useRef(false); + useEffect(() => clearSpaces, [clearSpaces]); + useEffect(() => { if (!spaces.equals(sessionSpaces)) { updateSpaces(sessionSpaces); diff --git a/app/packages/operators/src/OperatorInvocationRequestExecutor.tsx b/app/packages/operators/src/OperatorInvocationRequestExecutor.tsx index 1faee7b57b..f7b671b77c 100644 --- a/app/packages/operators/src/OperatorInvocationRequestExecutor.tsx +++ b/app/packages/operators/src/OperatorInvocationRequestExecutor.tsx @@ -1,15 +1,21 @@ -import { useEffect } from "react"; +import { useEffect, useMemo } from "react"; import { useInvocationRequestExecutor, useInvocationRequestQueue, } from "./state"; +import { QueueItemStatus } from "./constants"; export default function OperatorInvocationRequestExecutor() { const { requests, onSuccess, onError } = useInvocationRequestQueue(); + const pendingRequests = useMemo(() => { + return requests.filter( + (queueItem) => queueItem.status === QueueItemStatus.Pending + ); + }, [requests]); return ( <> - {requests.map((queueItem) => ( + {pendingRequests.map((queueItem) => ( { - if (!state) { - const baseState = new SpaceNode("root").toJSON(); - setState(defaultState || baseState); + if (!state && defaultState) { + setState(defaultState); } - }, []); + }, [state, setState, defaultState]); const spaces = new SpaceTree(state, (spaces: SpaceNodeJSON) => { setState(spaces); }); + const clearSpaces = useCallback(() => { + setState(undefined); + }, [setState]); + return { spaces, updateSpaces: ( @@ -57,6 +59,7 @@ export function useSpaces(id: string, defaultState?: SpaceNodeJSON) { setState(serializedTreeOrUpdater); } }, + clearSpaces, }; } diff --git a/app/packages/spaces/src/state.ts b/app/packages/spaces/src/state.ts index fe7a25435f..547a601a55 100644 --- a/app/packages/spaces/src/state.ts +++ b/app/packages/spaces/src/state.ts @@ -9,7 +9,9 @@ import { // a react hook for managing the state of all spaces in the app // it should use recoil to persist the tree -export const spacesAtom = atom<{ [spaceId: string]: SpaceNodeJSON }>({ +export const spacesAtom = atom<{ + [spaceId: string]: SpaceNodeJSON | undefined; +}>({ key: "spaces", default: {}, }); From 656a264b54053768de0d4268b2387ceb28338b3a Mon Sep 17 00:00:00 2001 From: Sashank Aryal <66688606+sashankaryal@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:37:30 -0500 Subject: [PATCH 24/26] Refetch saved views on dataset change (#4469) * add an effect to refetch saved views on dataset change * rm saved view attr usage for state, handle group slice --------- Co-authored-by: Benjamin Kane --- .../src/components/Sidebar/ViewSelection/index.tsx | 4 ++++ fiftyone/server/events/initialize.py | 4 ++-- fiftyone/server/mutation.py | 10 ---------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/app/packages/core/src/components/Sidebar/ViewSelection/index.tsx b/app/packages/core/src/components/Sidebar/ViewSelection/index.tsx index e06c031bdd..319ac0475e 100644 --- a/app/packages/core/src/components/Sidebar/ViewSelection/index.tsx +++ b/app/packages/core/src/components/Sidebar/ViewSelection/index.tsx @@ -80,6 +80,10 @@ export default function ViewSelection() { [viewOptions, viewSearch] ); + useEffect(() => { + refetch({ name: datasetName }); + }, [datasetName]); + useEffect(() => { if ( selected && diff --git a/fiftyone/server/events/initialize.py b/fiftyone/server/events/initialize.py index 735791489f..6ae42bc2f1 100644 --- a/fiftyone/server/events/initialize.py +++ b/fiftyone/server/events/initialize.py @@ -132,6 +132,7 @@ def handle_dataset_change( """ try: state.dataset = fod.load_dataset(initializer.dataset) + state.group_slice = state.dataset.group_slice state.selected = [] state.selected_labels = [] state.view = None @@ -139,6 +140,7 @@ def handle_dataset_change( except: state.dataset = None + state.group_slice = None state.selected = [] state.selected_labels = [] state.view = None @@ -151,7 +153,6 @@ def handle_dataset_change( initializer.view, slug=True ) state.view = state.dataset.load_saved_view(doc.name) - state.view_name = doc.name except: pass @@ -191,7 +192,6 @@ def handle_saved_view( if slug: doc = state.dataset._get_saved_view_doc(slug, slug=True) state.view = state.dataset.load_saved_view(doc.name) - state.view_name = doc.name state.selected = [] state.selected_labels = [] except: diff --git a/fiftyone/server/mutation.py b/fiftyone/server/mutation.py index 81f7f7261d..ebfa9ca8d8 100644 --- a/fiftyone/server/mutation.py +++ b/fiftyone/server/mutation.py @@ -93,7 +93,6 @@ async def set_dataset( state.selected = [] state.selected_labels = [] state.view = None - state.view_name = view_name if view_name is not None else None state.spaces = foo.default_workspace_factory() state.color_scheme = build_color_scheme( None, state.dataset, state.config @@ -243,14 +242,7 @@ async def set_view( result_view = _build_result_view(result_view, form) # Set view state - slug = ( - fou.to_slug(result_view.name) - if result_view.name - else saved_view_slug - ) state.view = result_view - state.view_name = result_view.name - state.saved_view_slug = slug await dispatch_event( subscription, @@ -300,7 +292,6 @@ async def create_saved_view( if use_state: dataset.reload() state.view = dataset.load_saved_view(view_name) - state.view_name = view_name await dispatch_event(subscription, fose.StateUpdate(state=state)) return next( @@ -348,7 +339,6 @@ async def delete_saved_view( and state.view.name == view_name ): state.view = dataset.view() - state.view_name = None await dispatch_event(subscription, fose.StateUpdate(state=state)) From 2e49b92cefeca162ae5d76961316bab9faa8b1b7 Mon Sep 17 00:00:00 2001 From: Brian Moore Date: Mon, 10 Jun 2024 13:05:07 -0400 Subject: [PATCH 25/26] fix copy_files() (#4472) --- fiftyone/core/storage.py | 74 ++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/fiftyone/core/storage.py b/fiftyone/core/storage.py index 236c32f1f7..e4a9467d4a 100644 --- a/fiftyone/core/storage.py +++ b/fiftyone/core/storage.py @@ -207,7 +207,7 @@ def open_files(paths, mode="r", skip_failures=False, progress=None): a list of open file-like objects """ tasks = [(p, mode, skip_failures) for p in paths] - return _run(_do_open_file, tasks, progress=progress) + return _run(_do_open_file, tasks, return_results=True, progress=progress) def read_file(path, binary=False): @@ -239,7 +239,7 @@ def read_files(paths, binary=False, skip_failures=False, progress=None): a list of file contents """ tasks = [(p, binary, skip_failures) for p in paths] - return _run(_do_read_file, tasks, progress=progress) + return _run(_do_read_file, tasks, return_results=True, progress=progress) def write_file(str_or_bytes, path): @@ -793,7 +793,7 @@ def move_files(inpaths, outpaths, skip_failures=False, progress=None): progress callback function to invoke instead """ tasks = [(i, o, skip_failures) for i, o in zip(inpaths, outpaths)] - _run(_do_move_file, tasks, progress=progress) + _run(_do_move_file, tasks, return_results=False, progress=progress) def move_dir( @@ -848,7 +848,7 @@ def delete_files(paths, skip_failures=False, progress=None): progress callback function to invoke instead """ tasks = [(p, skip_failures) for p in paths] - _run(_do_delete_file, tasks, progress=progress) + _run(_do_delete_file, tasks, return_results=False, progress=progress) def delete_dir(dirpath): @@ -861,67 +861,65 @@ def delete_dir(dirpath): etau.delete_dir(dirpath) -def run(fcn, tasks, num_workers=None, progress=None): +def run(fcn, tasks, return_results=True, num_workers=None, progress=None): """Applies the given function to each element of the given tasks. Args: fcn: a function that accepts a single argument tasks: an iterable of function arguments + return_results (True): whether to return the function results num_workers (None): a suggested number of threads to use progress (None): whether to render a progress bar (True/False), use the default value ``fiftyone.config.show_progress_bars`` (None), or a progress callback function to invoke instead Returns: - the list of function outputs - """ - num_workers = fou.recommend_thread_pool_workers(num_workers) - - try: - num_tasks = len(tasks) - except: - num_tasks = None - - kwargs = dict(total=num_tasks, iters_str="files", progress=progress) - - if num_workers <= 1: - with fou.ProgressBar(**kwargs) as pb: - results = [fcn(task) for task in pb(tasks)] - else: - with multiprocessing.dummy.Pool(processes=num_workers) as pool: - with fou.ProgressBar(**kwargs) as pb: - results = list(pb(pool.imap(fcn, tasks))) - - return results + the list of function outputs, or None if ``return_results == False`` + """ + return _run( + fcn, + tasks, + return_results=return_results, + num_workers=num_workers, + progress=progress, + ) def _copy_files(inpaths, outpaths, skip_failures, progress): tasks = [(i, o, skip_failures) for i, o in zip(inpaths, outpaths)] - _run(_do_copy_file, tasks, progress=progress) + _run(_do_copy_file, tasks, return_results=False, progress=progress) + +def _run(fcn, tasks, return_results=True, num_workers=None, progress=None): + try: + num_tasks = len(tasks) + except: + num_tasks = None -def _run(fcn, tasks, num_workers=None, progress=None): - num_tasks = len(tasks) if num_tasks == 0: - return [] + return [] if return_results else None num_workers = fou.recommend_thread_pool_workers(num_workers) - kwargs = dict(total=num_tasks, iters_str="files", progress=progress) - results = [] if num_workers <= 1: with fou.ProgressBar(**kwargs) as pb: - for task in pb(tasks): - result = fcn(task) - results.append(result) + if return_results: + results = [fcn(task) for task in pb(tasks)] + else: + for task in pb(tasks): + fcn(task) else: with multiprocessing.dummy.Pool(processes=num_workers) as pool: with fou.ProgressBar(**kwargs) as pb: - for result in pb(pool.imap_unordered(fcn, tasks)): - results.append(result) + if return_results: + results = list(pb(pool.imap(fcn, tasks))) + else: + for _ in pb(pool.imap_unordered(fcn, tasks)): + pass - return results + if return_results: + return results def _do_copy_file(arg): @@ -1003,6 +1001,8 @@ def _copy_file(inpath, outpath, cleanup=False): etau.ensure_basedir(outpath) if cleanup: shutil.move(inpath, outpath) + else: + shutil.copy(inpath, outpath) def _delete_file(filepath): From 58df9635b0737e73f4b03b1484e0e37946fe0127 Mon Sep 17 00:00:00 2001 From: brimoor Date: Mon, 10 Jun 2024 22:26:31 -0400 Subject: [PATCH 26/26] updating release notes --- docs/source/release-notes.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/source/release-notes.rst b/docs/source/release-notes.rst index c1c9ab8491..de69a59665 100644 --- a/docs/source/release-notes.rst +++ b/docs/source/release-notes.rst @@ -5,19 +5,20 @@ FiftyOne Release Notes FiftyOne Teams 1.7.1 -------------------- -*Released June 7, 2024* +*Released June 11, 2024* Includes all updates from :ref:`FiftyOne 0.24.1 `, plus: - Improved stability of loading/navigating to saved views in the App - Fixed a notification error when deleting users from the Team Settings page - Improved stability of the Team Groups page after deleting users +- Optimized export of cloud-backed 3D scenes .. _release-notes-v0.24.1: FiftyOne 0.24.1 --------------- -*Released June 7, 2024* +*Released June 11, 2024* What's New