diff --git a/.babelrc b/.babelrc deleted file mode 100644 index b5ac79bd..00000000 --- a/.babelrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "presets": [ - [ "react-app", { "absoluteRuntime": false } ] - ], - "plugins": ["@babel/plugin-proposal-optional-chaining"] -} diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index add1e2ae..00000000 --- a/.flowconfig +++ /dev/null @@ -1,2 +0,0 @@ -[options] -esproposal.optional_chaining=enable diff --git a/.gitignore b/.gitignore index 808fe5bc..b21621e4 100755 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ dist secret.* secret.story.* *.secret.* +.idea diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..f633ce67 --- /dev/null +++ b/.npmignore @@ -0,0 +1,4 @@ +.idea +.github +node_modules +src diff --git a/.prettierrc b/.prettierrc index cce9d3c0..732e2200 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,3 +1,3 @@ { - "semi": false + "semi": true } diff --git a/.storybook/addons.js b/.storybook/addons.js deleted file mode 100644 index 6aed412d..00000000 --- a/.storybook/addons.js +++ /dev/null @@ -1,2 +0,0 @@ -import '@storybook/addon-actions/register'; -import '@storybook/addon-links/register'; diff --git a/.storybook/config.js b/.storybook/config.js deleted file mode 100644 index 25199345..00000000 --- a/.storybook/config.js +++ /dev/null @@ -1,16 +0,0 @@ -// @flow - -import React from "react" -import Theme from "../src/Theme" -import { configure, addDecorator } from "@storybook/react" -import { action } from "@storybook/addon-actions" -import SettingsProvider from "../src/SettingsProvider" - -addDecorator(storyFn => {storyFn()}) -// addDecorator(storyFn => {storyFn()}) - -function loadStories() { - require("../src/stories") -} - -configure(loadStories, module) diff --git a/README.md b/README.md index cd58b6be..602467dd 100755 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ # React Image Annotate -[![npm version](https://badge.fury.io/js/react-image-annotate.svg)](https://badge.fury.io/js/react-image-annotate) +[![npm version](https://img.shields.io/npm/v/@asi/react-image-annotate.svg)](https://www.npmjs.com/package/@amnstak/react-image-annotate) -The best image/video annotation tool ever. [Check out the demo here](https://universaldatatool.github.io/react-image-annotate/). Or the [code sandbox here](https://codesandbox.io/s/react-image-annotate-example-38tsc?file=/src/App.js:0-403). + -## Sponsors +Implemented features in fork: -[![wao.ai sponsorship image](https://s3.amazonaws.com/asset.workaround.online/sponsorship-banner-1.png)](https://wao.ai) +- added typescript +- changed seamless immutability to immer +- updated npm and dependencies used by project +- updated react to v.19 ## Features @@ -20,29 +24,36 @@ The best image/video annotation tool ever. [Check out the demo here](https://uni ## Usage -`npm install react-image-annotate` +`npm i @amnstak/react-image-annotate` ```javascript import React from "react"; -import ReactImageAnnotate from "react-image-annotate"; +import Annotator from "@amnstak/react-image-annotate"; const App = () => ( - { + console.log(state); + }} + onNextImages={(state) => { + console.log(state); + }} + onExit={(output) => { + console.log({output}); + }} /> ); export default App; - ``` To get the proper fonts, make sure to import the Inter UI or Roboto font, the @@ -56,46 +67,8 @@ following line added to a css file should suffice. All of the following properties can be defined on the Annotator... -| Prop | Type (\* = required) | Description | Default | -| ------------------------ | ------------------------------------------------ | --------------------------------------------------------------------------------------- | ------------- | -| `taskDescription` | \*`string` | Markdown description for what to do in the image. | | -| `allowedArea` | `{ x: number, y: number, w: number, h: number }` | Area that is available for annotation. | Entire image. | -| `regionTagList` | `Array` | Allowed "tags" (mutually inclusive classifications) for regions. | | -| `regionClsList` | `Array` | Allowed "classes" (mutually exclusive classifications) for regions. | | -| `imageTagList` | `Array` | Allowed tags for entire image. | | -| `imageClsList` | `Array` | Allowed classes for entire image. | | -| `enabledTools` | `Array` | Tools allowed to be used. e.g. "select", "create-point", "create-box", "create-polygon" | Everything. | -| `showTags` | `boolean` | Show tags and allow tags on regions. | `true` | -| `selectedImage` | `string` | URL of initially selected image. | | -| `images` | `Array` | Array of images to load into annotator | | -| `showPointDistances` | `boolean` | Show distances between points. | `false` | -| `pointDistancePrecision` | `number` | Precision on displayed points (e.g. 3 => 0.123) | | -| `onExit` | `MainLayoutState => any` | Called when "Save" is called. | | -| `RegionEditLabel` | `Node` | React Node overriding the form to update the region (see [`RegionLabel`](https://github.com/waoai/react-image-annotate/blob/master/src/RegionLabel/index.js)) | | -| `allowComments` | `boolean` | Show a textarea to add comments on each annotation. | `false` | -| `hidePrev` | `boolean` | Hide `Previous Image` button from the header bar. | `false` | -| `hideNext` | `boolean` | Hide `Next Image` button from the header bar. | `false` | -| `hideClone` | `boolean` | Hide `Clone` button from the header bar. | `false` | -| `hideSettings` | `boolean` | Hide `Settings` button from the header bar. | `false` | -| `hideFullScreen` | `boolean` | Hide `FullScreen/Window` button from the header bar. | `false` | -| `hideSave` | `boolean` | Hide `Save` button from the header bar. | `false` | - -## Developers - -### Development - -This project uses [react-storybook](https://storybook.js.org/). To begin developing run the following commands in the cloned repo. - -1. `yarn install` -2. `yarn storybook` - -A browser tab will automatically open with the project components. - -See more details in the [contributing guidelines](https://github.com/waoai/react-image-annotate/wiki/Setup-for-Development). - -### Icons - -Consult these icon repositories: - -- [Material Icons](https://material.io/tools/icons/) -- [Font Awesome Icons](https://fontawesome.com/icons?d=gallery&m=free) +Refer `AnnotatorProps` + +`import { AnnotatorProps } from "@amnstak/react-image-annotate";` + +It has a complete details of the accepted props \ No newline at end of file diff --git a/public/index.html b/index.html similarity index 92% rename from public/index.html rename to index.html index 3c872092..fd447762 100644 --- a/public/index.html +++ b/index.html @@ -4,6 +4,7 @@ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..60de00c9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8229 @@ +{ + "name": "@amnstak/react-image-annotate", + "version": "0.0.23", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@amnstak/react-image-annotate", + "version": "0.0.23", + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "^0.2.0", + "@mui/icons-material": "^6.4.10", + "@mui/material": "^6.4.10", + "autoseg": "^0.0.12", + "classnames": "^2.5.1", + "color-alpha": "^2.0.0", + "immer": "^10.1.1", + "lodash": "^4.17.21", + "moment": "^2.30.0", + "react-full-screen": "^1.1.1", + "react-hotkeys": "^2.0.0", + "react-markdown": "^9.0.0", + "react-monaco-editor": "^0.58.0", + "react-remove-scroll": "^2.0.4", + "react-select": "^5.8.0", + "react-syntax-highlighter": "^15.5.0", + "react-use": "^17.5.0", + "react-use-measure": "^2.0.0", + "transformation-matrix-js": "^2.7.6", + "tss-react": "^4.9.6", + "use-event-callback": "^0.1.0" + }, + "devDependencies": { + "@rollup/plugin-replace": "^5.0.5", + "@types/lodash": "^4.17.0", + "@types/node": "^20.12.4", + "@types/react": "^18.2.66", + "@types/react-dom": "^18.2.22", + "@types/react-select": "^5.0.1", + "@types/react-syntax-highlighter": "^15.5.11", + "@types/rollup-plugin-peer-deps-external": "^2.2.5", + "@vitejs/plugin-react": "^4.2.1", + "cpy-cli": "^5.0.0", + "cross-env": "^7.0.3", + "gh-pages": "^2.0.1", + "prettier": "^2.5.1", + "react-github-btn": "^1.1.1", + "rollup-plugin-peer-deps-external": "^2.2.4", + "typescript": "^5.2.2", + "vite": "^5.2.7", + "vite-plugin-dts": "^3.8.1", + "vite-plugin-node-polyfills": "^0.21.0", + "vite-tsconfig-paths": "^4.3.2" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "license": "MIT" + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@microsoft/api-extractor": { + "version": "7.43.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", + "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/api-extractor-model": "7.28.13", + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "4.0.2", + "@rushstack/rig-package": "0.5.2", + "@rushstack/terminal": "0.10.0", + "@rushstack/ts-command-line": "4.19.1", + "lodash": "~4.17.15", + "minimatch": "~3.0.3", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.4.2" + }, + "bin": { + "api-extractor": "bin/api-extractor" + } + }, + "node_modules/@microsoft/api-extractor-model": { + "version": "7.28.13", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", + "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/tsdoc": "0.14.2", + "@microsoft/tsdoc-config": "~0.16.1", + "@rushstack/node-core-library": "4.0.2" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/typescript": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", + "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/tsdoc": "0.14.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" + } + }, + "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "6.4.10", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.10.tgz", + "integrity": "sha512-cblGjlM6+xsptwyaALw8RbRIUoqmKxOqLxlk2LkTDhxqUuql1YSOKKLH3w+Yd2QLz28b7MR65sx1OjsRZUfOSQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "6.4.10", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.4.10.tgz", + "integrity": "sha512-c2KdFl4KZ0QYC+JSDTMCNjcuOL2rVSdIx/beo7FwJDh2e9XqC1MoLCjw6L1Jo40zbArkgJyg3oFORbXcRfgZOA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^6.4.10", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "6.4.10", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.10.tgz", + "integrity": "sha512-L1B0+Vg9NFjo3NcfODH3bohl6fIkzjyDBHBHb3Al4QI7owaJrFm2sSDyfz++iatzICug6U6q5tHLQrCLO71xkg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/core-downloads-tracker": "^6.4.10", + "@mui/system": "^6.4.10", + "@mui/types": "~7.2.24", + "@mui/utils": "^6.4.9", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.0.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^6.4.10", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.9.tgz", + "integrity": "sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/utils": "^6.4.9", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.9.tgz", + "integrity": "sha512-qZRWO0cT407NI4ZRjZcH+1SOu8f3JzLHqdMlg52GyEufM9pkSZFnf7xjpwnlvkixcGjco6wLlMD0VB43KRcBuA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "6.4.10", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.10.tgz", + "integrity": "sha512-RyBGQwP3tgo4JEibK+RwVu1a6nQ6y8urMCNsb2aiN/nvTxxumq6P26aoG4GTUf8L4O1sthC4lMXlP4r8ixDkMg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/private-theming": "^6.4.9", + "@mui/styled-engine": "^6.4.9", + "@mui/types": "~7.2.24", + "@mui/utils": "^6.4.9", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.9.tgz", + "integrity": "sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/types": "~7.2.24", + "@types/prop-types": "^15.7.14", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/plugin-inject": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz", + "integrity": "sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-5.0.7.tgz", + "integrity": "sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.39.0.tgz", + "integrity": "sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.39.0.tgz", + "integrity": "sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.39.0.tgz", + "integrity": "sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.39.0.tgz", + "integrity": "sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.39.0.tgz", + "integrity": "sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.39.0.tgz", + "integrity": "sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.39.0.tgz", + "integrity": "sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.39.0.tgz", + "integrity": "sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.39.0.tgz", + "integrity": "sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.39.0.tgz", + "integrity": "sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.39.0.tgz", + "integrity": "sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.39.0.tgz", + "integrity": "sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.39.0.tgz", + "integrity": "sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.39.0.tgz", + "integrity": "sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.39.0.tgz", + "integrity": "sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.39.0.tgz", + "integrity": "sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.39.0.tgz", + "integrity": "sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.39.0.tgz", + "integrity": "sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.39.0.tgz", + "integrity": "sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.39.0.tgz", + "integrity": "sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rushstack/node-core-library": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", + "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "z-schema": "~5.0.2" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/node-core-library/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/@rushstack/rig-package": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", + "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" + } + }, + "node_modules/@rushstack/terminal": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", + "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rushstack/node-core-library": "4.0.2", + "supports-color": "~8.1.1" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/ts-command-line": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", + "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rushstack/terminal": "0.10.0", + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "string-argv": "~0.3.1" + } + }, + "node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/js-cookie": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", + "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==", + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.16", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz", + "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.17.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz", + "integrity": "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.20", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.20.tgz", + "integrity": "sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.6.tgz", + "integrity": "sha512-nf22//wEbKXusP6E9pfOCDwFdHAX4u172eaJI4YkDRQEZiorm6KfYnSC2SWLDMVWUOWPERmJnN0ujeAfTBLvrw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/react-select": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-5.0.1.tgz", + "integrity": "sha512-h5Im0AP0dr4AVeHtrcvQrLV+gmPa7SA0AGdxl2jOhtwiE6KgXBFSogWw8az32/nusE6AQHlCOHQWjP1S/+oMWA==", + "deprecated": "This is a stub types definition. react-select provides its own type definitions, so you do not need this installed.", + "dev": true, + "license": "MIT", + "dependencies": { + "react-select": "*" + } + }, + "node_modules/@types/react-syntax-highlighter": { + "version": "15.5.13", + "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz", + "integrity": "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/rollup-plugin-peer-deps-external": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@types/rollup-plugin-peer-deps-external/-/rollup-plugin-peer-deps-external-2.2.5.tgz", + "integrity": "sha512-BvxHEsbzspw1BDyktFdjx5AQ5OHZGFJuDUAj+dDzDT0pfnz9/vr8sxxQwGINsptaltxbTVBTAxlZujM62F79XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rollup": "^0.63.4" + } + }, + "node_modules/@types/rollup-plugin-peer-deps-external/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/rollup-plugin-peer-deps-external/node_modules/rollup": { + "version": "0.63.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.63.5.tgz", + "integrity": "sha512-dFf8LpUNzIj3oE0vCvobX6rqOzHzLBoblyFp+3znPbjiSmSvOoK2kMKx+Fv9jYduG1rvcCfCveSgEaQHjWRF6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "0.0.39", + "@types/node": "*" + }, + "bin": { + "rollup": "bin/rollup" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@volar/language-core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", + "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "1.11.1" + } + }, + "node_modules/@volar/source-map": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz", + "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "muggle-string": "^0.3.1" + } + }, + "node_modules/@volar/typescript": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz", + "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "1.11.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/language-core": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz", + "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "~1.11.1", + "@volar/source-map": "~1.11.1", + "@vue/compiler-dom": "^3.3.0", + "@vue/shared": "^3.3.0", + "computeds": "^0.0.1", + "minimatch": "^9.0.3", + "muggle-string": "^0.3.1", + "path-browserify": "^1.0.1", + "vue-template-compiler": "^2.7.14" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/language-core/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vue/language-core/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@xobotyi/scrollbar-width": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", + "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==", + "license": "MIT" + }, + "node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/autoseg": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/autoseg/-/autoseg-0.0.12.tgz", + "integrity": "sha512-MTCBZdgPCMgjGM3W2lRU7gMSSETUUvTnXcoKDde6A2piPdMePRCuMoeIld5amLZQ+0S7vcqVQj3YfVCx2kALUA==", + "license": "LGPL" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/browser-resolve": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", + "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.17.0" + } + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", + "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^5.2.1", + "randombytes": "^2.1.0", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", + "dev": true, + "license": "ISC", + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.5", + "hash-base": "~3.0", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/browserify-sign/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001712", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001712.tgz", + "integrity": "sha512-MBqPpGYYdQ7/hfKiet9SCI+nmN5/hp4ZzveOJubl5DTAMa5oggjAuoi0Z4onBpKPFI2ePGnQuQIzF3VxDjDJig==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cipher-base": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-alpha": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color-alpha/-/color-alpha-2.0.0.tgz", + "integrity": "sha512-AFicJNV27HMw2l3KZPngmoL9euIe+7YDVprQHuJbChyh1x/R4AjKdL9WKvfE5/nXIok+WfYhm+I6GsXaFgB7Xg==", + "license": "MIT", + "dependencies": { + "color-parse": "^2.0.0" + } + }, + "node_modules/color-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.0.tgz", + "integrity": "sha512-SbtvAMWvASO5TE2QP07jHBMXKafgdZz8Vrsrn96fiL+O92/FN/PLARzUW5sKt013fjAprK2d2iCn2hk2Xb5oow==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/color-parse": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-2.0.2.tgz", + "integrity": "sha512-eCtOz5w5ttWIUcaKLiktF+DxZO1R9KLNY/xhbV6CkhM7sR3GhVghmt6X6yOnzeaM24po+Z9/S1apbXMwA3Iepw==", + "license": "MIT", + "dependencies": { + "color-name": "^2.0.0" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/computeds": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cp-file": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-10.0.0.tgz", + "integrity": "sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.10", + "nested-error-stacks": "^2.1.1", + "p-event": "^5.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cpy/-/cpy-10.1.0.tgz", + "integrity": "sha512-VC2Gs20JcTyeQob6UViBLnyP0bYHkBh6EiKzot9vi2DmeGlFT9Wd7VG3NBrkNx/jYvFBeyDOMMHdHQhbtKLgHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^3.0.0", + "cp-file": "^10.0.0", + "globby": "^13.1.4", + "junk": "^4.0.1", + "micromatch": "^4.0.5", + "nested-error-stacks": "^2.1.1", + "p-filter": "^3.0.0", + "p-map": "^6.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy-cli": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-5.0.0.tgz", + "integrity": "sha512-fb+DZYbL9KHc0BC4NYqGRrDIJZPXUmjjtqdw4XRRg8iV8dIfghUX/WiL+q4/B/KFTy3sK6jsbUhBaz0/Hxg7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cpy": "^10.1.0", + "meow": "^12.0.1" + }, + "bin": { + "cpy": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz", + "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-cipher": "^1.0.1", + "browserify-sign": "^4.2.3", + "create-ecdh": "^4.0.4", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "diffie-hellman": "^5.0.3", + "hash-base": "~3.0.4", + "inherits": "^2.0.4", + "pbkdf2": "^3.1.2", + "public-encrypt": "^4.0.3", + "randombytes": "^2.1.0", + "randomfill": "^1.0.4" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/css-in-js-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", + "license": "MIT", + "dependencies": { + "hyphenate-style-name": "^1.0.3" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/domain-browser": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", + "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.134", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.134.tgz", + "integrity": "sha512-zSwzrLg3jNP3bwsLqWHmS5z2nIOQ5ngMnfMZOWWtXnqqQkPVyOipxK98w+1beLw1TB+EImPNcG8wVP/cLVs2Og==", + "dev": true, + "license": "ISC" + }, + "node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/email-addresses": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-3.1.0.tgz", + "integrity": "sha512-k0/r7GrWVL32kZlGwfPNgB2Y/mMXVTq/decgLczm/j34whdaspNrZO8CnXPf1laaHxI6ptUlsnAxN+UAPw+fzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-shallow-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", + "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" + }, + "node_modules/fastest-stable-stringify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", + "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/filename-reserved-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", + "integrity": "sha512-UZArj7+U+2reBBVCvVmRlyq9D7EYQdUtuNN+1iz7pF1jGcJ2L0TjiRCxsTZfj2xFbM4c25uGCUDpKTHA7L2TKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/filenamify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", + "integrity": "sha512-DKVP0WQcB7WaIMSwDETqImRej2fepPqvXQjaVib7LRZn9Rxn5UbvK2tYTqGf1A1DkIprQQkG4XSQXSOZp7Q3GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^1.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/filenamify-url": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/filenamify-url/-/filenamify-url-1.0.0.tgz", + "integrity": "sha512-O9K9JcZeF5VdZWM1qR92NSv1WY2EofwudQayPx5dbnnFl9k0IcZha4eV/FGkjnBK+1irOQInij0yiooCHu/0Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "filenamify": "^1.0.0", + "humanize-url": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fscreen": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fscreen/-/fscreen-1.2.0.tgz", + "integrity": "sha512-hlq4+BU0hlPmwsFjwGGzZ+OZ9N/wq9Ljg/sq3pX+2CD7hrJsX9tJgWWK/wiNTFM212CLHWhicOoqwXyZGGetJg==", + "license": "MIT" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gh-pages": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-2.2.0.tgz", + "integrity": "sha512-c+yPkNOPMFGNisYg9r4qvsMIjVYikJv7ImFOhPIVPt0+AcRUamZ7zkGRLHz7FKB0xrlZ+ddSOJsZv9XAFVXLmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^2.6.1", + "commander": "^2.18.0", + "email-addresses": "^3.0.1", + "filenamify-url": "^1.0.0", + "fs-extra": "^8.1.0", + "globby": "^6.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gh-pages/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/github-buttons": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.29.1.tgz", + "integrity": "sha512-TV3YgAKda5hPz75n7QXmGCsSzgVya1vvmBieebg3EB5ScmashTZ0FldViG1aU2d4V5rcAGrtQ7k5uAaCo0A4PA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz", + "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/hastscript/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/hastscript/node_modules/comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hastscript/node_modules/property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hastscript/node_modules/space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/highlightjs-vue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz", + "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==", + "license": "CC0-1.0" + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/humanize-url": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", + "integrity": "sha512-RtgTzXCPVb/te+e82NDhAc5paj+DuKSratIGAr+v+HZK24eAQ8LMoBGYoL7N/O+9iEc33AKHg45dOMKw3DNldQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "normalize-url": "^1.0.0", + "strip-url-auth": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hyphenate-style-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", + "license": "MIT" + }, + "node_modules/inline-style-prefixer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", + "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "license": "MIT", + "dependencies": { + "css-in-js-utils": "^3.1.0" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-timers-promises": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-timers-promises/-/isomorphic-timers-promises-1.0.1.tgz", + "integrity": "sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/junk": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", + "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowlight": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "license": "MIT", + "dependencies": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/monaco-editor": { + "version": "0.52.2", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", + "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", + "license": "MIT", + "peer": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/muggle-string": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz", + "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/nano-css": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.6.2.tgz", + "integrity": "sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==", + "license": "Unlicense", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "css-tree": "^1.1.2", + "csstype": "^3.1.2", + "fastest-stable-stringify": "^2.0.2", + "inline-style-prefixer": "^7.0.1", + "rtl-css-js": "^1.16.1", + "stacktrace-js": "^2.0.2", + "stylis": "^4.3.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/nano-css/node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nested-error-stacks": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", + "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-stdlib-browser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-stdlib-browser/-/node-stdlib-browser-1.3.1.tgz", + "integrity": "sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert": "^2.0.0", + "browser-resolve": "^2.0.0", + "browserify-zlib": "^0.2.0", + "buffer": "^5.7.1", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "create-require": "^1.1.1", + "crypto-browserify": "^3.12.1", + "domain-browser": "4.22.0", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "isomorphic-timers-promises": "^1.0.1", + "os-browserify": "^0.3.0", + "path-browserify": "^1.0.1", + "pkg-dir": "^5.0.0", + "process": "^0.11.10", + "punycode": "^1.4.1", + "querystring-es3": "^0.2.1", + "readable-stream": "^3.6.0", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.1", + "url": "^0.11.4", + "util": "^0.12.4", + "vm-browserify": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-stdlib-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-timeout": "^5.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", + "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^5.1.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter/node_modules/p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-6.0.0.tgz", + "integrity": "sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", + "dev": true, + "license": "ISC", + "dependencies": { + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/property-information": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz", + "integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-full-screen": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/react-full-screen/-/react-full-screen-1.1.1.tgz", + "integrity": "sha512-xoEgkoTiN0dw9cjYYGViiMCBYbkS97BYb4bHPhQVWXj1UnOs8PZ1rPzpX+2HMhuvQV1jA5AF9GaRbO3fA5aZtg==", + "license": "MIT", + "dependencies": { + "fscreen": "^1.0.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/react-github-btn": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-github-btn/-/react-github-btn-1.4.0.tgz", + "integrity": "sha512-lV4FYClAfjWnBfv0iNlJUGhamDgIq6TayD0kPZED6VzHWdpcHmPfsYOZ/CFwLfPv4Zp+F4m8QKTj0oy2HjiGXg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "github-buttons": "^2.22.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/react-hotkeys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-hotkeys/-/react-hotkeys-2.0.0.tgz", + "integrity": "sha512-3n3OU8vLX/pfcJrR3xJ1zlww6KS1kEJt0Whxc4FiGV+MJrQ1mYSYI3qS/11d2MJDFm8IhOXMTFQirfu6AVOF6Q==", + "license": "ISC", + "dependencies": { + "prop-types": "^15.6.1" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, + "node_modules/react-is": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", + "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==", + "license": "MIT" + }, + "node_modules/react-markdown": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.1.0.tgz", + "integrity": "sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, + "node_modules/react-monaco-editor": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.58.0.tgz", + "integrity": "sha512-e8JH0TQEzO96Wd/EXgzc9M9tQK1pxBECD+8GNob9slMURcCM36TiVrgc4topWCDGYxRuMj8IEkaX+s3eQcUUqw==", + "license": "MIT", + "peerDependencies": { + "monaco-editor": "^0.52.0", + "react": ">=16.8.0 <20.0.0", + "react-dom": ">=16.8.0 <20.0.0" + } + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", + "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-select": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.10.1.tgz", + "integrity": "sha512-roPEZUL4aRZDx6DcsD+ZNreVl+fM8VsKn0Wtex1v4IazH60ILp5xhdlp464IsEAlJdXeD+BhDAFsBVMfvLQueA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-syntax-highlighter": { + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz", + "integrity": "sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.4.1", + "highlightjs-vue": "^1.0.0", + "lowlight": "^1.17.0", + "prismjs": "^1.27.0", + "refractor": "^3.6.0" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/react-universal-interface": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", + "integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==", + "peerDependencies": { + "react": "*", + "tslib": "*" + } + }, + "node_modules/react-use": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.6.0.tgz", + "integrity": "sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g==", + "license": "Unlicense", + "dependencies": { + "@types/js-cookie": "^2.2.6", + "@xobotyi/scrollbar-width": "^1.9.5", + "copy-to-clipboard": "^3.3.1", + "fast-deep-equal": "^3.1.3", + "fast-shallow-equal": "^1.0.0", + "js-cookie": "^2.2.1", + "nano-css": "^5.6.2", + "react-universal-interface": "^0.6.2", + "resize-observer-polyfill": "^1.5.1", + "screenfull": "^5.1.0", + "set-harmonic-interval": "^1.0.1", + "throttle-debounce": "^3.0.1", + "ts-easing": "^0.2.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/react-use-measure": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz", + "integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.13", + "react-dom": ">=16.13" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/refractor": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "license": "MIT", + "dependencies": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.27.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "license": "MIT", + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/refractor/node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rollup": { + "version": "4.39.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.39.0.tgz", + "integrity": "sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.39.0", + "@rollup/rollup-android-arm64": "4.39.0", + "@rollup/rollup-darwin-arm64": "4.39.0", + "@rollup/rollup-darwin-x64": "4.39.0", + "@rollup/rollup-freebsd-arm64": "4.39.0", + "@rollup/rollup-freebsd-x64": "4.39.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.39.0", + "@rollup/rollup-linux-arm-musleabihf": "4.39.0", + "@rollup/rollup-linux-arm64-gnu": "4.39.0", + "@rollup/rollup-linux-arm64-musl": "4.39.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.39.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.39.0", + "@rollup/rollup-linux-riscv64-gnu": "4.39.0", + "@rollup/rollup-linux-riscv64-musl": "4.39.0", + "@rollup/rollup-linux-s390x-gnu": "4.39.0", + "@rollup/rollup-linux-x64-gnu": "4.39.0", + "@rollup/rollup-linux-x64-musl": "4.39.0", + "@rollup/rollup-win32-arm64-msvc": "4.39.0", + "@rollup/rollup-win32-ia32-msvc": "4.39.0", + "@rollup/rollup-win32-x64-msvc": "4.39.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-peer-deps-external": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/rollup-plugin-peer-deps-external/-/rollup-plugin-peer-deps-external-2.2.4.tgz", + "integrity": "sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "rollup": "*" + } + }, + "node_modules/rtl-css-js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", + "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT", + "peer": true + }, + "node_modules/screenfull": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", + "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-harmonic-interval": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", + "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==", + "license": "Unlicense", + "engines": { + "node": ">=6.9" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-generator": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", + "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT" + }, + "node_modules/stacktrace-gps": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", + "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", + "license": "MIT", + "dependencies": { + "source-map": "0.5.6", + "stackframe": "^1.3.4" + } + }, + "node_modules/stacktrace-gps/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stacktrace-js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", + "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "license": "MIT", + "dependencies": { + "error-stack-parser": "^2.0.6", + "stack-generator": "^2.0.5", + "stacktrace-gps": "^3.0.4" + } + }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/strip-url-auth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-url-auth/-/strip-url-auth-1.0.1.tgz", + "integrity": "sha512-++41PnXftlL3pvI6lpvhSEO+89g1kIJC4MYB5E6yH+WHa5InIqz51yGd1YOGd7VNSNdoEOfzTMqbAM/2PbgaHQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/style-to-js": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", + "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.8" + } + }, + "node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" + }, + "node_modules/transformation-matrix-js": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/transformation-matrix-js/-/transformation-matrix-js-2.7.6.tgz", + "integrity": "sha512-1CxDIZmCQ3vA0GGnkdMQqxUXVm3xXAFmglPYRS1hr37LzSg22TC7QAWOT38OmdUvMEs/rqcnkFoAsqvzdiluDg==", + "deprecated": "Package no longer supported. Contact support@npmjs.com for more info.", + "license": "MIT" + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-easing": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", + "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==", + "license": "Unlicense" + }, + "node_modules/tsconfck": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.5.tgz", + "integrity": "sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tss-react": { + "version": "4.9.16", + "resolved": "https://registry.npmjs.org/tss-react/-/tss-react-4.9.16.tgz", + "integrity": "sha512-7g9B96gdmR7klrYcslLdw0maeyS+PnWsID28eBkKQEbEJNbMjlgvgTFlGUyURrfafmbpkfjRzE5+lDMRT91LEQ==", + "license": "MIT", + "dependencies": { + "@emotion/cache": "*", + "@emotion/serialize": "*", + "@emotion/utils": "*" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/server": "^11.4.0", + "@mui/material": "^5.0.0 || ^6.0.0 || ^7.0.0", + "@types/react": "^16.8.0 || ^17.0.2 || ^18.0.0 || ^19.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/server": { + "optional": true + }, + "@mui/material": { + "optional": true + } + } + }, + "node_modules/tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-event-callback": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/use-event-callback/-/use-event-callback-0.1.0.tgz", + "integrity": "sha512-5fTzY5UEXHMK5UR0NRkUz6TPfWmmX9fO8Tx3SnHrfMPdrQ7Rna0gDBy0r56SP68TwsP9DgwSBzeysCu3A/Z2NA==", + "license": "ISC", + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", + "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/validator": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.0.tgz", + "integrity": "sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "5.4.17", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.17.tgz", + "integrity": "sha512-5+VqZryDj4wgCs55o9Lp+p8GE78TLVg0lasCH5xFZ4jacZjtqZa6JUw9/p0WeAojaOfncSM6v77InkFPGnvPvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-dts": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/vite-plugin-dts/-/vite-plugin-dts-3.9.1.tgz", + "integrity": "sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/api-extractor": "7.43.0", + "@rollup/pluginutils": "^5.1.0", + "@vue/language-core": "^1.8.27", + "debug": "^4.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.8", + "vue-tsc": "^1.8.27" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "typescript": "*", + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vite-plugin-node-polyfills": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.21.0.tgz", + "integrity": "sha512-Sk4DiKnmxN8E0vhgEhzLudfJQfaT8k4/gJ25xvUPG54KjLJ6HAmDKbr4rzDD/QWEY+Lwg80KE85fGYBQihEPQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/plugin-inject": "^5.0.5", + "node-stdlib-browser": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/davidmyersdev" + }, + "peerDependencies": { + "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/vite-tsconfig-paths": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz", + "integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/vue-tsc": { + "version": "1.8.27", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz", + "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "~1.11.1", + "@vue/language-core": "1.8.27", + "semver": "^7.5.4" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/vue-tsc/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "commander": "^9.4.1" + } + }, + "node_modules/z-schema/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json index 39df133a..59ca2c10 100644 --- a/package.json +++ b/package.json @@ -1,93 +1,112 @@ { - "name": "react-image-annotate", - "version": "2.0.0", + "name": "@amnstak/react-image-annotate", + "version": "0.0.23", + "type": "module", + "main": "dist/lib.js", + "types": "dist/lib.d.ts", + "files": [ + "dist" + ], + "keywords": [ + "react", + "image", + "annotation", + "labeling", + "image-labeling", + "image-annotation", + "image-segmentation", + "semantic-segmentation", + "bounding-box", + "react-component", + "drawing-tool", + "label-tool", + "typescript" + ], + "exports": { + ".": { + "import": "./dist/lib.js", + "types": "./dist/lib.d.ts" + }, + "./workspace": { + "import": "./dist/workspace.js", + "types": "./dist/workspace/index.d.ts" + }, + "./ImageViewer": { + "import": "./dist/ImageViewer.js", + "types": "./dist/ImageViewer/index.d.ts" + } + }, "dependencies": { - "@emotion/react": "^11.7.0", - "@emotion/styled": "^11.6.0", - "@fortawesome/fontawesome-svg-core": "^1.2.12", - "@fortawesome/free-solid-svg-icons": "^5.6.3", - "@fortawesome/react-fontawesome": "^0.1.3", - "@mui/icons-material": "^5.2.1", - "@mui/material": "^5.2.3", - "@mui/styles": "^5.2.3", - "@semantic-release/git": "^9.0.0", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "^0.2.0", + "@mui/icons-material": "^6.4.10", + "@mui/material": "^6.4.10", "autoseg": "^0.0.12", - "clamp": "^1.0.1", - "color-alpha": "^1.0.4", - "get-image-data": "^3.0.1", - "material-survey": "^2.1.0", - "mmgc1-cpp": "^1.0.50", - "moment": "^2.23.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-full-screen": "^0.3.1", + "classnames": "^2.5.1", + "color-alpha": "^2.0.0", + "immer": "^10.1.1", + "lodash": "^4.17.21", + "moment": "^2.30.0", + "react-full-screen": "^1.1.1", "react-hotkeys": "^2.0.0", - "react-json-view": "^1.19.1", - "react-markdown": "^4.0.6", - "react-material-workspace-layout": "^1.0.10", - "react-monaco-editor": "^0.25.1", + "react-markdown": "^9.0.0", + "react-monaco-editor": "^0.58.0", "react-remove-scroll": "^2.0.4", - "react-select": "^3.0.8", - "react-syntax-highlighter": "^12.2.1", - "react-use": "^13.27.0", + "react-select": "^5.8.0", + "react-syntax-highlighter": "^15.5.0", + "react-use": "^17.5.0", "react-use-measure": "^2.0.0", - "seamless-immutable": "^7.1.4", - "shallow-equal": "^1.2.1", - "storybook": "^5.3.14", - "styled-components": "^5.2.1", "transformation-matrix-js": "^2.7.6", - "use-event-callback": "^0.1.0", - "use-key-hook": "^1.3.0" + "tss-react": "^4.9.6", + "use-event-callback": "^0.1.0" + }, + "devDependencies": { + "@rollup/plugin-replace": "^5.0.5", + "@types/lodash": "^4.17.0", + "@types/node": "^20.12.4", + "@types/react": "^18.2.66", + "@types/react-dom": "^18.2.22", + "@types/react-select": "^5.0.1", + "@types/react-syntax-highlighter": "^15.5.11", + "@types/rollup-plugin-peer-deps-external": "^2.2.5", + "@vitejs/plugin-react": "^4.2.1", + "cpy-cli": "^5.0.0", + "cross-env": "^7.0.3", + "gh-pages": "^2.0.1", + "prettier": "^2.5.1", + "react-github-btn": "^1.1.1", + "rollup-plugin-peer-deps-external": "^2.2.4", + "typescript": "^5.2.2", + "vite": "^5.2.7", + "vite-plugin-dts": "^3.8.1", + "vite-plugin-node-polyfills": "^0.21.0", + "vite-tsconfig-paths": "^4.3.2" }, "peerDependencies": { - "react": "^17.0.0", - "react-dom": "^17.0.0" + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, - "homepage": "/react-image-annotate", "repository": { "type": "git", - "url": "https://github.com/UniversalDataTool/react-image-annotate.git" + "url": "git+https://github.com/aman1tagic/react-image-annotate.git" }, "scripts": { - "start": "react-scripts start", - "test": "react-scripts test", - "eject": "react-scripts eject", - "storybook": "start-storybook -p 9090 -s public", - "build": "npm run build:babel && cp ./package.json ./dist/package.json && cp ./README.md ./dist/README.md", - "dist": "npm run build && cd dist && npm publish", - "build:babel": "NODE_ENV=production babel ./src --ignore \"src/**/*.story.js\" --out-dir=./dist && rm dist/index.js && cp dist/lib.js dist/index.js", - "build-storybook": "build-storybook", - "build:gh-pages": "CI=false react-scripts build && mkdir build/demo && cp build/index.html build/demo/index.html", - "gh-pages": "npm run build:gh-pages && gh-pages -d build", + "start": "vite --force", + "build": "tsc && vite build", + "watch": "tsc && vite build --watch", "prettier": "prettier --write \"src/**/*.js\"", "prettier:test": "prettier --check \"src/**/*.js\"" }, - "eslintConfig": { - "extends": "react-app" - }, "browserslist": [ ">0.2%", "not dead", "not ie <= 11", "not op_mini all" ], - "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/plugin-proposal-optional-chaining": "^7.11.0", - "@storybook/addon-actions": "^5.3.14", - "@storybook/addon-links": "^5.3.14", - "@storybook/addons": "^5.3.14", - "@storybook/react": "^5.3.14", - "babel-loader": "^8.0.5", - "babel-preset-react-app": "^7.0.0", - "gh-pages": "^2.0.1", - "prettier": "^2.5.1", - "raw.macro": "^0.3.0", - "react-github-btn": "^1.1.1", - "react-scripts": "^3.4.1" - }, "prettier": { - "semi": false + "semi": true } } diff --git a/src/Annotator/bike-pic.png b/src/Annotator/bike-pic.png deleted file mode 100644 index 51d6de7b..00000000 Binary files a/src/Annotator/bike-pic.png and /dev/null differ diff --git a/src/Annotator/bike-pic2.png b/src/Annotator/bike-pic2.png deleted file mode 100644 index 61b4fccc..00000000 Binary files a/src/Annotator/bike-pic2.png and /dev/null differ diff --git a/src/Annotator/dab-keyframes.story.json b/src/Annotator/dab-keyframes.story.json deleted file mode 100644 index c033ab8b..00000000 --- a/src/Annotator/dab-keyframes.story.json +++ /dev/null @@ -1 +0,0 @@ -{"0":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4746317908870222,"y":0.17626206226677932},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4487209921649774,"y":0.2694362475702937},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.41397696660587197,"y":0.3699387395830733},"rightElbow":{"x":0.5906415033470862,"y":0.364704234790741},"rightHand":{"x":0.6542407365739231,"y":0.4002988673786005}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"479":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4673470463145521,"y":0.19100168229192332},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.2893273657811563},"leftHand":{"x":0.4404478609960767,"y":0.3051551630931666},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4328309749571659,"y":0.4222888613021013},"rightElbow":{"x":0.5874898343303621,"y":0.3913183287097443},"rightHand":{"x":0.6415204525487472,"y":0.44683362315624264}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"716":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4746317908870222,"y":0.17626206226677932},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4363544745930924,"y":0.3228281964520828},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.585930449033987,"y":0.4044864712124663},"rightHand":{"x":0.6389298100563513,"y":0.4411280047587922}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"1095":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4746317908870221,"y":0.17626206226677932},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.2893273657811563},"leftHand":{"x":0.44737492639237225,"y":0.476382614412626},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.5655850955624976,"y":0.42795303711459537},"rightHand":{"x":0.5894808372714573,"y":0.5232999966249137}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"1118":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4976149858125678,"y":0.17778527206277028},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.2893273657811563},"leftHand":{"x":0.4455200023009997,"y":0.4826821239054704},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.42592776068568866,"y":0.42512094920834825},"rightElbow":{"x":0.5672683442310021,"y":0.42601155864067825},"rightHand":{"x":0.5935719393363946,"y":0.5165015944201626}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"1368":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5017798209688135,"y":0.17963630990999058},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.28932736578115625},"leftHand":{"x":0.48879738488820257,"y":0.356707045987093},"rightShoulder":{"x":0.5370532605355843,"y":0.27885835619649174},"leftElbow":{"x":0.4251806625619568,"y":0.4172075506845399},"rightElbow":{"x":0.564526723209169,"y":0.4061013580655783},"rightHand":{"x":0.5498343845048111,"y":0.4866834521414889}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"1373":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4893538356154567,"y":0.35528212616454297},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.585930449033987,"y":0.4044864712124663},"rightHand":{"x":0.5483298762505795,"y":0.4889846449138738}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"1625":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4893538356154567,"y":0.35528212616454297},"rightShoulder":{"x":0.5454579431886196,"y":0.28828477914079875},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.5775664698606539,"y":0.4049712346052037},"rightHand":{"x":0.5085707949521467,"y":0.4088800509647476}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"1794":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4893538356154567,"y":0.35528212616454297},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646188},"rightHand":{"x":0.5071732824961516,"y":0.40718439246878346}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"2235":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.17967333066693503},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.48980642347488146,"y":0.3397084520431372},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4257163155055763,"y":0.41564655218944524},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646188},"rightHand":{"x":0.5067367749125811,"y":0.4064483881453737}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"2623":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.17967333066693503},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.28932736578115636},"leftHand":{"x":0.4872300656474055,"y":0.34559726993451106},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.42620073914177703,"y":0.4144124037913681},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646187},"rightHand":{"x":0.5089450816218464,"y":0.40579407504633214}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"2864":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.17967333066693503},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.28932736578115636},"leftHand":{"x":0.49311888353877925,"y":0.37176979389617243},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.42650163114261314,"y":0.41364583223483053},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646188},"rightHand":{"x":0.5048965193215269,"y":0.43196659900799356}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"3001":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4747072291917559,"y":0.48474464491387376},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646188},"rightHand":{"x":0.5262084056623442,"y":0.515722796174378}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"3011":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4820773499924534,"y":0.48104008143610855},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4252973252321734,"y":0.41426597685380695},"rightElbow":{"x":0.5725414114822169,"y":0.40306213118302386},"rightHand":{"x":0.5317642509509198,"y":0.517027301883393}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"3091":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.44306393146210193,"y":0.5274963114680574},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.42635016229370254,"y":0.39199952997175247},"rightElbow":{"x":0.5762984362544342,"y":0.41626308463099676},"rightHand":{"x":0.576666487372645,"y":0.5418911996469712}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"3301":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4105282826954702,"y":0.3656471031771597},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4291138595802166,"y":0.3335501069063595},"rightElbow":{"x":0.5894808372714573,"y":0.3382702534167713},"rightHand":{"x":0.6601060294334938,"y":0.40435230456253646}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"3537":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4307069090274806,"y":0.2278188250731353},"sternum":{"x":0.47318822762118673,"y":0.2957889348230651},"leftShoulder":{"x":0.44823045294738434,"y":0.29295684691681806},"leftHand":{"x":0.4774363594805573,"y":0.22970688367730002},"rightShoulder":{"x":0.5257588593808981,"y":0.25613970413560605},"leftElbow":{"x":0.4052181178712569,"y":0.3061732571459711},"rightElbow":{"x":0.5931979526484066,"y":0.26746805576059435},"rightHand":{"x":0.6786916063182402,"y":0.2419792646043707}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"4306":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.45490878631628445,"y":0.20669718671199733},"sternum":{"x":0.4775885689464238,"y":0.2942243690185364},"leftShoulder":{"x":0.44427014575467094,"y":0.28669858369870316},"leftHand":{"x":0.4769963253480336,"y":0.2516108049407023},"rightShoulder":{"x":0.5257588593808981,"y":0.25613970413560605},"leftElbow":{"x":0.41049852746154136,"y":0.34606968516145387},"rightElbow":{"x":0.5999667042505391,"y":0.2735681705235042},"rightHand":{"x":0.6762419117855385,"y":0.24400117278228467}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"4465":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.45991281556065355,"y":0.2023300339169116},"sternum":{"x":0.4784983924454,"y":0.29390087621890043},"leftShoulder":{"x":0.4434513046055924,"y":0.2854046125001592},"leftHand":{"x":0.476905342998136,"y":0.25613970413560605},"rightShoulder":{"x":0.5257588593808981,"y":0.25613970413560605},"leftElbow":{"x":0.4115903156603128,"y":0.3543187515521714},"rightElbow":{"x":0.5990391339550412,"y":0.30428519854180636},"rightHand":{"x":0.6686022931522351,"y":0.30239713993764167}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"4810":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4980040473937477,"y":0.18459443390996827},"sternum":{"x":0.49527667313378676,"y":0.28906389439882496},"leftShoulder":{"x":0.4547879807463942,"y":0.2854046125001592},"leftHand":{"x":0.46466173276607,"y":0.3488485223537189},"rightShoulder":{"x":0.5398163377954923,"y":0.28032461323598334},"leftElbow":{"x":0.42746166225743537,"y":0.39543309702281276},"rightElbow":{"x":0.5844822636231334,"y":0.3969339197196268},"rightHand":{"x":0.6469935239337719,"y":0.42242271087585054}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"4869":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.504518200084045,"y":0.18156138927109972},"sternum":{"x":0.4981460022949891,"y":0.28823670040640625},"leftShoulder":{"x":0.4567267166661256,"y":0.2854046125001592},"leftHand":{"x":0.46256789797276016,"y":0.36470307387507733},"rightShoulder":{"x":0.5422203703359592,"y":0.2844605831980768},"leftElbow":{"x":0.4301758925450592,"y":0.4024642459583717},"rightElbow":{"x":0.5809845735527162,"y":0.38358365991672455},"rightHand":{"x":0.6484236668202246,"y":0.42323289060418356}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"5352":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.509297348425837,"y":0.19005765298984095},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.41849352993179006,"y":0.4968671761666076},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.4434513046055924,"y":0.40624036316670115},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.5751433922460815,"y":0.5563410221977962}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"5643":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4434513046055924,"y":0.3014531106355593},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.43229995847474456,"y":0.3448784585313478},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.562930013150391,"y":0.5676693738227845}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"5957":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.49389787043561834,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.4588507825958108,"y":0.29201281761473563},"leftHand":{"x":0.45938179907823223,"y":0.2183785320523117},"rightShoulder":{"x":0.5459374857129085,"y":0.29106878831265337},"leftElbow":{"x":0.41477641455484077,"y":0.3175016087709594},"rightElbow":{"x":0.5639920461152337,"y":0.42700900781251294},"rightHand":{"x":0.5868257548593507,"y":0.5553969928957139}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"6182":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4370365444267241,"y":0.27512838513550697},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.41660051697537204,"y":0.3458765353125571},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.5993932064495242,"y":0.5457884600719732}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"6219":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4333619914395872,"y":0.2844605831980768},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.41690048048452605,"y":0.350542634343842},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.6012305895492022,"y":0.5461532388538225}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"6222":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4333619914395872,"y":0.2844605831980768},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.41690048048452605,"y":0.350542634343842},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.6070043811913611,"y":0.5440686412707255}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"6594":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4121213321427341,"y":0.3288299603959477},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.41690048048452605,"y":0.350542634343842},"rightElbow":{"x":0.5708952603867109,"y":0.43456124222917186},"rightHand":{"x":0.5985081174726199,"y":0.5563410221977962}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"6901":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.46681602983213083,"y":0.18533750647942915},"sternum":{"x":0.4869946561641412,"y":0.290124759010571},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.46150586500791746,"y":0.22970688367730002},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.40628015083609953,"y":0.3118374329584653},"rightElbow":{"x":0.5512476505371218,"y":0.4364493008333366},"rightHand":{"x":0.5544337494316498,"y":0.5789977254477728}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"7267":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4439823210880137,"y":0.21932256135439407},"sternum":{"x":0.47637432651571476,"y":0.2891807297084886},"leftShoulder":{"x":0.4370791068165365,"y":0.30522922784388873},"leftHand":{"x":0.46150586500791746,"y":0.22970688367730002},"rightShoulder":{"x":0.5193866615918421,"y":0.2778523780835004},"leftElbow":{"x":0.3945977882228303,"y":0.30994937435430053},"rightElbow":{"x":0.550185617572279,"y":0.43078512502084254},"rightHand":{"x":0.561336963703127,"y":0.5657813152186197}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]}} diff --git a/src/Annotator/index.js b/src/Annotator/index.js deleted file mode 100644 index e4795c94..00000000 --- a/src/Annotator/index.js +++ /dev/null @@ -1,206 +0,0 @@ -// @flow - -import type { - Action, - Image, - MainLayoutState, - Mode, - ToolEnum, -} from "../MainLayout/types" -import React, { useEffect, useReducer } from "react" -import makeImmutable, { without } from "seamless-immutable" - -import type { KeypointsDefinition } from "../ImageCanvas/region-tools" -import MainLayout from "../MainLayout" -import type { Node } from "react" -import SettingsProvider from "../SettingsProvider" -import combineReducers from "./reducers/combine-reducers.js" -import generalReducer from "./reducers/general-reducer.js" -import getFromLocalStorage from "../utils/get-from-local-storage" -import historyHandler from "./reducers/history-handler.js" -import imageReducer from "./reducers/image-reducer.js" -import useEventCallback from "use-event-callback" -import videoReducer from "./reducers/video-reducer.js" - -type Props = { - taskDescription?: string, - allowedArea?: { x: number, y: number, w: number, h: number }, - regionTagList?: Array, - regionClsList?: Array, - imageTagList?: Array, - imageClsList?: Array, - enabledTools?: Array, - selectedTool?: String, - showTags?: boolean, - selectedImage?: string | number, - images?: Array, - showPointDistances?: boolean, - pointDistancePrecision?: number, - RegionEditLabel?: Node, - onExit: (MainLayoutState) => any, - videoTime?: number, - videoSrc?: string, - keyframes?: Object, - videoName?: string, - keypointDefinitions: KeypointsDefinition, - fullImageSegmentationMode?: boolean, - autoSegmentationOptions?: - | {| type: "simple" |} - | {| type: "autoseg", maxClusters?: number, slicWeightFactor?: number |}, - hideHeader?: boolean, - hideHeaderText?: boolean, - hideNext?: boolean, - hidePrev?: boolean, - hideClone?: boolean, - hideSettings?: boolean, - hideFullScreen?: boolean, - hideSave?: boolean, -} - -export const Annotator = ({ - images, - allowedArea, - selectedImage = images && images.length > 0 ? 0 : undefined, - showPointDistances, - pointDistancePrecision, - showTags = getFromLocalStorage("showTags", true), - enabledTools = [ - "select", - "create-point", - "create-box", - "create-polygon", - "create-line", - "create-expanding-line", - "show-mask", - ], - selectedTool = "select", - regionTagList = [], - regionClsList = [], - imageTagList = [], - imageClsList = [], - keyframes = {}, - taskDescription = "", - fullImageSegmentationMode = false, - RegionEditLabel, - videoSrc, - videoTime = 0, - videoName, - onExit, - onNextImage, - onPrevImage, - keypointDefinitions, - autoSegmentationOptions = { type: "autoseg" }, - hideHeader, - hideHeaderText, - hideNext, - hidePrev, - hideClone, - hideSettings, - hideFullScreen, - hideSave, - allowComments, -}: Props) => { - if (typeof selectedImage === "string") { - selectedImage = (images || []).findIndex((img) => img.src === selectedImage) - if (selectedImage === -1) selectedImage = undefined - } - const annotationType = images ? "image" : "video" - const [state, dispatchToReducer] = useReducer( - historyHandler( - combineReducers( - annotationType === "image" ? imageReducer : videoReducer, - generalReducer - ) - ), - makeImmutable({ - annotationType, - showTags, - allowedArea, - showPointDistances, - pointDistancePrecision, - selectedTool, - fullImageSegmentationMode: fullImageSegmentationMode, - autoSegmentationOptions, - mode: null, - taskDescription, - showMask: true, - labelImages: imageClsList.length > 0 || imageTagList.length > 0, - regionClsList, - regionTagList, - imageClsList, - imageTagList, - currentVideoTime: videoTime, - enabledTools, - history: [], - videoName, - keypointDefinitions, - allowComments, - ...(annotationType === "image" - ? { - selectedImage, - images, - selectedImageFrameTime: - images && images.length > 0 ? images[0].frameTime : undefined, - } - : { - videoSrc, - keyframes, - }), - }) - ) - - const dispatch = useEventCallback((action: Action) => { - if (action.type === "HEADER_BUTTON_CLICKED") { - if (["Exit", "Done", "Save", "Complete"].includes(action.buttonName)) { - return onExit(without(state, "history")) - } else if (action.buttonName === "Next" && onNextImage) { - return onNextImage(without(state, "history")) - } else if (action.buttonName === "Prev" && onPrevImage) { - return onPrevImage(without(state, "history")) - } - } - dispatchToReducer(action) - }) - - const onRegionClassAdded = useEventCallback((cls) => { - dispatchToReducer({ - type: "ON_CLS_ADDED", - cls: cls, - }) - }) - - useEffect(() => { - if (selectedImage === undefined) return - dispatchToReducer({ - type: "SELECT_IMAGE", - imageIndex: selectedImage, - image: state.images[selectedImage], - }) - }, [selectedImage, state.images]) - - if (!images && !videoSrc) - return 'Missing required prop "images" or "videoSrc"' - - return ( - - - - ) -} - -export default Annotator diff --git a/src/Annotator/index.story.js b/src/Annotator/index.story.js deleted file mode 100644 index dae1ece0..00000000 --- a/src/Annotator/index.story.js +++ /dev/null @@ -1,727 +0,0 @@ -// @flow - -import React, { useState } from "react" - -import { storiesOf } from "@storybook/react" -import { action as actionAddon } from "@storybook/addon-actions" -import exampleImage from "../ImageCanvas/seves_desk.story.jpg" -import bikeImg1 from "./bike-pic.png" -import bikeImg2 from "./bike-pic2.png" -import { HotKeys } from "react-hotkeys" -import { defaultKeyMap } from "../ShortcutsManager" - -import Annotator from "./" - -import { testRegions } from "../ImageCanvas/index.story" - -const middlewares = [ - (store) => (next) => (action) => { - actionAddon(action.type)(action) - return next(action) - }, -] - -storiesOf("Annotator", module) - .add("Basic", () => ( - - )) - .add("Basic - Allow Comments", () => ( - - )) - .add("Fixed Size Container", () => ( -
- (next) => (action) => { - actionAddon(action.type)(action) - return next(action) - }, - ]} - labelImages - regionClsList={["Alpha", "Beta", "Charlie", "Delta"]} - regionTagList={["tag1", "tag2", "tag3"]} - imageClsList={["Alpha", "Beta", "Charlie", "Delta"]} - imageTagList={["tag1", "tag2", "tag3"]} - images={[ - { - src: exampleImage, - name: "Seve's Desk", - regions: testRegions, - }, - { - src: "https://loremflickr.com/100/100/cars?lock=1", - name: "Frame 0036", - }, - { - src: "https://loremflickr.com/100/100/cars?lock=2", - name: "Frame 0037", - }, - { - src: "https://loremflickr.com/100/100/cars?lock=3", - name: "Frame 0038", - }, - ]} - /> -
- )) - .add("Shrunk Annotator (Test Fullscreen)", () => ( -
- (next) => (action) => { - actionAddon(action.type)(action) - return next(action) - }, - ]} - images={[ - { - src: exampleImage, - name: "Seve's Desk", - regions: testRegions, - }, - ]} - /> -
- )) - .add("Annotator w/o No Region Labels or Image Labels", () => ( - - )) - .add("Annotator with no enabled tools", () => ( - - )) - .add("Bounding Box Annotator with output to console.log", () => ( - { - window.lastOutput = out - console.log(out) - }} - taskDescription={`## Annotate Hands\nDraw a bounding box around each hand.`} - enabledTools={["select", "create-box"]} - regionClsList={["Hand", "Face"]} - regionTagList={["Open Pinch", "Closed Pinch", "In Frame"]} - showTags={false} - images={[ - { - src: "https://s3.amazonaws.com/jobstorage.workaround.online/Atheer/video-frames/VID_20190111_161054.mp4_frame017.png", - name: "Bounding Box Test", - regions: [], - }, - { - src: "https://s3.amazonaws.com/jobstorage.workaround.online/Atheer/video-frames/VID_20190111_161054.mp4_frame001.png", - name: "Bounding Box Test", - regions: [], - }, - ]} - /> - )) - .add("Bounding Box Annotator with allowed area", () => ( - - )) - .add("Car Annotation", () => ( - { - window.lastOutput = out - console.log(JSON.stringify(out.images)) - }} - /> - )) - .add("Annotator blocks scroll from propagating", () => ( -
- (next) => (action) => { - actionAddon(action.type)(action) - return next(action) - }, - ]} - images={[ - { - src: exampleImage, - name: "Seve's Desk", - regions: testRegions, - }, - ]} - /> -
You shouldn't be able to see this
-
- )) - .add("Annotator should not expand beyond parent", () => ( -
- (next) => (action) => { - actionAddon(action.type)(action) - return next(action) - }, - ]} - images={[ - { - src: exampleImage, - name: "Seve's Desk", - regions: testRegions, - }, - ]} - /> -
- )) - .add("Video with frames as each image", () => ( -
- (next) => (action) => { - actionAddon(action.type)(action) - return next(action) - }, - ]} - images={[ - { - src: "https://s3.amazonaws.com/asset.workaround.online/SampleVideo_1280x720_1mb.mp4", - frameTime: 0, - name: "Frame 1", - }, - { - src: "https://s3.amazonaws.com/asset.workaround.online/SampleVideo_1280x720_1mb.mp4", - frameTime: 4500, - name: "Frame 2", - }, - ]} - /> -
- )) - .add("Keyframe video", () => ( -
- { - console.log(...args) - actionAddon("onExit")(...args) - }} - showTags - videoSrc="https://s3.amazonaws.com/asset.workaround.online/SampleVideo_1280x720_1mb.mp4" - videoTime={1000} - keyframes={{ - 0: { - regions: [ - { - type: "point", - x: 0.1608187134502924, - y: 0.5769980506822612, - highlighted: true, - editingLabels: false, - color: "hsl(238,100%,50%)", - id: "9995495728521284", - }, - { - type: "box", - x: 0.089171974522293, - y: 0.36801132342533616, - w: 0.30573248407643316, - h: 0.4170794998820476, - highlighted: true, - editingLabels: false, - color: "hsl(263,100%,50%)", - id: "04858393322065635", - }, - ], - }, - 3333: { - regions: [ - { - type: "point", - x: 0.1608187134502924, - y: 0.5769980506822612, - highlighted: true, - editingLabels: false, - color: "hsl(238,100%,50%)", - id: "9995495728521284", - }, - { - type: "box", - x: 0.14861995753715496, - y: 0.0934182590233546, - w: 0.3163481953290871, - h: 0.7596131163010142, - highlighted: true, - editingLabels: false, - color: "hsl(263,100%,50%)", - id: "04858393322065635", - }, - ], - }, - }} - /> -
- )) - .add("Override Next/Prev Button Handling", () => { - const images = [ - exampleImage, - "https://loremflickr.com/100/100/cars?lock=1", - "https://loremflickr.com/100/100/cars?lock=2", - ] - const [selectedImageIndex, changeSelectedImageIndex] = useState(0) - - return ( - { - actionAddon("onNextImage")() - changeSelectedImageIndex((selectedImageIndex + 1) % 3) - }} - onPrevImage={() => { - actionAddon("onPrevImage")() - changeSelectedImageIndex((selectedImageIndex - 1 + 3) % 3) - }} - labelImages - selectedImage={images[selectedImageIndex]} - regionClsList={["Alpha", "Beta", "Charlie", "Delta"]} - imageClsList={["Alpha", "Beta", "Charlie", "Delta"]} - images={[ - { - src: exampleImage, - name: "Seve's Desk", - }, - { - src: images[1], - name: "Frame 0036", - }, - { - src: images[2], - name: "Frame 0037", - }, - ]} - /> - ) - }) - .add("Override RegionEditLabel", () => { - const images = [ - exampleImage, - "https://loremflickr.com/100/100/cars?lock=1", - "https://loremflickr.com/100/100/cars?lock=2", - ] - - const NewRegionEditLabel = ({ - region, - editing, - onDelete, - onChange, - onClose, - onOpen, - }) => { - return ( -
- I'm the closed part -
- I'm the part that shows when it's being edited! - - - -
-
- ) - } - - return ( - - ) - }) - .add("Two on sample page w/ hotkeys", () => { - return ( - -
-
- (next) => (action) => { - actionAddon(action.type)(action) - return next(action) - }, - ]} - images={[ - { - src: exampleImage, - name: "Seve's Desk", - regions: testRegions, - }, - ]} - /> -
-
- (next) => (action) => { - actionAddon(action.type)(action) - return next(action) - }, - ]} - images={[ - { - src: exampleImage, - name: "Seve's Desk", - regions: testRegions, - }, - ]} - /> -
-
-
- ) - }) - .add("CORs Error (Pixel Segmentation)", () => ( - - )) - .add("Modify Allowed Area", () => ( - - )) - .add("Hide Next, Hide Header Text", () => ( - - )) - .add("Hide Header", () => ( - - )) diff --git a/src/Annotator/index.tsx b/src/Annotator/index.tsx new file mode 100644 index 00000000..af0433e4 --- /dev/null +++ b/src/Annotator/index.tsx @@ -0,0 +1,229 @@ +import { + Action, + AnnotatorToolEnum, + Image, + MainLayoutState, + RegionAllowedActions, +} from "../MainLayout/types.ts"; +import { ComponentType, forwardRef, FunctionComponent, useEffect, useImperativeHandle, useReducer, useRef } from "react"; + +import type { KeypointsDefinition } from "../types/region-tools.ts"; +import MainLayout, { MainLayoutRef } from "../MainLayout/index.tsx"; +import SettingsProvider from "../SettingsProvider/index.tsx"; +import combineReducers from "./reducers/combine-reducers.ts"; +import generalReducer from "./reducers/general-reducer.ts"; +import getFromLocalStorage from "../utils/get-from-local-storage.ts"; +import historyHandler from "./reducers/history-handler.ts"; +import imageReducer from "./reducers/image-reducer.ts"; +import useEventCallback from "use-event-callback"; +import { AutosegOptions } from "autoseg/webworker"; +import { produce } from "immer"; + +export type AnnotatorProps = { + taskDescription?: string; + allowedArea?: { x: number; y: number; w: number; h: number }; + regionTagList?: Array; + regionTagSingleSelection?: boolean; + regionAllowedActions?: Partial; + regionClsList?: Array; + imageTagList?: Array; + imageClsList?: Array; + enabledTools?: Array; + selectedTool?: String; + showTags?: boolean; + selectedCls?: string; + selectedImage?: string | number; + images?: Array; + showPointDistances?: boolean; + pointDistancePrecision?: number; + RegionEditLabel?: ComponentType | FunctionComponent | null; + onExit: (state: MainLayoutState) => void; + keypointDefinitions?: KeypointsDefinition; + fullImageSegmentationMode?: boolean; + autoSegmentationOptions?: AutosegOptions; + hideHeader?: boolean; + hideHeaderText?: boolean; + hideNext?: boolean; + hidePrev?: boolean; + hideClone?: boolean; + hideSettings?: boolean; + hideFullScreen?: boolean; + hideSave?: boolean; + allowComments?: boolean; + customeHeaderItem?: { + icon: React.ReactNode, + name: string, + onClickAction: () => void + } + onNextImage?: (state: MainLayoutState) => void; + onPrevImage?: (state: MainLayoutState) => void; +}; + +export type AnnotatorRef = { + clickHeaderButton: (name: string) => void; +} + +export const Annotator = forwardRef(({ + images, + allowedArea, + selectedImage = images && images.length > 0 ? 0 : undefined, + showPointDistances, + pointDistancePrecision, + showTags = getFromLocalStorage("showTags", true), + selectedCls, + enabledTools = [ + "select", + "create-point", + "create-box", + "create-polygon", + "create-line", + "create-expanding-line", + "show-mask", + ], + selectedTool = "create-box", + regionTagSingleSelection = false, + regionTagList = [], + regionClsList = [], + regionAllowedActions = { + remove: true, + lock: true, + visibility: true, + }, + imageTagList = [], + imageClsList = [], + taskDescription = "", + fullImageSegmentationMode = false, + RegionEditLabel, + onExit, + onNextImage, + onPrevImage, + autoSegmentationOptions = { type: "autoseg" }, + hideHeader, + hideHeaderText, + hideNext, + hidePrev, + hideClone, + hideSettings, + hideFullScreen, + hideSave, + allowComments, + customeHeaderItem +}, ref) => { + if (typeof selectedImage === "string") { + selectedImage = (images || []).findIndex( + (img) => img.name === selectedImage + ); + + if (selectedImage === -1) selectedImage = undefined; + } + + const mainLayoutRef = useRef(null); + + useImperativeHandle(ref, () => ({ + clickHeaderButton(name: string) { + mainLayoutRef.current?.clickHeaderButton(name); + }, + })); + + const combinedReducers = combineReducers(imageReducer, generalReducer) as ( + state: MainLayoutState, + action: Action + ) => MainLayoutState; + + const immutableState = { + showTags, + selectedCls, + allowedArea, + showPointDistances, + pointDistancePrecision, + selectedTool, + fullImageSegmentationMode: fullImageSegmentationMode, + autoSegmentationOptions, + mode: null, + taskDescription, + showMask: true, + labelImages: imageClsList.length > 0 || imageTagList.length > 0, + regionClsList, + regionTagList, + regionTagSingleSelection, + imageClsList, + imageTagList, + enabledTools, + history: [], + allowComments, + regionAllowedActions: { + remove: regionAllowedActions?.remove ?? true, + lock: regionAllowedActions?.lock ?? true, + visibility: regionAllowedActions?.visibility ?? true, + }, + ...{ + selectedImage, + images, + }, + }; + const [state, dispatchToReducer] = useReducer( + historyHandler(combinedReducers) as unknown as ( + state: MainLayoutState, + action: Action + ) => MainLayoutState, + immutableState as unknown as MainLayoutState + ); + + const dispatch = useEventCallback((action: Action) => { + if (action.type === "HEADER_BUTTON_CLICKED") { + if (["Exit", "Done", "Save", "Complete"].includes(action.buttonName)) { + return onExit(produce(state, s => {s.history.splice(0)})); + } else if (action.buttonName === "Next" && onNextImage) { + return onNextImage(produce(state, s => {s.history.splice(0)})); + } else if (action.buttonName === "Prev" && onPrevImage) { + return onPrevImage(produce(state, s => {s.history.splice(0)})); + } + } + dispatchToReducer(action); + }); + + const onRegionClassAdded = useEventCallback((cls) => { + dispatchToReducer({ + type: "ON_CLS_ADDED", + cls: cls, + }); + }); + + useEffect(() => { + if (selectedImage === undefined) return; + const image = state.images[selectedImage]; + dispatchToReducer({ + type: "SELECT_IMAGE", + imageIndex: +selectedImage, + image, + }); + // @ts-ignore + }, [selectedImage, state.images]); + + if (!images) return
Missing required "images"
; + + return ( + + + + ); +}); + +export default Annotator; diff --git a/src/Annotator/poses.story.js b/src/Annotator/poses.story.js deleted file mode 100644 index 042a38da..00000000 --- a/src/Annotator/poses.story.js +++ /dev/null @@ -1,150 +0,0 @@ -// @flow - -import React, { useState } from "react" - -import { storiesOf } from "@storybook/react" -import { action as actionAddon } from "@storybook/addon-actions" -import dancingManImage from "../ImageCanvas/dancing-man.story.jpg" -import dabKeyframes from "./dab-keyframes.story.json" -import Annotator from "./" - -const dancingManVideo = - "https://s3.us-east-1.amazonaws.com/asset.workaround.online/developer-samples/how-to-dab.mp4" - -const middlewares = [ - (store) => (next) => (action) => { - actionAddon(action.type)(action) - console.log(action) - return next(action) - }, -] - -storiesOf("Annotator (Poses)", module) - .add("Image", () => ( - - )) - .add("Video", () => ( - { - actionAddon("onExit")(...props) - window.testPropsSavePlease = props - console.log(...props) - }} - labelImages - enabledTools={["create-box", "create-keypoints"]} - videoSrc={dancingManVideo} - keypointDefinitions={{ - human: { - connections: [ - ["head", "sternum"], - ["sternum", "leftShoulder"], - ["leftShoulder", "leftElbow"], - ["leftElbow", "leftHand"], - ["sternum", "rightShoulder"], - ["rightShoulder", "rightElbow"], - ["rightElbow", "rightHand"], - ], - landmarks: { - head: { - label: "Head", - color: "#f00", - defaultPosition: [0, -0.05], - }, - sternum: { - label: "Torso", - color: "#0f0", - defaultPosition: [0, 0], - }, - leftShoulder: { - label: "Left Shoulder", - color: "#00f", - defaultPosition: [-0.05, 0], - }, - leftHand: { - label: "Left Hand", - color: "#00f", - defaultPosition: [-0.05, 0.05], - }, - rightShoulder: { - label: "Right Shoulder", - color: "#00f", - defaultPosition: [0.05, 0], - }, - leftElbow: { - label: "Left Elbow", - color: "#00f", - defaultPosition: [-0.08, 0.02], - }, - rightElbow: { - label: "Right Elbow", - color: "#00f", - defaultPosition: [0.08, 0.02], - }, - rightHand: { - label: "Right Hand", - color: "#00f", - defaultPosition: [0.05, 0.05], - }, - }, - }, - }} - keyframes={dabKeyframes} - /> - )) diff --git a/src/Annotator/reducers/combine-reducers.js b/src/Annotator/reducers/combine-reducers.js deleted file mode 100644 index d3045d16..00000000 --- a/src/Annotator/reducers/combine-reducers.js +++ /dev/null @@ -1,7 +0,0 @@ -export default (...reducers) => - (state, action) => { - for (const reducer of reducers) { - state = reducer(state, action) - } - return state - } diff --git a/src/Annotator/reducers/combine-reducers.ts b/src/Annotator/reducers/combine-reducers.ts new file mode 100644 index 00000000..62580787 --- /dev/null +++ b/src/Annotator/reducers/combine-reducers.ts @@ -0,0 +1,11 @@ +import { Action, MainLayoutStateBase } from "../../MainLayout/types.ts"; + +export default ( + ...reducers: ((state: T, action: Action) => T)[] + ) => + (state: T, action: Action) => { + for (const reducer of reducers) { + state = reducer(state, action); + } + return state; + }; diff --git a/src/Annotator/reducers/convert-expanding-line-to-polygon.js b/src/Annotator/reducers/convert-expanding-line-to-polygon.js deleted file mode 100644 index c72a041b..00000000 --- a/src/Annotator/reducers/convert-expanding-line-to-polygon.js +++ /dev/null @@ -1,53 +0,0 @@ -// @flow - -function clamp(num, min, max) { - return num <= min ? min : num >= max ? max : num -} - -export default (expandingLine) => { - const expandingWidth = expandingLine.expandingWidth || 0.005 - const pointPairs = expandingLine.points.map(({ x, y, angle, width }, i) => { - if (!angle) { - const n = - expandingLine.points[clamp(i + 1, 0, expandingLine.points.length - 1)] - const p = - expandingLine.points[clamp(i - 1, 0, expandingLine.points.length - 1)] - angle = Math.atan2(p.x - n.x, p.y - n.y) + Math.PI / 2 - } - const dx = (Math.sin(angle) * (width || expandingWidth)) / 2 - const dy = (Math.cos(angle) * (width || expandingWidth)) / 2 - return [ - { x: x + dx, y: y + dy }, - { x: x - dx, y: y - dy }, - ] - }) - const firstSection = pointPairs.map(([p1, p2]) => p1) - const secondSection = pointPairs.map(([p1, p2]) => p2).asMutable() - secondSection.reverse() - - const newPoints = firstSection.concat(secondSection).map(({ x, y }) => [x, y]) - - return { - ...expandingLine, - type: "polygon", - open: false, - points: newPoints, - unfinished: undefined, - candidatePoint: undefined, - } - - // let { expandingWidth = 0.005, points } = region - // expandingWidth = points.slice(-1)[0].width || expandingWidth - // const lastPoint = points.slice(-1)[0] - // return ( - // <> - // `${p.x * iw} ${p.y * ih}`) - // .join(" ")} - // return { - // ...expandingLine, - // unfinished: undefined, - // candidatePoint: undefined, - // } -} diff --git a/src/Annotator/reducers/convert-expanding-line-to-polygon.ts b/src/Annotator/reducers/convert-expanding-line-to-polygon.ts new file mode 100644 index 00000000..bde1b716 --- /dev/null +++ b/src/Annotator/reducers/convert-expanding-line-to-polygon.ts @@ -0,0 +1,39 @@ + + +import { clamp } from "../../utils/clamp.ts"; +import { ExpandingLine } from "../../types/region-tools.ts"; + +export default (expandingLine: ExpandingLine) => { + const expandingWidth = expandingLine.expandingWidth || 0.005; + const pointPairs = expandingLine.points.map(({ x, y, angle, width }, i) => { + if (!angle) { + const n = + expandingLine.points[clamp(i + 1, 0, expandingLine.points.length - 1)]; + const p = + expandingLine.points[clamp(i - 1, 0, expandingLine.points.length - 1)]; + angle = Math.atan2(p.x - n.x, p.y - n.y) + Math.PI / 2; + } + const dx = (Math.sin(angle) * (width || expandingWidth)) / 2; + const dy = (Math.cos(angle) * (width || expandingWidth)) / 2; + return [ + { x: x + dx, y: y + dy }, + { x: x - dx, y: y - dy }, + ]; + }); + const firstSection = pointPairs.map(([p1]) => p1); + const secondSection = pointPairs.map(([_, p2]) => p2); + secondSection.reverse(); + + const newPoints = firstSection + .concat(secondSection) + .map(({ x, y }) => [x, y]); + + return { + ...expandingLine, + type: "polygon", + open: false, + points: newPoints, + unfinished: undefined, + candidatePoint: undefined, + }; +}; diff --git a/src/Annotator/reducers/fix-twisted.js b/src/Annotator/reducers/fix-twisted.js deleted file mode 100644 index 60c2af38..00000000 --- a/src/Annotator/reducers/fix-twisted.js +++ /dev/null @@ -1,6 +0,0 @@ -// @flow - -export default (pointsWithAngles) => { - // Adjacent angles should not have an angular distance of more than Math.PI - return pointsWithAngles -} diff --git a/src/Annotator/reducers/fix-twisted.ts b/src/Annotator/reducers/fix-twisted.ts new file mode 100644 index 00000000..cfbf16cd --- /dev/null +++ b/src/Annotator/reducers/fix-twisted.ts @@ -0,0 +1,8 @@ + + +import { ExpandingLine } from "../../types/region-tools.ts"; + +export default (pointsWithAngles: ExpandingLine["points"]) => { + // Adjacent angles should not have an angular distance of more than Math.PI + return pointsWithAngles; +}; diff --git a/src/Annotator/reducers/general-reducer.js b/src/Annotator/reducers/general-reducer.js deleted file mode 100644 index 290db057..00000000 --- a/src/Annotator/reducers/general-reducer.js +++ /dev/null @@ -1,914 +0,0 @@ -// @flow -import type { MainLayoutState, Action } from "../../MainLayout/types" -import { moveRegion } from "../../ImageCanvas/region-tools.js" -import { getIn, setIn, updateIn } from "seamless-immutable" -import moment from "moment" -import isEqual from "lodash/isEqual" -import getActiveImage from "./get-active-image" -import { saveToHistory } from "./history-handler.js" -import colors from "../../colors" -import fixTwisted from "./fix-twisted" -import convertExpandingLineToPolygon from "./convert-expanding-line-to-polygon" -import clamp from "clamp" -import getLandmarksWithTransform from "../../utils/get-landmarks-with-transform" -import setInLocalStorage from "../../utils/set-in-local-storage" - -const getRandomId = () => Math.random().toString().split(".")[1] - -export default (state: MainLayoutState, action: Action) => { - if ( - state.allowedArea && - state.selectedTool !== "modify-allowed-area" && - ["MOUSE_DOWN", "MOUSE_UP", "MOUSE_MOVE"].includes(action.type) - ) { - const aa = state.allowedArea - action.x = clamp(action.x, aa.x, aa.x + aa.w) - action.y = clamp(action.y, aa.y, aa.y + aa.h) - } - - if (action.type === "ON_CLS_ADDED" && action.cls && action.cls !== "") { - const oldRegionClsList = state.regionClsList - const newState = { - ...state, - regionClsList: oldRegionClsList.concat(action.cls), - } - return newState - } - - // Throttle certain actions - if (action.type === "MOUSE_MOVE") { - if (Date.now() - ((state: any).lastMouseMoveCall || 0) < 16) return state - state = setIn(state, ["lastMouseMoveCall"], Date.now()) - } - if (!action.type.includes("MOUSE")) { - state = setIn(state, ["lastAction"], action) - } - - const { currentImageIndex, pathToActiveImage, activeImage } = - getActiveImage(state) - - const getRegionIndex = (region) => { - const regionId = - typeof region === "string" || typeof region === "number" - ? region - : region.id - if (!activeImage) return null - const regionIndex = (activeImage.regions || []).findIndex( - (r) => r.id === regionId - ) - return regionIndex === -1 ? null : regionIndex - } - const getRegion = (regionId) => { - if (!activeImage) return null - const regionIndex = getRegionIndex(regionId) - if (regionIndex === null) return [null, null] - const region = activeImage.regions[regionIndex] - return [region, regionIndex] - } - const modifyRegion = (regionId, obj) => { - const [region, regionIndex] = getRegion(regionId) - if (!region) return state - if (obj !== null) { - return setIn(state, [...pathToActiveImage, "regions", regionIndex], { - ...region, - ...obj, - }) - } else { - // delete region - const regions = activeImage.regions - return setIn( - state, - [...pathToActiveImage, "regions"], - (regions || []).filter((r) => r.id !== region.id) - ) - } - } - const unselectRegions = (state: MainLayoutState) => { - if (!activeImage) return state - return setIn( - state, - [...pathToActiveImage, "regions"], - (activeImage.regions || []).map((r) => ({ - ...r, - highlighted: false, - })) - ) - } - - const closeEditors = (state: MainLayoutState) => { - if (currentImageIndex === null) return state - return setIn( - state, - [...pathToActiveImage, "regions"], - (activeImage.regions || []).map((r) => ({ - ...r, - editingLabels: false, - })) - ) - } - - const setNewImage = (img: string | Object, index: number) => { - let { src, frameTime } = typeof img === "object" ? img : { src: img } - return setIn( - setIn(state, ["selectedImage"], index), - ["selectedImageFrameTime"], - frameTime - ) - } - - switch (action.type) { - case "@@INIT": { - return state - } - case "SELECT_IMAGE": { - return setNewImage(action.image, action.imageIndex) - } - case "SELECT_CLASSIFICATION": { - return setIn(state, ["selectedCls"], action.cls) - } - case "CHANGE_REGION": { - const regionIndex = getRegionIndex(action.region) - if (regionIndex === null) return state - const oldRegion = activeImage.regions[regionIndex] - if (oldRegion.cls !== action.region.cls) { - state = saveToHistory(state, "Change Region Classification") - const clsIndex = state.regionClsList.indexOf(action.region.cls) - if (clsIndex !== -1) { - state = setIn(state, ["selectedCls"], action.region.cls) - action.region.color = colors[clsIndex % colors.length] - } - } - if (!isEqual(oldRegion.tags, action.region.tags)) { - state = saveToHistory(state, "Change Region Tags") - } - if (!isEqual(oldRegion.comment, action.region.comment)) { - state = saveToHistory(state, "Change Region Comment") - } - return setIn( - state, - [...pathToActiveImage, "regions", regionIndex], - action.region - ) - } - case "CHANGE_IMAGE": { - if (!activeImage) return state - const { delta } = action - for (const key of Object.keys(delta)) { - if (key === "cls") saveToHistory(state, "Change Image Class") - if (key === "tags") saveToHistory(state, "Change Image Tags") - state = setIn(state, [...pathToActiveImage, key], delta[key]) - } - return state - } - case "SELECT_REGION": { - const { region } = action - const regionIndex = getRegionIndex(action.region) - if (regionIndex === null) return state - const regions = [...(activeImage.regions || [])].map((r) => ({ - ...r, - highlighted: r.id === region.id, - editingLabels: r.id === region.id, - })) - return setIn(state, [...pathToActiveImage, "regions"], regions) - } - case "BEGIN_MOVE_POINT": { - state = closeEditors(state) - return setIn(state, ["mode"], { - mode: "MOVE_REGION", - regionId: action.point.id, - }) - } - case "BEGIN_BOX_TRANSFORM": { - const { box, directions } = action - state = closeEditors(state) - if (directions[0] === 0 && directions[1] === 0) { - return setIn(state, ["mode"], { mode: "MOVE_REGION", regionId: box.id }) - } else { - return setIn(state, ["mode"], { - mode: "RESIZE_BOX", - regionId: box.id, - freedom: directions, - original: { x: box.x, y: box.y, w: box.w, h: box.h }, - }) - } - } - case "BEGIN_MOVE_POLYGON_POINT": { - const { polygon, pointIndex } = action - state = closeEditors(state) - if ( - state.mode && - state.mode.mode === "DRAW_POLYGON" && - pointIndex === 0 - ) { - return setIn( - modifyRegion(polygon, { - points: polygon.points.slice(0, -1), - open: false, - }), - ["mode"], - null - ) - } else { - state = saveToHistory(state, "Move Polygon Point") - } - return setIn(state, ["mode"], { - mode: "MOVE_POLYGON_POINT", - regionId: polygon.id, - pointIndex, - }) - } - case "BEGIN_MOVE_KEYPOINT": { - const { region, keypointId } = action - state = closeEditors(state) - state = saveToHistory(state, "Move Keypoint") - return setIn(state, ["mode"], { - mode: "MOVE_KEYPOINT", - regionId: region.id, - keypointId, - }) - } - case "ADD_POLYGON_POINT": { - const { polygon, point, pointIndex } = action - const regionIndex = getRegionIndex(polygon) - if (regionIndex === null) return state - const points = [...polygon.points] - points.splice(pointIndex, 0, point) - return setIn(state, [...pathToActiveImage, "regions", regionIndex], { - ...polygon, - points, - }) - } - case "MOUSE_MOVE": { - const { x, y } = action - - if (!state.mode) return state - if (!activeImage) return state - const { mouseDownAt } = state - switch (state.mode.mode) { - case "MOVE_POLYGON_POINT": { - const { pointIndex, regionId } = state.mode - const regionIndex = getRegionIndex(regionId) - if (regionIndex === null) return state - return setIn( - state, - [ - ...pathToActiveImage, - "regions", - regionIndex, - "points", - pointIndex, - ], - [x, y] - ) - } - case "MOVE_KEYPOINT": { - const { keypointId, regionId } = state.mode - const [region, regionIndex] = getRegion(regionId) - if (regionIndex === null) return state - return setIn( - state, - [ - ...pathToActiveImage, - "regions", - regionIndex, - "points", - keypointId, - ], - { ...(region: any).points[keypointId], x, y } - ) - } - case "MOVE_REGION": { - const { regionId } = state.mode - if (regionId === "$$allowed_area") { - const { - allowedArea: { w, h }, - } = state - return setIn(state, ["allowedArea"], { - x: x - w / 2, - y: y - h / 2, - w, - h, - }) - } - const regionIndex = getRegionIndex(regionId) - if (regionIndex === null) return state - return setIn( - state, - [...pathToActiveImage, "regions", regionIndex], - moveRegion(activeImage.regions[regionIndex], x, y) - ) - } - case "RESIZE_BOX": { - const { - regionId, - freedom: [xFree, yFree], - original: { x: ox, y: oy, w: ow, h: oh }, - } = state.mode - - const dx = xFree === 0 ? ox : xFree === -1 ? Math.min(ox + ow, x) : ox - const dw = - xFree === 0 - ? ow - : xFree === -1 - ? ow + (ox - dx) - : Math.max(0, ow + (x - ox - ow)) - const dy = yFree === 0 ? oy : yFree === -1 ? Math.min(oy + oh, y) : oy - const dh = - yFree === 0 - ? oh - : yFree === -1 - ? oh + (oy - dy) - : Math.max(0, oh + (y - oy - oh)) - - // determine if we should switch the freedom - if (dw <= 0.001) { - state = setIn(state, ["mode", "freedom"], [xFree * -1, yFree]) - } - if (dh <= 0.001) { - state = setIn(state, ["mode", "freedom"], [xFree, yFree * -1]) - } - - if (regionId === "$$allowed_area") { - return setIn(state, ["allowedArea"], { - x: dx, - w: dw, - y: dy, - h: dh, - }) - } - - const regionIndex = getRegionIndex(regionId) - if (regionIndex === null) return state - const box = activeImage.regions[regionIndex] - - return setIn(state, [...pathToActiveImage, "regions", regionIndex], { - ...box, - x: dx, - w: dw, - y: dy, - h: dh, - }) - } - case "RESIZE_KEYPOINTS": { - const { regionId, landmarks, centerX, centerY } = state.mode - const distFromCenter = Math.sqrt( - (centerX - x) ** 2 + (centerY - y) ** 2 - ) - const scale = distFromCenter / 0.15 - return modifyRegion(regionId, { - points: getLandmarksWithTransform({ - landmarks, - center: { x: centerX, y: centerY }, - scale, - }), - }) - } - case "DRAW_POLYGON": { - const { regionId } = state.mode - const [region, regionIndex] = getRegion(regionId) - if (!region) return setIn(state, ["mode"], null) - return setIn( - state, - [ - ...pathToActiveImage, - "regions", - regionIndex, - "points", - (region: any).points.length - 1, - ], - [x, y] - ) - } - case "DRAW_LINE": { - const { regionId } = state.mode - const [region, regionIndex] = getRegion(regionId) - if (!region) return setIn(state, ["mode"], null) - return setIn(state, [...pathToActiveImage, "regions", regionIndex], { - ...region, - x2: x, - y2: y, - }) - } - case "DRAW_EXPANDING_LINE": { - const { regionId } = state.mode - const [expandingLine, regionIndex] = getRegion(regionId) - if (!expandingLine) return state - const isMouseDown = Boolean(state.mouseDownAt) - if (isMouseDown) { - // If the mouse is down, set width/angle - const lastPoint = expandingLine.points.slice(-1)[0] - const mouseDistFromLastPoint = Math.sqrt( - (lastPoint.x - x) ** 2 + (lastPoint.y - y) ** 2 - ) - if (mouseDistFromLastPoint < 0.002 && !lastPoint.width) return state - - const newState = setIn( - state, - [...pathToActiveImage, "regions", regionIndex, "points"], - expandingLine.points.slice(0, -1).concat([ - { - ...lastPoint, - width: mouseDistFromLastPoint * 2, - angle: Math.atan2(lastPoint.x - x, lastPoint.y - y), - }, - ]) - ) - return newState - } else { - // If mouse is up, move the next candidate point - return setIn( - state, - [...pathToActiveImage, "regions", regionIndex], - { - ...expandingLine, - candidatePoint: { x, y }, - } - ) - } - - return state - } - case "SET_EXPANDING_LINE_WIDTH": { - const { regionId } = state.mode - const [expandingLine, regionIndex] = getRegion(regionId) - if (!expandingLine) return state - const lastPoint = expandingLine.points.slice(-1)[0] - const { mouseDownAt } = state - return setIn( - state, - [...pathToActiveImage, "regions", regionIndex, "expandingWidth"], - Math.sqrt((lastPoint.x - x) ** 2 + (lastPoint.y - y) ** 2) - ) - } - default: - return state - } - } - case "MOUSE_DOWN": { - if (!activeImage) return state - const { x, y } = action - - state = setIn(state, ["mouseDownAt"], { x, y }) - - if (state.mode) { - switch (state.mode.mode) { - case "DRAW_POLYGON": { - const [polygon, regionIndex] = getRegion(state.mode.regionId) - if (!polygon) break - return setIn( - state, - [...pathToActiveImage, "regions", regionIndex], - { ...polygon, points: polygon.points.concat([[x, y]]) } - ) - } - case "DRAW_LINE": { - const [line, regionIndex] = getRegion(state.mode.regionId) - if (!line) break - setIn(state, [...pathToActiveImage, "regions", regionIndex], { - ...line, - x2: x, - y2: y, - }) - return setIn(state, ["mode"], null) - } - case "DRAW_EXPANDING_LINE": { - const [expandingLine, regionIndex] = getRegion(state.mode.regionId) - if (!expandingLine) break - const lastPoint = expandingLine.points.slice(-1)[0] - if ( - expandingLine.points.length > 1 && - Math.sqrt((lastPoint.x - x) ** 2 + (lastPoint.y - y) ** 2) < 0.002 - ) { - if (!lastPoint.width) { - return setIn(state, ["mode"], { - mode: "SET_EXPANDING_LINE_WIDTH", - regionId: state.mode.regionId, - }) - } else { - return state - .setIn( - [...pathToActiveImage, "regions", regionIndex], - convertExpandingLineToPolygon(expandingLine) - ) - .setIn(["mode"], null) - } - } - - // Create new point - return setIn( - state, - [...pathToActiveImage, "regions", regionIndex, "points"], - expandingLine.points.concat([{ x, y, angle: null, width: null }]) - ) - } - case "SET_EXPANDING_LINE_WIDTH": { - const [expandingLine, regionIndex] = getRegion(state.mode.regionId) - if (!expandingLine) break - const { expandingWidth } = expandingLine - return state - .setIn( - [...pathToActiveImage, "regions", regionIndex], - convertExpandingLineToPolygon({ - ...expandingLine, - points: expandingLine.points.map((p) => - p.width ? p : { ...p, width: expandingWidth } - ), - expandingWidth: undefined, - }) - ) - .setIn(["mode"], null) - } - default: - break - } - } - - let newRegion - let defaultRegionCls = state.selectedCls, - defaultRegionColor = "#ff0000" - - const clsIndex = (state.regionClsList || []).indexOf(defaultRegionCls) - if (clsIndex !== -1) { - defaultRegionColor = colors[clsIndex % colors.length] - } - - switch (state.selectedTool) { - case "create-point": { - state = saveToHistory(state, "Create Point") - newRegion = { - type: "point", - x, - y, - highlighted: true, - editingLabels: true, - color: defaultRegionColor, - id: getRandomId(), - cls: defaultRegionCls, - } - break - } - case "create-box": { - state = saveToHistory(state, "Create Box") - newRegion = { - type: "box", - x: x, - y: y, - w: 0, - h: 0, - highlighted: true, - editingLabels: false, - color: defaultRegionColor, - cls: defaultRegionCls, - id: getRandomId(), - } - state = setIn(state, ["mode"], { - mode: "RESIZE_BOX", - editLabelEditorAfter: true, - regionId: newRegion.id, - freedom: [1, 1], - original: { x, y, w: newRegion.w, h: newRegion.h }, - isNew: true, - }) - break - } - case "create-polygon": { - if (state.mode && state.mode.mode === "DRAW_POLYGON") break - state = saveToHistory(state, "Create Polygon") - newRegion = { - type: "polygon", - points: [ - [x, y], - [x, y], - ], - open: true, - highlighted: true, - color: defaultRegionColor, - cls: defaultRegionCls, - id: getRandomId(), - } - state = setIn(state, ["mode"], { - mode: "DRAW_POLYGON", - regionId: newRegion.id, - }) - break - } - case "create-expanding-line": { - state = saveToHistory(state, "Create Expanding Line") - newRegion = { - type: "expanding-line", - unfinished: true, - points: [{ x, y, angle: null, width: null }], - open: true, - highlighted: true, - color: defaultRegionColor, - cls: defaultRegionCls, - id: getRandomId(), - } - state = setIn(state, ["mode"], { - mode: "DRAW_EXPANDING_LINE", - regionId: newRegion.id, - }) - break - } - case "create-line": { - if (state.mode && state.mode.mode === "DRAW_LINE") break - state = saveToHistory(state, "Create Line") - newRegion = { - type: "line", - x1: x, - y1: y, - x2: x, - y2: y, - highlighted: true, - editingLabels: false, - color: defaultRegionColor, - cls: defaultRegionCls, - id: getRandomId(), - } - state = setIn(state, ["mode"], { - mode: "DRAW_LINE", - regionId: newRegion.id, - }) - break - } - case "create-keypoints": { - state = saveToHistory(state, "Create Keypoints") - const [[keypointsDefinitionId, { landmarks, connections }]] = - (Object.entries(state.keypointDefinitions): any) - - newRegion = { - type: "keypoints", - keypointsDefinitionId, - points: getLandmarksWithTransform({ - landmarks, - center: { x, y }, - scale: 1, - }), - highlighted: true, - editingLabels: false, - id: getRandomId(), - } - state = setIn(state, ["mode"], { - mode: "RESIZE_KEYPOINTS", - landmarks, - centerX: x, - centerY: y, - regionId: newRegion.id, - isNew: true, - }) - break - } - default: - break - } - - const regions = [...(getIn(state, pathToActiveImage).regions || [])] - .map((r) => - setIn(r, ["editingLabels"], false).setIn(["highlighted"], false) - ) - .concat(newRegion ? [newRegion] : []) - - return setIn(state, [...pathToActiveImage, "regions"], regions) - } - case "MOUSE_UP": { - const { x, y } = action - - const { mouseDownAt = { x, y } } = state - if (!state.mode) return state - state = setIn(state, ["mouseDownAt"], null) - switch (state.mode.mode) { - case "RESIZE_BOX": { - if (state.mode.isNew) { - if ( - Math.abs(state.mode.original.x - x) < 0.002 || - Math.abs(state.mode.original.y - y) < 0.002 - ) { - return setIn( - modifyRegion(state.mode.regionId, null), - ["mode"], - null - ) - } - } - if (state.mode.editLabelEditorAfter) { - return { - ...modifyRegion(state.mode.regionId, { editingLabels: true }), - mode: null, - } - } - } - case "MOVE_REGION": - case "RESIZE_KEYPOINTS": - case "MOVE_POLYGON_POINT": { - return { ...state, mode: null } - } - case "MOVE_KEYPOINT": { - return { ...state, mode: null } - } - case "CREATE_POINT_LINE": { - return state - } - case "DRAW_EXPANDING_LINE": { - const [expandingLine, regionIndex] = getRegion(state.mode.regionId) - if (!expandingLine) return state - let newExpandingLine = expandingLine - const lastPoint = - expandingLine.points.length !== 0 - ? expandingLine.points.slice(-1)[0] - : mouseDownAt - let jointStart - if (expandingLine.points.length > 1) { - jointStart = expandingLine.points.slice(-2)[0] - } else { - jointStart = lastPoint - } - const mouseDistFromLastPoint = Math.sqrt( - (lastPoint.x - x) ** 2 + (lastPoint.y - y) ** 2 - ) - if (mouseDistFromLastPoint > 0.002) { - // The user is drawing has drawn the width for the last point - const newPoints = [...expandingLine.points] - for (let i = 0; i < newPoints.length - 1; i++) { - if (newPoints[i].width) continue - newPoints[i] = { - ...newPoints[i], - width: lastPoint.width, - } - } - newExpandingLine = setIn( - expandingLine, - ["points"], - fixTwisted(newPoints) - ) - } else { - return state - } - return setIn( - state, - [...pathToActiveImage, "regions", regionIndex], - newExpandingLine - ) - } - default: - return state - } - } - case "OPEN_REGION_EDITOR": { - const { region } = action - const regionIndex = getRegionIndex(action.region) - if (regionIndex === null) return state - const newRegions = setIn( - activeImage.regions.map((r) => ({ - ...r, - highlighted: false, - editingLabels: false, - })), - [regionIndex], - { - ...(activeImage.regions || [])[regionIndex], - highlighted: true, - editingLabels: true, - } - ) - return setIn(state, [...pathToActiveImage, "regions"], newRegions) - } - case "CLOSE_REGION_EDITOR": { - const { region } = action - const regionIndex = getRegionIndex(action.region) - if (regionIndex === null) return state - return setIn(state, [...pathToActiveImage, "regions", regionIndex], { - ...(activeImage.regions || [])[regionIndex], - editingLabels: false, - }) - } - case "DELETE_REGION": { - const regionIndex = getRegionIndex(action.region) - if (regionIndex === null) return state - return setIn( - state, - [...pathToActiveImage, "regions"], - (activeImage.regions || []).filter((r) => r.id !== action.region.id) - ) - } - case "DELETE_SELECTED_REGION": { - return setIn( - state, - [...pathToActiveImage, "regions"], - (activeImage.regions || []).filter((r) => !r.highlighted) - ) - } - case "HEADER_BUTTON_CLICKED": { - const buttonName = action.buttonName.toLowerCase() - switch (buttonName) { - case "prev": { - if (currentImageIndex === null) return state - if (currentImageIndex === 0) return state - return setNewImage( - state.images[currentImageIndex - 1], - currentImageIndex - 1 - ) - } - case "next": { - if (currentImageIndex === null) return state - if (currentImageIndex === state.images.length - 1) return state - return setNewImage( - state.images[currentImageIndex + 1], - currentImageIndex + 1 - ) - } - case "clone": { - if (currentImageIndex === null) return state - if (currentImageIndex === state.images.length - 1) return state - return setIn( - setNewImage( - state.images[currentImageIndex + 1], - currentImageIndex + 1 - ), - ["images", currentImageIndex + 1, "regions"], - activeImage.regions - ) - } - case "settings": { - return setIn(state, ["settingsOpen"], !state.settingsOpen) - } - case "help": { - return state - } - case "fullscreen": { - return setIn(state, ["fullScreen"], true) - } - case "exit fullscreen": - case "window": { - return setIn(state, ["fullScreen"], false) - } - case "hotkeys": { - return state - } - case "exit": - case "done": { - return state - } - default: - return state - } - } - case "SELECT_TOOL": { - if (action.selectedTool === "show-tags") { - setInLocalStorage("showTags", !state.showTags) - return setIn(state, ["showTags"], !state.showTags) - } else if (action.selectedTool === "show-mask") { - return setIn(state, ["showMask"], !state.showMask) - } - if (action.selectedTool === "modify-allowed-area" && !state.allowedArea) { - state = setIn(state, ["allowedArea"], { x: 0, y: 0, w: 1, h: 1 }) - } - state = setIn(state, ["mode"], null) - return setIn(state, ["selectedTool"], action.selectedTool) - } - case "CANCEL": { - const { mode } = state - if (mode) { - switch (mode.mode) { - case "DRAW_EXPANDING_LINE": - case "SET_EXPANDING_LINE_WIDTH": - case "DRAW_POLYGON": { - const { regionId } = mode - return modifyRegion(regionId, null) - } - case "MOVE_POLYGON_POINT": - case "RESIZE_BOX": - case "MOVE_REGION": { - return setIn(state, ["mode"], null) - } - default: - return state - } - } - // Close any open boxes - const regions: any = activeImage.regions - if (regions && regions.some((r) => r.editingLabels)) { - return setIn( - state, - [...pathToActiveImage, "regions"], - regions.map((r) => ({ - ...r, - editingLabels: false, - })) - ) - } else if (regions) { - return setIn( - state, - [...pathToActiveImage, "regions"], - regions.map((r) => ({ - ...r, - highlighted: false, - })) - ) - } - break - } - default: - break - } - return state -} diff --git a/src/Annotator/reducers/general-reducer.ts b/src/Annotator/reducers/general-reducer.ts new file mode 100644 index 00000000..fec48318 --- /dev/null +++ b/src/Annotator/reducers/general-reducer.ts @@ -0,0 +1,1063 @@ + +import { Action, MainLayoutState } from "../../MainLayout/types.ts"; +import { ExpandingLine, moveRegion, Region } from "../../types/region-tools.ts"; +import {produce} from "immer"; +import isEqual from "lodash/isEqual"; +import get from "lodash/get"; +import set from "lodash/set"; +import getActiveImage from "./get-active-image.ts"; +import { saveToHistory } from "./history-handler.ts"; +import colors from "../../colors.ts"; +import fixTwisted from "./fix-twisted.ts"; +import convertExpandingLineToPolygon from "./convert-expanding-line-to-polygon.ts"; +import getLandmarksWithTransform from "../../utils/get-landmarks-with-transform.ts"; +import setInLocalStorage from "../../utils/set-in-local-storage.ts"; +import { clamp } from "../../utils/clamp.ts"; +import { cloneDeep } from "lodash"; + +const getRandomId = () => Math.random().toString().split(".")[1]; + +export default ( + state: T, + action: Action +): T => { + + + if ( + state.allowedArea && + state.selectedTool !== "modify-allowed-area" && + ["MOUSE_DOWN", "MOUSE_UP", "MOUSE_MOVE"].includes(action.type) && + "x" in action + ) { + const aa = state.allowedArea; + action.x = clamp(action.x, aa.x, aa.x + aa.w); + action.y = clamp(action.y, aa.y, aa.y + aa.h); + } + + if (action.type === "ON_CLS_ADDED" && !!action.cls) { + const oldRegionClsList = state.regionClsList; + const isStringRegionClsList = oldRegionClsList?.every( + (cls) => typeof cls === "string" + ); + if (!isStringRegionClsList) return state; + return { + ...state, + regionClsList: ((oldRegionClsList || []) as string[]).concat(action.cls), + }; + } + + // Throttle certain actions + if (action.type === "MOUSE_MOVE") { + if (Date.now() - ((state).lastMouseMoveCall || 0) < 16) return state + state = produce(state, s => {s.lastMouseMoveCall = Date.now()}) + } + if (!action.type.includes("MOUSE")) { + state = produce(state, s => {s.lastAction = action}) + } + + const { currentImageIndex, pathToActiveImage, activeImage } = + getActiveImage(state); + + const getRegionIndex = (region: number | string | Region) => { + const regionId = + typeof region === "string" || typeof region === "number" + ? region + : region.id; + if (!activeImage) return null; + const regionIndex = (activeImage.regions || []).findIndex( + (r) => r.id === regionId + ); + return regionIndex === -1 ? null : regionIndex; + }; + const getRegion = ( + regionId: string | number | Region + ): [Region | null, number | null] | null => { + if (!activeImage) return null; + const regionIndex = getRegionIndex(regionId); + if (regionIndex === null || !activeImage.regions) return [null, null]; + const region = activeImage.regions[regionIndex]; + return [region, regionIndex]; + }; + const modifyRegion = ( + regionId: string | number | Region, + obj: Partial | null + ): T => { + const [region, regionIndex] = getRegion(regionId) ?? [null, null]; + if (!region || regionIndex === null) return state as T; + if (obj !== null) { + return produce(state, s => {set(s, [...pathToActiveImage, "regions", regionIndex], { + ...region, + ...obj, + })}) as T; + } else { + // delete region + const regions = activeImage?.regions + return produce( + state, + s => set( + s, + [...pathToActiveImage, "regions"], + (regions || []).filter((r) => r.id !== region.id) + ) + ) as T; + } + }; + // const unselectRegions = (state: MainLayoutState) => { + // if (!activeImage) return state; + // return Immutable(state).setIn( + // [...pathToActiveImage, "regions"], + // (activeImage.regions || []).map((r) => ({ + // ...r, + // highlighted: false, + // })) + // ); + // }; + + const closeEditors = (state: MainLayoutState) => { + if (currentImageIndex === null) { + return state; + } + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions"], + (activeImage?.regions || []).map((r) => ({ + ...r, + editingLabels: false, + })) + )} + ); + }; + + const setNewImage = (index: number) => { + return produce( + state, + s => { + s.selectedImage = index + } + ) + }; + switch (action.type) { + case "@@INIT": { + return state; + } + case "SELECT_IMAGE": { + return setNewImage(action.imageIndex) as T; + } + case "SELECT_CLASSIFICATION": { + return produce(state, s => {s.selectedCls = action.cls}) as T; + } + case "CHANGE_REGION": { + const _action = cloneDeep(action); + const regionIndex = getRegionIndex(_action.region); + if (regionIndex === null) return state; + const oldRegion = activeImage?.regions?.[regionIndex]; + if (oldRegion?.cls !== _action.region.cls) { + state = saveToHistory(state, "Change Region Classification") as T; + const clsIndex = _action.region.cls + ? state.regionClsList?.findIndex((cls) => + typeof cls === "string" + ? cls === _action.region.cls + : cls.id === _action.region.cls + ) + : undefined; + + if (clsIndex !== undefined && clsIndex !== -1) { + state = produce(state, s => {s.selectedCls = _action.region.cls}) + + if (clsIndex !== -1 && state.regionClsList) { + const cls = state.regionClsList[clsIndex]; + _action.region.color = + typeof cls !== "string" + ? cls.color + : colors[clsIndex % colors.length]; + } + } + } + if (!isEqual(oldRegion?.tags, _action.region.tags)) { + state = saveToHistory(state, "Change Region Tags") as T; + } + if (!isEqual(oldRegion?.comment, _action.region.comment)) { + state = saveToHistory(state, "Change Region Comment") as T; + } + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions", regionIndex], + _action.region + )} + ); + } + case "CHANGE_IMAGE": { + if (!activeImage) return state; + const { delta } = action; + for (const key of Object.keys(delta)) { + if (key === "cls") saveToHistory(state, "Change Image Class"); + if (key === "tags") saveToHistory(state, "Change Image Tags"); + state = produce(state, s => {set(s, [...pathToActiveImage, key], delta[key as "cls" | "tags"])}) + } + return state; + } + case "SELECT_REGION": { + const { region } = action; + const regionIndex = getRegionIndex(action.region); + if (regionIndex === null) return state; + const regions = [...(activeImage?.regions || [])].map((r) => ({ + ...r, + highlighted: r.id === region.id, + editingLabels: r.id === region.id, + })); + return produce(state, s => {set(s, [...pathToActiveImage, "regions"], regions)}) + } + case "BEGIN_MOVE_POINT": { + state = closeEditors(state) as T; + return produce(state, s => {s.mode = { + mode: "MOVE_REGION", + regionId: action.point.id as string, + }}) + } + case "BEGIN_BOX_TRANSFORM": { + const { box, directions } = action; + state = closeEditors(state) as T; + if (directions[0] === 0 && directions[1] === 0) { + return produce(state, s => {s.mode = {mode: "MOVE_REGION", regionId: box.id as string}}) + } else { + return produce(state, s => {s.mode = { + mode: "RESIZE_BOX", + regionId: box.id as string, + freedom: directions, + original: {x: box.x, y: box.y, w: box.w, h: box.h}, + }}) + } + } + case "BEGIN_MOVE_POLYGON_POINT": { + const { polygon, pointIndex } = action; + state = closeEditors(state) as T; + if ( + state.mode && + state.mode.mode === "DRAW_POLYGON" && + pointIndex === 0 + ) { + return produce( + modifyRegion(polygon, { + points: polygon.points.slice(0, -1), + editingLabels: true, + open: false, + }), + s => {s.mode = null} + ) + } else { + state = saveToHistory(state, "Move Polygon Point") as T; + } + return produce(state, s => {s.mode = { + mode: "MOVE_POLYGON_POINT", + regionId: polygon.id as string, + pointIndex, + }}) + } + case "BEGIN_MOVE_KEYPOINT": { + const { region, keypointId } = action; + state = closeEditors(state) as T; + state = saveToHistory(state, "Move Keypoint") as T; + return produce(state, s => {s.mode = { + mode: "MOVE_KEYPOINT", + regionId: region.id as string, + keypointId, + }}) + } + case "ADD_POLYGON_POINT": { + const { polygon, point, pointIndex } = action; + const regionIndex = getRegionIndex(polygon); + if (regionIndex === null) return state; + const points = [...polygon.points]; + points.splice(pointIndex, 0, point); + return produce(state, s => {set(s, [...pathToActiveImage, "regions", regionIndex], { + ...polygon, + points, + })}) as T; + } + case "MOUSE_MOVE": { + const { x, y } = action; + if (!state.mode) return state; + if (!activeImage) return state; + switch (state.mode.mode) { + case "MOVE_POLYGON_POINT": { + const { pointIndex, regionId } = state.mode; + const regionIndex = getRegionIndex(regionId); + if (regionIndex === null) return state; + + return produce( + state, + s => {set(s, [ + ...pathToActiveImage, + "regions", + regionIndex, + "points", + pointIndex, + ], + [x, y] + )} + ) as T; + } + case "MOVE_KEYPOINT": { + const { keypointId, regionId } = state.mode; + const [region, regionIndex] = getRegion(regionId) || [null, null]; + if ( + region === null || + regionIndex === null || + region.type !== "keypoints" || + typeof region !== "object" || + !("points" in region) + ) + return state; + + return produce( + state, + s => {set(s, [ + ...pathToActiveImage, + "regions", + regionIndex, + "points", + keypointId, + ], + {...(region).points[keypointId], x, y} + )} + ) as T; + } + case "MOVE_REGION": { + const { regionId } = state.mode; + if (regionId === "$$allowed_area") { + const { allowedArea: { w, h } = { w: 0, h: 0 } } = state; + return produce(state, s => {s.allowedArea = { + x: x - w / 2, + y: y - h / 2, + w, + h, + }}) + } + const regionIndex = getRegionIndex(regionId); + if (regionIndex === null || !activeImage.regions) return state; + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions", regionIndex], + moveRegion(activeImage.regions![regionIndex], x, y) + )} + ) as T; + } + case "RESIZE_BOX": { + const { + regionId, + freedom: [xFree, yFree], + original: { x: ox, y: oy, w: ow, h: oh }, + } = state.mode; + + const dx = + xFree === 0 ? ox : xFree === -1 ? Math.min(ox + ow, x) : ox; + const dw = + xFree === 0 + ? ow + : xFree === -1 + ? ow + (ox - dx) + : Math.max(0, ow + (x - ox - ow)); + const dy = + yFree === 0 ? oy : yFree === -1 ? Math.min(oy + oh, y) : oy; + const dh = + yFree === 0 + ? oh + : yFree === -1 + ? oh + (oy - dy) + : Math.max(0, oh + (y - oy - oh)); + + // determine if we should switch the freedom + if (dw <= 0.001) { + state = produce(state, s => {if(s.mode?.mode === 'RESIZE_BOX') s.mode.freedom = [xFree * -1, yFree]}) as T; + } + if (dh <= 0.001) { + state = produce(state, s => { if(s.mode?.mode === 'RESIZE_BOX') s.mode!.freedom = [xFree, yFree * -1]}) as T; + } + + if (regionId === "$$allowed_area") { + return produce(state, s => {s.allowedArea = { + x: dx, + w: dw, + y: dy, + h: dh, + }}) as T; + } + + const regionIndex = getRegionIndex(regionId); + if (regionIndex === null || !activeImage.regions) return state; + const box = activeImage.regions[regionIndex]; + return produce(state, s => {set(s, [...pathToActiveImage, "regions", regionIndex], { + ...box, + x: dx, + w: dw, + y: dy, + h: dh, + })}) as T; + } + case "RESIZE_KEYPOINTS": { + const { regionId, landmarks, centerX, centerY } = state.mode; + const distFromCenter = Math.sqrt( + (centerX - x) ** 2 + (centerY - y) ** 2 + ); + const scale = distFromCenter / 0.15; + return modifyRegion(regionId, { + points: getLandmarksWithTransform({ + landmarks: landmarks, + center: { x: centerX, y: centerY }, + scale, + }), + }) as T; + } + case "DRAW_POLYGON": { + const { regionId } = state.mode; + const [region, regionIndex] = getRegion(regionId) || [null, null]; + if (!region) return produce(state, s => {s.mode = null}) as T; + if ( + typeof region !== "object" || + region.type !== "polygon" || + regionIndex === null + ) + return state; + const { points } = region; + if (!Array.isArray(points)) return state; + return produce( + state, + s => {set(s, [ + ...pathToActiveImage, + "regions", + regionIndex, + "points", + points.length - 1, + ], + [x, y] + )} + ) as T; + } + case "DRAW_LINE": { + const { regionId } = state.mode; + const [region, regionIndex] = getRegion(regionId) || [null, null]; + if (!region || typeof region !== "object" || regionIndex === null) + return produce(state, s => {s.mode = null}) as T; + return produce(state, s => {set(s, [...pathToActiveImage, "regions", regionIndex], { + ...region, + x2: x, + y2: y, + })}) as T; + } + case "DRAW_EXPANDING_LINE": { + const { regionId } = state.mode; + const [expandingLine, regionIndex] = getRegion(regionId) || [ + null, + null, + ]; + if ( + !expandingLine || + typeof expandingLine !== "object" || + expandingLine.type !== "expanding-line" || + regionIndex === null + ) + return state; + const isMouseDown = Boolean(state.mouseDownAt); + if (isMouseDown) { + // If the mouse is down, set width/angle + const lastPoint = expandingLine.points.slice(-1)[0]; + const mouseDistFromLastPoint = Math.sqrt( + (lastPoint.x - x) ** 2 + (lastPoint.y - y) ** 2 + ); + if (mouseDistFromLastPoint < 0.002 && !lastPoint.width) + return state; + + const newState = produce( + state, + s => {set(s, + [...pathToActiveImage, "regions", regionIndex, "points"], + expandingLine.points.slice(0, -1).concat([ + { + ...lastPoint, + width: mouseDistFromLastPoint * 2, + angle: Math.atan2(lastPoint.x - x, lastPoint.y - y), + }, + ]) + )} + ); + + return newState as T; + } + // If mouse is up, move the next candidate point + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions", regionIndex], + { + ...expandingLine, + candidatePoint: {x, y}, + } + )} + ) as T; + } + case "SET_EXPANDING_LINE_WIDTH": { + const { regionId } = state.mode; + const [expandingLine, regionIndex] = getRegion(regionId) || [ + null, + null, + ]; + if ( + regionIndex === null || + !expandingLine || + typeof expandingLine !== "object" || + expandingLine.type !== "expanding-line" + ) + return state; + const lastPoint = expandingLine.points.slice(-1)[0]; + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions", regionIndex, "expandingWidth"], + Math.sqrt((lastPoint.x - x) ** 2 + (lastPoint.y - y) ** 2) + )} + ) as T; + } + default: + return state; + } + } + case "MOUSE_DOWN": { + if (!activeImage) return state; + const { x, y } = action; + + state = produce(state, s => {s.mouseDownAt = {x, y}}) as T; + + if (state.mode) { + switch (state.mode.mode) { + case "DRAW_POLYGON": { + const [polygon, regionIndex] = getRegion(state.mode.regionId) || [ + null, + null, + ]; + if ( + regionIndex === null || + !polygon || + typeof polygon !== "object" || + polygon.type !== "polygon" + ) + break; + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions", regionIndex], + {...polygon, points: polygon.points.concat([[x, y]])} + )} + ) as T; + } + case "DRAW_LINE": { + const [line, regionIndex] = getRegion(state.mode.regionId) || [ + null, + null, + ]; + if (!line || typeof line !== "object" || regionIndex === null) + break; + const newState = produce(state, s => {set(s, [...pathToActiveImage, "regions", regionIndex], {...line, x2: x, y2: y})}); + return produce(newState, s => {s.mode = null}) as T; + } + case "DRAW_EXPANDING_LINE": { + const [expandingLine, regionIndex] = getRegion( + state.mode.regionId + ) || [null, null]; + if ( + regionIndex === null || + !expandingLine || + typeof expandingLine !== "object" || + expandingLine.type !== "expanding-line" + ) + break; + const lastPoint = expandingLine.points.slice(-1)[0]; + if ( + expandingLine.points.length > 1 && + Math.sqrt((lastPoint.x - x) ** 2 + (lastPoint.y - y) ** 2) < 0.002 + ) { + if (!lastPoint.width) { + return produce(state, s => { + s.mode = { + mode: "SET_EXPANDING_LINE_WIDTH", + regionId: state.mode?.mode !== 'CREATE_POINT_LINE' ? state.mode!.regionId : '' + }}) as T; + + } else { + return produce(state, s => { + set(s, + [...pathToActiveImage, "regions", regionIndex], + convertExpandingLineToPolygon(expandingLine) + ) + s.mode = null + }) as T; + } + } + + // Create new point + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions", regionIndex, "points"], + expandingLine.points.concat([{x, y, angle: null, width: null}]) + )} + ) as T; + } + case "SET_EXPANDING_LINE_WIDTH": { + const [expandingLine, regionIndex] = getRegion( + state.mode.regionId + ) || [null, null]; + if ( + regionIndex === null || + !expandingLine || + typeof expandingLine !== "object" || + expandingLine.type !== "expanding-line" + ) + break; + const { expandingWidth } = expandingLine; + return produce(state, s => { + set(s, + [...pathToActiveImage, "regions", regionIndex], + convertExpandingLineToPolygon({ + ...expandingLine, + points: expandingLine.points.map((p) => + p.width ? p : {...p, width: expandingWidth || null} + ), + expandingWidth: undefined, + }) + ) + s.mode = null + }) as T; + } + default: + break; + } + } + + let newRegion; + let defaultRegionCls = state.selectedCls; + let defaultRegionColor = "#ff0000"; + console.debug(defaultRegionColor); + const clsIndex = + defaultRegionCls && state.regionClsList + ? state.regionClsList.findIndex((cls) => + typeof cls === "string" + ? cls === defaultRegionCls + : cls.id === defaultRegionCls + ) + : -1; + + if (clsIndex !== -1 && defaultRegionCls && state.regionClsList) { + const cls = state.regionClsList[clsIndex]; + defaultRegionColor = + typeof cls !== "string" + ? cls.color + : colors[clsIndex % colors.length]; + } + switch (state.selectedTool) { + case "create-point": { + state = saveToHistory(state, "Create Point") as T; + newRegion = { + // @ts-ignore + type: "point", + x, + y, + highlighted: true, + editingLabels: true, + color: defaultRegionColor, + id: getRandomId(), + cls: defaultRegionCls, + }; + break; + } + case "create-box": { + state = saveToHistory(state, "Create Box") as T; + newRegion = { + type: "box", + x: x, + y: y, + w: 0, + h: 0, + highlighted: true, + editingLabels: false, + color: defaultRegionColor, + cls: defaultRegionCls, + id: getRandomId(), + }; + state = produce(state, s => {s.mode = { + mode: "RESIZE_BOX", + editLabelEditorAfter: true, + regionId: newRegion!.id as string, + freedom: [1, 1], + original: {x, y, w: newRegion!.w, h: newRegion!.h}, + isNew: true, + }}) as T; + break; + } + case "create-polygon": { + if (state.mode && state.mode.mode === "DRAW_POLYGON") break; + state = saveToHistory(state, "Create Polygon") as T; + newRegion = { + type: "polygon", + points: [ + [x, y], + [x, y], + ], + open: true, + highlighted: true, + color: defaultRegionColor, + cls: defaultRegionCls, + id: getRandomId(), + }; + state = produce(state, s => {s.mode = { + mode: "DRAW_POLYGON", + regionId: newRegion!.id, + }}) as T; + break; + } + case "create-expanding-line": { + state = saveToHistory(state, "Create Expanding Line") as T; + newRegion = { + type: "expanding-line", + unfinished: true, + points: [{ x, y, angle: null, width: null }], + open: true, + highlighted: true, + color: defaultRegionColor, + cls: defaultRegionCls, + id: getRandomId(), + }; + state = produce(state, s => {s.mode = { + mode: "DRAW_EXPANDING_LINE", + regionId: newRegion!.id, + }}) as T; + break; + } + case "create-line": { + if (state.mode && state.mode.mode === "DRAW_LINE") break; + state = saveToHistory(state, "Create Line") as T; + newRegion = { + type: "line", + x1: x, + y1: y, + x2: x, + y2: y, + highlighted: true, + editingLabels: false, + color: defaultRegionColor, + cls: defaultRegionCls, + id: getRandomId(), + }; + state = produce(state, s => {s.mode = { + mode: "DRAW_LINE", + regionId: newRegion!.id, + }}) as T; + break; + } + case "create-keypoints": { + if (!state.keypointDefinitions) { + console.error("No keypoint definitions"); + return state; + } + state = saveToHistory(state, "Create Keypoints") as T; + const [[keypointsDefinitionId, { landmarks }]] = Object.entries( + state.keypointDefinitions + ); + newRegion = { + type: "keypoints", + keypointsDefinitionId, + points: getLandmarksWithTransform({ + landmarks: landmarks, + center: { x, y }, + scale: 1, + }), + highlighted: true, + editingLabels: false, + id: getRandomId(), + }; + state = produce(state, s => {s.mode = { + mode: "RESIZE_KEYPOINTS", + landmarks, + centerX: x, + centerY: y, + regionId: newRegion!.id, + isNew: true, + }}) as T; + break; + } + default: + break; + } + + const regions = [...(get(state, pathToActiveImage).regions || [])] + .map((r) => + produce(r, (d: any) => { + d.editingLabels = false + d.highlighted = false + }) + ) + .concat(newRegion ? [newRegion] : []); + + return produce(state, s => {set(s, [...pathToActiveImage, "regions"], regions)}) as T; + } + case "MOUSE_UP": { + const { x, y } = action; + + const { mouseDownAt = { x, y } } = state; + if (!state.mode) return state; + state = produce(state, s => {s!.mouseDownAt = undefined}) as T; + + switch (state.mode?.mode) { + case "RESIZE_BOX": { + if (state.mode.isNew) { + if ( + Math.abs(state.mode.original.x - x) < 0.002 || + Math.abs(state.mode.original.y - y) < 0.002 + ) { + return produce( + modifyRegion(state.mode.regionId, null), + s => {s.mode = null} + ) as T; + } + } + if (state.mode.editLabelEditorAfter) { + return { + ...modifyRegion(state.mode.regionId, { editingLabels: true }), + mode: null, + } as T; + } + return { ...state, mode: null }; + } + case "MOVE_REGION": + case "RESIZE_KEYPOINTS": + case "MOVE_POLYGON_POINT": { + return { ...state, mode: null }; + } + case "MOVE_KEYPOINT": { + return { ...state, mode: null }; + } + case "CREATE_POINT_LINE": { + return state; + } + case "DRAW_EXPANDING_LINE": { + const [expandingLine, regionIndex] = getRegion( + state.mode.regionId + ) || [null, null]; + if ( + regionIndex === null || + !expandingLine || + typeof expandingLine !== "object" || + expandingLine.type !== "expanding-line" + ) + return state; + let newExpandingLine = expandingLine; + const lastPoint = + expandingLine.points.length !== 0 + ? expandingLine.points.slice(-1)[0] + : mouseDownAt; + const mouseDistFromLastPoint = Math.sqrt( + (lastPoint.x - x) ** 2 + (lastPoint.y - y) ** 2 + ); + if (mouseDistFromLastPoint > 0.002) { + // The user is drawing has drawn the width for the last point + const newPoints = [...expandingLine.points]; + for (let i = 0; i < newPoints.length - 1; i++) { + if (newPoints[i].width) continue; + newPoints[i] = { + ...newPoints[i], + width: + "width" in lastPoint ? (lastPoint.width as number) : 0.002, + }; + } + newExpandingLine = produce( + expandingLine, + s => {s.points = fixTwisted(newPoints)} + ) as unknown as ExpandingLine; + } else { + return state; + } + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions", regionIndex], + newExpandingLine + )} + ) as T; + } + default: + return state; + } + } + case "OPEN_REGION_EDITOR": { + const regionIndex = getRegionIndex(action.region); + if (regionIndex === null || !activeImage?.regions) return state; + // @ts-ignore + const newRegions = produce( + activeImage.regions.map((r) => ({ + ...r, + highlighted: false, + editingLabels: false, + })), + s => {s[regionIndex] = { + ...(activeImage.regions || [])[regionIndex], + highlighted: true, + editingLabels: true, + }} + ); + return produce(state, s => {set(s, [...pathToActiveImage, "regions"], newRegions)}) as T; + } + case "CLOSE_REGION_EDITOR": { + const regionIndex = getRegionIndex(action.region); + if (regionIndex === null) return state; + return produce(state, s => {set(s, [...pathToActiveImage, "regions", regionIndex], { + ...(activeImage?.regions || [])[regionIndex], + editingLabels: false, + })}) as T; + } + case "DELETE_REGION": { + const regionIndex = getRegionIndex(action.region); + if (regionIndex === null) return state; + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions"], + (activeImage?.regions || []).filter((r) => r.id !== action.region.id) + )} + ) as T; + } + case "DELETE_SELECTED_REGION": { + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions"], + (activeImage?.regions || []).filter((r) => !r.highlighted) + )} + ) as T; + } + case "HEADER_BUTTON_CLICKED": { + const buttonName = action.buttonName.toLowerCase(); + switch (buttonName) { + case "prev": { + if ( + currentImageIndex === null || + !("images" in state) || + !state.images + ) + return state; + if (currentImageIndex === 0) return state; + if ("images" in state) { + return setNewImage(currentImageIndex - 1) as T; + } + return state; + } + case "next": { + if (currentImageIndex === null) return state; + if (!("images" in state)) return state; + if (currentImageIndex === state.images.length - 1) return state; + return setNewImage(+currentImageIndex + 1) as T; + } + case "clone": { + if (currentImageIndex === null) return state; + if (!("images" in state)) return state; + if (currentImageIndex === state.images.length - 1) return state; + const newState = setNewImage(+currentImageIndex + 1) as T; + + return produce( + newState, + s => {set(s, + ["images", currentImageIndex + 1, "regions"], + activeImage?.regions || [] + )} + ) as T; + } + case "settings": { + return produce(state, s => {s.settingsOpen = !state.settingsOpen}) as T; + } + case "help": { + return state; + } + case "fullscreen": { + return produce(state, s => {s.fullScreen = true}) as T; + } + case "exit fullscreen": + case "window": { + return produce(state, s => {s.fullScreen = false}) as T; + } + case "hotkeys": { + return state; + } + case "exit": + case "done": { + return state; + } + default: + return state; + } + } + case "SELECT_TOOL": { + if (action.selectedTool === "show-tags") { + setInLocalStorage("showTags", !state.showTags); + return produce(state, s => {s.showTags = !state.showTags}) as T; + } else if (action.selectedTool === "show-mask") { + return produce(state, s => {s.showMask = !state.showMask}) as T; + } + if (action.selectedTool === "modify-allowed-area" && !state.allowedArea) { + state = produce(state, s => {s.allowedArea = {x: 0, y: 0, w: 1, h: 1}}) as T; + } + state = produce(state, s => {s.mode = null}) as T; + return produce(state, s => {s.selectedTool = action.selectedTool})as T; + } + case "CANCEL": { + const { mode } = state; + if (mode) { + switch (mode.mode) { + case "DRAW_EXPANDING_LINE": + case "SET_EXPANDING_LINE_WIDTH": + case "DRAW_POLYGON": { + const { regionId } = mode; + return modifyRegion(regionId, null) as T; + } + case "MOVE_POLYGON_POINT": + case "RESIZE_BOX": + case "MOVE_REGION": { + return produce(state, s => {s.mode = null}) as T; + } + default: + return state; + } + } + // Close any open boxes + const regions = activeImage?.regions; + if (regions && regions.some((r) => r.editingLabels)) { + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions"], + regions.map((r) => ( + { + ...r, + editingLabels: false, + })) + )} + )as T; + } else if (regions) { + return produce( + state, + s => {set(s, + [...pathToActiveImage, "regions"], + regions.map((r) => ({ + ...r, + highlighted: false, + })) + )} + ) as T; + } + break; + } + default: + break; + } + return state; +}; diff --git a/src/Annotator/reducers/get-active-image.js b/src/Annotator/reducers/get-active-image.js deleted file mode 100644 index 54d54f22..00000000 --- a/src/Annotator/reducers/get-active-image.js +++ /dev/null @@ -1,21 +0,0 @@ -import { getIn } from "seamless-immutable" - -export default (state) => { - let currentImageIndex = null, - pathToActiveImage, - activeImage - if (state.annotationType === "image") { - currentImageIndex = state.selectedImage - if (currentImageIndex === -1) { - currentImageIndex = null - activeImage = null - } else { - pathToActiveImage = ["images", currentImageIndex] - activeImage = getIn(state, pathToActiveImage) - } - } else if (state.annotationType === "video") { - pathToActiveImage = ["keyframes", state.currentVideoTime || 0] - activeImage = getIn(state, pathToActiveImage) || null - } - return { currentImageIndex, pathToActiveImage, activeImage } -} diff --git a/src/Annotator/reducers/get-active-image.ts b/src/Annotator/reducers/get-active-image.ts new file mode 100644 index 00000000..e38f9d6f --- /dev/null +++ b/src/Annotator/reducers/get-active-image.ts @@ -0,0 +1,18 @@ +import { Image, MainLayoutState } from "../../MainLayout/types"; +import get from 'lodash/get'; + +export default (state: MainLayoutState) => { + let currentImageIndex: number | null = null; + let pathToActiveImage: string[] = []; + let activeImage: Image | null = null; + currentImageIndex = state.selectedImage ?? null; + if (currentImageIndex === -1 || currentImageIndex === null) { + currentImageIndex = null; + activeImage = null; + } else { + pathToActiveImage = ["images", currentImageIndex.toString()]; + activeImage = get(state, pathToActiveImage); + + } + return { currentImageIndex, pathToActiveImage, activeImage }; +}; diff --git a/src/Annotator/reducers/get-implied-video-regions.js b/src/Annotator/reducers/get-implied-video-regions.js deleted file mode 100644 index e6831d83..00000000 --- a/src/Annotator/reducers/get-implied-video-regions.js +++ /dev/null @@ -1,115 +0,0 @@ -// @flow - -import type { Region } from "../../ImageCanvas/region-tools.js" - -const emptyArr = [] - -export default ( - keyframes: { [string | number]: { regions: Array } }, - time: number -) => { - if (keyframes[time || 0]) { - return keyframes[time || 0].regions - } - // Get surrounding video keyframes - const keyframeTimes = Object.keys(keyframes) - .map((a) => parseInt(a)) - .filter((a) => !isNaN(a)) - if (keyframeTimes.length === 0) return emptyArr - keyframeTimes.sort((a, b) => a - b) - let nextKeyframeTimeIndex = keyframeTimes.findIndex((kt) => kt >= time) - if (nextKeyframeTimeIndex === -1) { - return ( - keyframes[keyframeTimes[keyframeTimes.length - 1]].regions || emptyArr - ) - } else if (nextKeyframeTimeIndex === 0) { - return emptyArr - } - - const t1 = keyframeTimes[nextKeyframeTimeIndex - 1] - const prevKeyframe = keyframes[t1] - const t2 = keyframeTimes[nextKeyframeTimeIndex] - const nextKeyframe = keyframes[t2] - - const [prevRegionMap, nextRegionMap] = [{}, {}] - for (const region of prevKeyframe.regions) prevRegionMap[region.id] = region - for (const region of nextKeyframe.regions) nextRegionMap[region.id] = region - - const impliedRegions = [] - - // Weighted time coefficients for linear transition - const w1 = (t2 - time) / (t2 - t1) - const w2 = 1 - w1 - - for (const regionId in prevRegionMap) { - const [prev, next] = [prevRegionMap[regionId], nextRegionMap[regionId]] - if (!next) { - impliedRegions.push({ - ...prev, - highlighted: false, - editingLabels: false, - }) - continue - } - switch (prev.type) { - case "point": { - impliedRegions.push({ - ...prev, - highlighted: false, - editingLabels: false, - x: prev.x * w1 + next.x * w2, - y: prev.y * w1 + next.y * w2, - }) - break - } - case "box": { - impliedRegions.push({ - ...prev, - highlighted: false, - editingLabels: false, - x: prev.x * w1 + next.x * w2, - y: prev.y * w1 + next.y * w2, - w: prev.w * w1 + next.w * w2, - h: prev.h * w1 + next.h * w2, - }) - break - } - case "polygon": { - if (next.points.length === prev.points.length) { - impliedRegions.push({ - ...prev, - highlighted: false, - editingLabels: false, - points: prev.points.map((pp, i) => [ - pp[0] * w1 + next.points[i][0] * w2, - pp[1] * w1 + next.points[i][1] * w2, - ]), - }) - } else { - impliedRegions.push(prev) - } - break - } - case "keypoints": { - const newPoints = {} - for (const [pointId, prevPoint] of Object.entries(prev.points)) { - newPoints[pointId] = { - x: prevPoint.x * w1 + next.points[pointId].x * w2, - y: prevPoint.y * w1 + next.points[pointId].y * w2, - } - } - impliedRegions.push({ - ...prev, - highlighted: false, - editingLabels: false, - points: newPoints, - }) - break - } - default: - break - } - } - - return impliedRegions -} diff --git a/src/Annotator/reducers/history-handler.js b/src/Annotator/reducers/history-handler.js deleted file mode 100644 index c14b20b6..00000000 --- a/src/Annotator/reducers/history-handler.js +++ /dev/null @@ -1,60 +0,0 @@ -// @flow - -import type { MainLayoutState, Action } from "../../MainLayout/types" -import { setIn, updateIn, asMutable, without } from "seamless-immutable" -import moment from "moment" - -const typesToSaveWithHistory = { - BEGIN_BOX_TRANSFORM: "Transform/Move Box", - BEGIN_MOVE_POINT: "Move Point", - DELETE_REGION: "Delete Region", -} - -export const saveToHistory = (state: MainLayoutState, name: string) => - updateIn(state, ["history"], (h) => - [ - { - time: moment().toDate(), - state: without(state, "history"), - name, - }, - ].concat((h || []).slice(0, 9)) - ) - -export default (reducer) => { - return (state: MainLayoutState, action: Action) => { - const prevState = state - const nextState = reducer(state, action) - - if (action.type === "RESTORE_HISTORY") { - if (state.history.length > 0) { - return setIn( - nextState.history[0].state, - ["history"], - nextState.history.slice(1) - ) - } - } else { - if ( - prevState !== nextState && - Object.keys(typesToSaveWithHistory).includes(action.type) - ) { - return setIn( - nextState, - ["history"], - [ - { - time: moment().toDate(), - state: without(prevState, "history"), - name: typesToSaveWithHistory[action.type] || action.type, - }, - ] - .concat(nextState.history || []) - .slice(0, 9) - ) - } - } - - return nextState - } -} diff --git a/src/Annotator/reducers/history-handler.ts b/src/Annotator/reducers/history-handler.ts new file mode 100644 index 00000000..7f0f6874 --- /dev/null +++ b/src/Annotator/reducers/history-handler.ts @@ -0,0 +1,67 @@ + + +import { Action, MainLayoutImageAnnotationState, MainLayoutState } from "../../MainLayout/types"; +import moment from "moment"; +import { produce } from "immer"; +import { omit } from "lodash"; + +const typesToSaveWithHistory: Record = { + BEGIN_BOX_TRANSFORM: "Transform/Move Box", + BEGIN_MOVE_POINT: "Move Point", + DELETE_REGION: "Delete Region", +}; + +export const saveToHistory = ( + state: T, + name: string +): T => produce(state, (draft) => { + const newValue = { + time: moment().toDate(), + state: { ...state, history: undefined }, + name, + }; + + const prevItems = draft.history || []; + draft.history = [newValue, ...prevItems].slice(0, 9); +}); + +export default ( + reducer: ( + state: MainLayoutState, + action: Action + ) => MainLayoutState +) => { + return (state: MainLayoutState, action: Action) => { + const prevState = state; + const nextState = reducer(state, action); + + if (action.type === "RESTORE_HISTORY") { + if (state.history.length > 0) { + const newState = produce(nextState.history[0].state, (draft) => { + draft.history = nextState.history.slice(1); + }); + return newState; + } + } else { + if ( + prevState !== nextState && + Object.keys(typesToSaveWithHistory).includes(action.type) + ) { + const historyItem = { + time: moment().toDate(), + state: omit(prevState, "history") as MainLayoutImageAnnotationState, + name: typesToSaveWithHistory[action.type] || action.type, + }; + + const nextStateWithHistory = produce(nextState, (draft) => { + const prevItems = draft.history || []; + draft.history = [historyItem, ...prevItems].slice(0, 9); + }); + + return nextStateWithHistory; + } + } + + return nextState; + }; +}; diff --git a/src/Annotator/reducers/image-reducer.js b/src/Annotator/reducers/image-reducer.js deleted file mode 100644 index 6c39e3bc..00000000 --- a/src/Annotator/reducers/image-reducer.js +++ /dev/null @@ -1,23 +0,0 @@ -// @flow - -import type { - MainLayoutImageAnnotationState, - Action, -} from "../../MainLayout/types" -import { setIn } from "seamless-immutable" -import getActiveImage from "./get-active-image" - -export default (state: MainLayoutImageAnnotationState, action: Action) => { - const { currentImageIndex, pathToActiveImage, activeImage } = - getActiveImage(state) - - switch (action.type) { - case "IMAGE_OR_VIDEO_LOADED": { - return setIn(state, ["images", currentImageIndex, "pixelSize"], { - w: action.metadata.naturalWidth, - h: action.metadata.naturalHeight, - }) - } - } - return state -} diff --git a/src/Annotator/reducers/image-reducer.ts b/src/Annotator/reducers/image-reducer.ts new file mode 100644 index 00000000..99d2295f --- /dev/null +++ b/src/Annotator/reducers/image-reducer.ts @@ -0,0 +1,33 @@ + + +import type { + Action, + MainLayoutImageAnnotationState, +} from "../../MainLayout/types"; +import getActiveImage from "./get-active-image"; +import {produce} from 'immer'; + +export default ( + state: MainLayoutImageAnnotationState, + action: Action +): MainLayoutImageAnnotationState => { + const { currentImageIndex } = getActiveImage(state); + + switch (action.type) { + case "IMAGE_LOADED": { + if (!currentImageIndex) return state; + return produce(state, (draft) => { + // const idx = currentImageIndex.toString(); + const idx = currentImageIndex; + + if (!draft.images[idx]) return; + + draft.images[idx].pixelSize = { + w: action.metadata.naturalWidth, + h: action.metadata.naturalHeight, + }; + }); + } + } + return state; +}; diff --git a/src/Annotator/reducers/video-reducer.js b/src/Annotator/reducers/video-reducer.js deleted file mode 100644 index 4dea849b..00000000 --- a/src/Annotator/reducers/video-reducer.js +++ /dev/null @@ -1,85 +0,0 @@ -// @flow - -import type { - MainLayoutVideoAnnotationState, - Action, -} from "../../MainLayout/types" -import { setIn, without } from "seamless-immutable" -import getImpliedVideoRegions from "./get-implied-video-regions" -import { saveToHistory } from "./history-handler.js" - -export default (state: MainLayoutVideoAnnotationState, action: Action) => { - const copyImpliedRegions = () => { - return setIn( - saveToHistory(state, "Add Keyframe"), - ["keyframes", state.currentVideoTime || 0], - { - regions: getImpliedVideoRegions( - state.keyframes, - state.currentVideoTime - ), - } - ) - } - - switch (action.type) { - case "IMAGE_OR_VIDEO_LOADED": { - const { duration } = action.metadata - if (typeof duration === "number") { - return setIn(state, ["videoDuration"], duration * 1000) - } - } - case "HEADER_BUTTON_CLICKED": { - switch (action.buttonName.toLowerCase()) { - case "play": - return setIn(state, ["videoPlaying"], true) - case "pause": - return setIn(state, ["videoPlaying"], false) - } - } - case "CHANGE_VIDEO_TIME": { - return setIn(state, ["currentVideoTime"], action.newTime) - } - case "CHANGE_VIDEO_PLAYING": { - return setIn(state, ["videoPlaying"], action.isPlaying) - } - case "DELETE_KEYFRAME": { - return setIn(state, ["keyframes"], without(state.keyframes, action.time)) - } - default: - break - } - - // Before the user modifies regions, copy the interpolated regions over to a - // new keyframe - if (!state.keyframes[state.currentVideoTime]) { - switch (action.type) { - case "BEGIN_BOX_TRANSFORM": - case "BEGIN_MOVE_POINT": - case "BEGIN_MOVE_KEYPOINT": - case "BEGIN_MOVE_POLYGON_POINT": - case "ADD_POLYGON_POINT": - case "SELECT_REGION": - case "CHANGE_REGION": - case "DELETE_REGION": - case "OPEN_REGION_EDITOR": - return copyImpliedRegions() - case "MOUSE_DOWN": { - switch (state.selectedTool) { - case "create-point": - case "create-polygon": - case "create-box": - case "create-keypoints": - return copyImpliedRegions() - default: - break - } - break - } - default: - break - } - } - - return state -} diff --git a/src/Annotator/video.story.js b/src/Annotator/video.story.js deleted file mode 100644 index b7268757..00000000 --- a/src/Annotator/video.story.js +++ /dev/null @@ -1,51 +0,0 @@ -// @flow - -import React from "react" - -import { storiesOf } from "@storybook/react" -import { action } from "@storybook/addon-actions" -import Annotator from "./" - -storiesOf("Annotator(video)", module).add("Video Annotator", () => { - const props = { - regionClsList: ["valid", "invalid"], - enabledTools: ["select", "create-box", "create-polygon", "create-point"], - keyframes: { - 0: { - regions: [ - { - id: "910517662556203", - cls: "valid", - color: "#f44336", - type: "box", - x: 0.12195121951219515, - y: 0.28726287262872624, - w: 0.2606707317073171, - h: 0.4769647696476965, - }, - ], - }, - 2656: { - regions: [ - { - id: "910517662556203", - cls: "valid", - color: "#f44336", - type: "box", - x: 0.13109756097560976, - y: 0.08672086720867206, - w: 0.3445121951219512, - h: 0.7913279132791328, - }, - ], - }, - }, - onExit: action("onExit"), - taskDescription: "", - videoName: "", - videoTime: 0, - videoSrc: - "https://s3.amazonaws.com/asset.workaround.online/SampleVideo_1280x720_1mb.mp4", - } - return -}) diff --git a/src/ClassSelectionMenu/index.js b/src/ClassSelectionMenu/index.js deleted file mode 100644 index e584520b..00000000 --- a/src/ClassSelectionMenu/index.js +++ /dev/null @@ -1,108 +0,0 @@ -import React, { useEffect } from "react" -import { styled } from "@mui/material/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" -import Box from "@mui/material/Box" -import * as muiColors from "@mui/material/colors" -import SidebarBoxContainer from "../SidebarBoxContainer" -import colors from "../colors" -import BallotIcon from "@mui/icons-material/Ballot" -import capitalize from "lodash/capitalize" -import classnames from "classnames" - -const theme = createTheme() -const LabelContainer = styled("div")(({ theme }) => ({ - display: "flex", - paddingTop: 4, - paddingBottom: 4, - paddingLeft: 16, - paddingRight: 16, - alignItems: "center", - cursor: "pointer", - opacity: 0.7, - backgroundColor: "#fff", - "&:hover": { - opacity: 1, - }, - "&.selected": { - opacity: 1, - fontWeight: "bold", - }, -})) -const Circle = styled("div")(({ theme }) => ({ - width: 12, - height: 12, - borderRadius: 12, - marginRight: 8, -})) -const Label = styled("div")(({ theme }) => ({ - fontSize: 11, -})) -const DashSep = styled("div")(({ theme }) => ({ - flexGrow: 1, - borderBottom: `2px dotted ${muiColors.grey[300]}`, - marginLeft: 8, - marginRight: 8, -})) -const Number = styled("div")(({ theme }) => ({ - fontSize: 11, - textAlign: "center", - minWidth: 14, - paddingTop: 2, - paddingBottom: 2, - fontWeight: "bold", - color: muiColors.grey[700], -})) - -export const ClassSelectionMenu = ({ - selectedCls, - regionClsList, - onSelectCls, -}) => { - useEffect(() => { - const keyMapping = {} - for (let i = 0; i < 9 && i < regionClsList.length; i++) { - keyMapping[i + 1] = () => onSelectCls(regionClsList[i]) - } - const onKeyDown = (e) => { - if (keyMapping[e.key]) { - keyMapping[e.key]() - e.preventDefault() - e.stopPropagation() - } - } - window.addEventListener("keydown", onKeyDown) - return () => window.removeEventListener("keydown", onKeyDown) - }, [regionClsList, selectedCls]) - - return ( - - } - expandedByDefault - > - {regionClsList.map((label, index) => ( - onSelectCls(label)} - > - - - - - {index < 9 ? `Key [${index + 1}]` : ""} - - - ))} - - - - ) -} - -export default ClassSelectionMenu diff --git a/src/ClassSelectionMenu/index.tsx b/src/ClassSelectionMenu/index.tsx new file mode 100644 index 00000000..08c70fb2 --- /dev/null +++ b/src/ClassSelectionMenu/index.tsx @@ -0,0 +1,136 @@ +import { useEffect } from 'react'; +import { createTheme, styled, ThemeProvider } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import * as muiColors from '@mui/material/colors'; +import SidebarBoxContainer from '../SidebarBoxContainer'; +import colors from '../colors'; +import BallotIcon from '@mui/icons-material/Ballot'; +import capitalize from 'lodash/capitalize'; +import classnames from 'classnames'; + +const theme = createTheme(); +const LabelContainer = styled('div')(() => ({ + display: 'flex', + paddingTop: 4, + paddingBottom: 4, + paddingLeft: 16, + paddingRight: 16, + alignItems: 'center', + cursor: 'pointer', + opacity: 0.7, + backgroundColor: '#fff', + '&:hover': { + opacity: 1, + }, + '&.selected': { + opacity: 1, + fontWeight: 'bold', + }, +})); +const Circle = styled('div')(() => ({ + width: 12, + height: 12, + borderRadius: 12, + marginRight: 8, +})); +const Label = styled('div')(() => ({ + fontSize: 11, +})); +const DashSep = styled('div')(() => ({ + flexGrow: 1, + borderBottom: `2px dotted ${muiColors.grey[300]}`, + marginLeft: 8, + marginRight: 8, +})); +const Number = styled('div')(() => ({ + fontSize: 11, + textAlign: 'center', + minWidth: 14, + paddingTop: 2, + paddingBottom: 2, + fontWeight: 'bold', + color: muiColors.grey[700], +})); + +const getRegionValue = (item: string | { id: string; label: string; color: string }) => { + return typeof item === 'string' ? item : item.id; +}; + +interface ClassSelectionMenuProps { + selectedCls?: string; + regionClsList: (string | { id: string; label: string; color: string })[]; + onSelectCls: (value: string) => void; +} + +export const ClassSelectionMenu = ({ + selectedCls, + regionClsList, + onSelectCls, +}: ClassSelectionMenuProps) => { + useEffect(() => { + const keyMapping: Record< + string, + (item?: string | { id: string; label: string; color: string }) => void + > = {}; + for (let i = 0; i < 9 && i < regionClsList.length; i++) { + keyMapping[i + 1] = () => { + const item = regionClsList[i]; + onSelectCls(getRegionValue(item)); + }; + } + const onKeyDown = (e: KeyboardEvent) => { + if (keyMapping[e.key]) { + keyMapping[e.key](); + e.preventDefault(); + e.stopPropagation(); + } + }; + window.addEventListener('keydown', onKeyDown); + return () => window.removeEventListener('keydown', onKeyDown); + }, [regionClsList, selectedCls]); + + return ( + + } + expandedByDefault + > + {regionClsList.map((item, index) => ( + onSelectCls(getRegionValue(item))} + > + + + + + {index < 9 ? `Key [${index + 1}]` : ''} + + + ))} + + + + ); +}; + +export default ClassSelectionMenu; diff --git a/src/Crosshairs/index.js b/src/Crosshairs/index.js deleted file mode 100644 index 8bcf808f..00000000 --- a/src/Crosshairs/index.js +++ /dev/null @@ -1,64 +0,0 @@ -// @flow - -import React, { Fragment, useEffect, useState } from "react" - -export const Crosshairs = ({ - mousePosition, - x, - y, -}: { - mousePosition: { current: { x: number, y: number } }, - x?: number, - y?: number, -}) => { - const [forceRenderState, changeForceRenderState] = useState() - - if (mousePosition) { - x = mousePosition.current.x - y = mousePosition.current.y - } - - useEffect(() => { - if (!mousePosition) return - const interval = setInterval(() => { - if (x !== mousePosition.current.x || y !== mousePosition.current.y) { - changeForceRenderState([ - mousePosition.current.x, - mousePosition.current.y, - ]) - } - }, 10) - return () => clearInterval(interval) - }) - - return ( - -
-
- - ) -} - -export default Crosshairs diff --git a/src/Crosshairs/index.tsx b/src/Crosshairs/index.tsx new file mode 100644 index 00000000..e50c0137 --- /dev/null +++ b/src/Crosshairs/index.tsx @@ -0,0 +1,64 @@ + + +import { Fragment } from "react"; + +export const Crosshairs = ({ + mousePosition, + x, + y, +}: { + mousePosition: { current: { x: number; y: number } }; + x?: number; + y?: number; +}) => { + // const [forceRenderState, changeForceRenderState] = useState() + + if (mousePosition) { + x = mousePosition.current.x; + y = mousePosition.current.y; + } + + // useEffect(() => { + // if (!mousePosition) return + // const interval = setInterval(() => { + // if (x !== mousePosition.current.x || y !== mousePosition.current.y) { + // changeForceRenderState([ + // mousePosition.current.x, + // mousePosition.current.y, + // ]) + // } + // }, 10) + // return () => clearInterval(interval) + // }) + + return ( + +
+
+ + ); +}; + +export default Crosshairs; diff --git a/src/DebugSidebarBox/index.js b/src/DebugSidebarBox/index.tsx similarity index 50% rename from src/DebugSidebarBox/index.js rename to src/DebugSidebarBox/index.tsx index 67f464f2..3451581d 100644 --- a/src/DebugSidebarBox/index.js +++ b/src/DebugSidebarBox/index.tsx @@ -1,13 +1,23 @@ -// @flow -import React from "react" -import SidebarBoxContainer from "../SidebarBoxContainer" -export const DebugSidebarBox = ({ state, lastAction }: any) => { - const image = (state.images || [])[state.selectedImage] +import SidebarBoxContainer from "../SidebarBoxContainer/index.tsx"; +import { Action, MainLayoutState } from "../MainLayout/types.ts"; + +interface DebugSidebarBoxProps { + state: MainLayoutState; + lastAction: Action | undefined; +} + +export const DebugSidebarBox = ({ + state, + lastAction, +}: DebugSidebarBoxProps) => { + const image = state.selectedImage + ? (state.images || [])[state.selectedImage] + : null; const region = image ? (image.regions || []).filter((r) => r.highlighted) - : null + : null; return ( } expandedByDefault> @@ -27,10 +37,14 @@ export const DebugSidebarBox = ({ state, lastAction }: any) => {
frame:
-
{JSON.stringify(state.selectedImageFrameTime, null, "  ")}
+
+          {"selectedImageFrameTime" in state
+            ? JSON.stringify(state.selectedImageFrameTime, null, "  ")
+            : null}
+        
- ) -} + ); +}; -export default DebugSidebarBox +export default DebugSidebarBox; diff --git a/src/DemoSite/Editor.js b/src/DemoSite/Editor.tsx similarity index 64% rename from src/DemoSite/Editor.js rename to src/DemoSite/Editor.tsx index 929d91d8..41419a0e 100644 --- a/src/DemoSite/Editor.js +++ b/src/DemoSite/Editor.tsx @@ -1,19 +1,20 @@ -// @flow -import React, { useState } from "react" -import Button from "@mui/material/Button" -import { makeStyles } from "@mui/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" -import Select from "react-select" -import Code from "react-syntax-highlighter" -import Dialog from "@mui/material/Dialog" -import DialogTitle from "@mui/material/DialogTitle" -import DialogContent from "@mui/material/DialogContent" -import DialogActions from "@mui/material/DialogActions" -import MonacoEditor from "react-monaco-editor" -const theme = createTheme() -const useStyles = makeStyles((theme) => ({ +import { useState } from "react"; +import Button from "@mui/material/Button"; +import { tss } from "tss-react/mui"; +import { createTheme, ThemeProvider } from "@mui/material/styles"; +import Select from "react-select"; +import Code from "react-syntax-highlighter"; +import Dialog from "@mui/material/Dialog"; +import DialogTitle from "@mui/material/DialogTitle"; +import DialogContent from "@mui/material/DialogContent"; +import DialogActions from "@mui/material/DialogActions"; +import MonacoEditor from "react-monaco-editor"; +import { AnnotatorProps } from "../Annotator"; + +const theme = createTheme(); +const useStyles = tss.create(() => ({ editBar: { padding: 10, borderBottom: "1px solid #ccc", @@ -29,17 +30,72 @@ const useStyles = makeStyles((theme) => ({ specificationArea: { padding: 10, }, -})) +})); const loadSavedInput = () => { try { - return JSON.parse(window.localStorage.getItem("customInput") || "{}") + return JSON.parse(window.localStorage.getItem("customInput") || "{}"); } catch (e) { - return {} + return {}; } -} +}; -export const examples = { +export const examples: Record Omit> = { + FULL: () => ({ + taskDescription: + "Annotate each image according to this _markdown_ specification.", + regionTagList: ["has-bun", "has-sausage"], + regionTagSingleSelection: true, + regionClsList: [ + { id: "1", label: "hotdog", color: "#33ccff" }, + { id: "2", label: "not-hotdog", color: "#33cc33" }, + ], + enabledTools: [ + "select", + "create-point", + "create-box", + "create-polygon", + "create-line", + "create-expanding-line", + "show-mask", + "create-keypoints", + ], + showTags: true, + keypointDefinitions: { + "1": { + landmarks: { + "1": { + id: 1, + color: "0000FF", + label: "nose", + defaultPosition: [0.5, 0.5], + }, + "2": { + id: 1, + color: "00FFFF", + label: "left-eye", + defaultPosition: [0.4, 0.4], + }, + }, + connections: [["1", "2"]], + }, + }, + images: [ + { + src: "https://images.unsplash.com/photo-1496905583330-eb54c7e5915a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80", + name: "hot-dogs-1", + }, + { + src: "https://www.bianchi.com/wp-content/uploads/2019/07/YPB17I555K.jpg", + name: "bianchi-oltre-xr4", + }, + ], + imageClsList: ["test", "test2"], + showPointDistances: true, + allowComments: true, + fullImageSegmentationMode: true, + autoSegmentationOptions: { type: "autoseg" }, + }), "Simple Bounding Box": () => ({ taskDescription: "Annotate each image according to this _markdown_ specification.", @@ -65,7 +121,8 @@ export const examples = { taskDescription: "Annotate each image according to this _markdown_ specification.", regionClsList: ["car", "truck"], - enabledTools: ["select", "create-polygon"], + enabledTools: ["select", "create-polygon", "create-box"], + selectedTool: "create-polygon", images: [ { src: "https://images.unsplash.com/photo-1561518776-e76a5e48f731?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80", @@ -74,47 +131,46 @@ export const examples = { ], }), Custom: () => loadSavedInput(), -} +}; const Editor = ({ onOpenAnnotator, lastOutput }: any) => { - const c = useStyles() - const [currentError, changeCurrentError] = useState() + const { classes } = useStyles(); + const [currentError, changeCurrentError] = useState(null); const [selectedExample, changeSelectedExample] = useState( - window.localStorage.getItem("customInput") - ? "Custom" - : "Simple Bounding Box" - ) - const [outputDialogOpen, changeOutputOpen] = useState(false) + window.localStorage.getItem("customInput") ? "Custom" : "FULL" + ); + const [outputDialogOpen, changeOutputOpen] = useState(false); const [currentJSONValue, changeCurrentJSONValue] = useState( JSON.stringify(examples[selectedExample](), null, " ") - ) + ); return (
-
+

React Image Annotate

tag with two divs - const commentInput = commentInputRef.current.children[0].children[0] - - if (commentInput) return commentInput.focus() - } - - return ( - - (!editing ? onOpen(region) : null)} - className={classnames(classes.regionInfo, { - highlighted: region.highlighted, - })} - > - {!editing ? ( -
- {region.cls && ( -
-
- {region.cls} -
- )} - {region.tags && ( -
- {region.tags.map((t) => ( -
- {t} -
- ))} -
- )} -
- ) : ( -
-
-
- {region.type} -
-
- onDelete(region)} - tabIndex={-1} - style={{ width: 22, height: 22 }} - size="small" - variant="outlined" - > - - -
- {(allowedClasses || []).length > 0 && ( -
- { - if (actionMeta.action == "create-option") { - onRegionClassAdded(o.value) - } - return onChange({ - ...(region: any), - cls: o.value, - }) - }} - value={ - region.cls ? { label: region.cls, value: region.cls } : null - } - options={asMutable( - allowedClasses.map((c) => ({ value: c, label: c })) - )} - /> -
- )} - {(allowedTags || []).length > 0 && ( -
- tag with two divs + const commentInput = commentInputRef.current?.children?.[0] + ?.children?.[0] as HTMLInputElement | undefined; + + if (commentInput) return commentInput.focus(); + }; + + const isCreatableAllowedClasses = typeof allowedClasses?.[0] === "string"; + const selectedRegionClass = + allowedClasses?.find((c) => typeof c === "object" && c.id === region.cls) || + region.cls; + const selectedLabel = + selectedRegionClass && typeof selectedRegionClass === "object" + ? selectedRegionClass.label + : region.cls; + const selectedValue = + selectedRegionClass && typeof selectedRegionClass === "object" + ? { label: selectedRegionClass.label, value: selectedRegionClass.id } + : region.cls + ? { label: region.cls, value: region.cls } + : null; + + return ( + + (!editing && onOpen ? onOpen(region) : null)} + className={classnames(classes.regionInfo, { + highlighted: region.highlighted, + })} + > + {!editing ? ( +
+ {region.cls && ( +
+
+ {selectedLabel} +
+ )} + {region.tags && ( +
+ {region.tags.map((t) => ( +
+ {t} +
+ ))} +
+ )} +
+ ) : ( +
+
+
+ {region.type} +
+
+ onDelete(region)} + tabIndex={-1} + style={{ width: 22, height: 22 }} + size="small" + > + + +
+ {(allowedClasses || []).length > 0 && ( +
+ {isCreatableAllowedClasses ? ( + { + if (!o) return; + if ( + actionMeta.action == "create-option" && + onRegionClassAdded + ) { + onRegionClassAdded(o.value); + } + onChange({ + ...region, + cls: o.value, + }); + }} + value={selectedValue} + options={ + allowedClasses?.map((c) => + typeof c === "string" + ? { value: c, label: c } + : { value: c.id, label: c.label } + ) + } + /> + ) : ( + { + if (Array.isArray(newTags)) { + onChange({ + ...region, + tags: newTags.map((t) => t.value), + }); + return; + } + if (newTags && "value" in newTags) { + onChange({ + ...region, + tags: [newTags.value], + }); + } + }} + placeholder="Tags" + value={(region.tags || []).map((c) => ({ + label: c, + value: c, + }))} + isMulti={!tagSingleSelection} + options={ + allowedTags?.map((c) => ({ value: c, label: c })) + } + /> +
+ )} + {allowComments && ( + + onChange({ ...region, comment: event.target.value }) + } + /> + )} + {onClose && ( +
+
+ +
+ )} +
+ )} + + + ); +}; + +export default memo( + RegionLabel, + (prevProps, nextProps) => + prevProps.editing === nextProps.editing && + prevProps.region === nextProps.region +); diff --git a/src/RegionLabel/styles.js b/src/RegionLabel/styles.js deleted file mode 100644 index 6d3a8447..00000000 --- a/src/RegionLabel/styles.js +++ /dev/null @@ -1,51 +0,0 @@ -// @flow - -import { grey } from "@mui/material/colors" - -export default { - regionInfo: { - fontSize: 12, - cursor: "default", - transition: "opacity 200ms", - opacity: 0.5, - "&:hover": { - opacity: 0.9, - cursor: "pointer", - }, - "&.highlighted": { - opacity: 0.9, - "&:hover": { - opacity: 1, - }, - }, - // pointerEvents: "none", - fontWeight: 600, - color: grey[900], - padding: 8, - "& .name": { - display: "flex", - flexDirection: "row", - alignItems: "center", - "& .circle": { - marginRight: 4, - boxShadow: "0px 0px 2px rgba(0,0,0,0.4)", - width: 10, - height: 10, - borderRadius: 5, - }, - }, - "& .tags": { - "& .tag": { - color: grey[700], - display: "inline-block", - margin: 1, - fontSize: 10, - textDecoration: "underline", - }, - }, - }, - commentBox: { - fontWeight: 400, - fontSize: 13, - }, -} diff --git a/src/RegionSelectAndTransformBoxes/index.js b/src/RegionSelectAndTransformBoxes/index.tsx similarity index 70% rename from src/RegionSelectAndTransformBoxes/index.js rename to src/RegionSelectAndTransformBoxes/index.tsx index e1279710..9ae790aa 100644 --- a/src/RegionSelectAndTransformBoxes/index.js +++ b/src/RegionSelectAndTransformBoxes/index.tsx @@ -1,33 +1,64 @@ -import React, { Fragment, memo } from "react" -import HighlightBox from "../HighlightBox" -import { styled } from "@mui/material/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" -import PreventScrollToParents from "../PreventScrollToParents" -import Tooltip from "@mui/material/Tooltip" +import { Fragment, memo, MutableRefObject } from "react"; +import HighlightBox from "../HighlightBox/index.tsx"; +import { createTheme, styled, ThemeProvider } from "@mui/material/styles"; +import PreventScrollToParents from "../PreventScrollToParents/index.tsx"; +import Tooltip from "@mui/material/Tooltip"; +import { + type Box, + type Keypoints, + type Point, + type Polygon, + Region, +} from "../types/region-tools.ts"; +import { MouseEvents } from "../ImageCanvas/use-mouse.ts"; +import { ProjectBox, ProjectBoxFn } from "../ImageCanvas/use-project-box.ts"; +import { CanvasLayoutParams } from "../ImageCanvas/index.tsx"; +import { IMatrix } from "transformation-matrix-js"; -const theme = createTheme() -const TransformGrabber = styled("div")(({ theme }) => ({ +const theme = createTheme(); +const TransformGrabber = styled("div")(() => ({ width: 8, height: 8, zIndex: 2, border: "2px solid #FFF", position: "absolute", -})) +})); const boxCursorMap = [ ["nw-resize", "n-resize", "ne-resize"], ["w-resize", "grab", "e-resize"], ["sw-resize", "s-resize", "se-resize"], -] +]; -const arePropsEqual = (prev, next) => { +const arePropsEqual = ( + prev: RegionSelectAndTransformBoxProps, + next: RegionSelectAndTransformBoxProps +) => { return ( prev.region === next.region && prev.dragWithPrimary === next.dragWithPrimary && prev.createWithPrimary === next.createWithPrimary && prev.zoomWithPrimary === next.zoomWithPrimary && prev.mat === next.mat - ) + ); +}; + +interface RegionSelectAndTransformBoxProps { + region: Region; + mouseEvents: MouseEvents; + projectRegionBox: ProjectBoxFn; + dragWithPrimary?: boolean; + createWithPrimary?: boolean; + zoomWithPrimary?: boolean; + onBeginMovePoint: (point: Point) => void; + onSelectRegion: (r: Region) => void; + layoutParams: MutableRefObject; + mat: IMatrix; + onBeginBoxTransform: (r: Box, corner: [number, number]) => void; + onBeginMovePolygonPoint: (r: Polygon, pointIndex: number) => void; + onBeginMoveKeypoint: (r: Keypoints, keypointId: string) => void; + onAddPolygonPoint: (r: Polygon, pa: [number, number], i: number) => void; + showHighlightBox: boolean; } export const RegionSelectAndTransformBox = memo( @@ -41,16 +72,15 @@ export const RegionSelectAndTransformBox = memo( onBeginMovePoint, onSelectRegion, layoutParams, - fullImageSegmentationMode = false, mat, onBeginBoxTransform, onBeginMovePolygonPoint, onBeginMoveKeypoint, onAddPolygonPoint, showHighlightBox, - }) => { - const pbox = projectRegionBox(r) - const { iw, ih } = layoutParams.current + }: RegionSelectAndTransformBoxProps) => { + const pbox: ProjectBox = projectRegionBox(r); + const { iw, ih } = layoutParams.current ?? { iw: 0, ih: 0 }; return ( @@ -89,8 +119,8 @@ export const RegionSelectAndTransformBox = memo( {...mouseEvents} onMouseDown={(e) => { if (e.button === 0) - return onBeginBoxTransform(r, [px * 2 - 1, py * 2 - 1]) - mouseEvents.onMouseDown(e) + return onBeginBoxTransform(r, [px * 2 - 1, py * 2 - 1]); + mouseEvents.onMouseDown(e); }} style={{ left: pbox.x - 4 - 2 + pbox.w * px, @@ -109,15 +139,15 @@ export const RegionSelectAndTransformBox = memo( const proj = mat .clone() .inverse() - .applyToPoint(px * iw, py * ih) + .applyToPoint(px * iw, py * ih); return ( { if (e.button === 0 && (!r.open || i === 0)) - return onBeginMovePolygonPoint(r, i) - mouseEvents.onMouseDown(e) + return onBeginMovePolygonPoint(r, i); + mouseEvents.onMouseDown(e); }} style={{ cursor: !r.open @@ -134,7 +164,7 @@ export const RegionSelectAndTransformBox = memo( top: proj.y - 4, }} /> - ) + ); })} {r.type === "polygon" && r.highlighted && @@ -150,15 +180,19 @@ export const RegionSelectAndTransformBox = memo( const proj = mat .clone() .inverse() - .applyToPoint(pa[0] * iw, pa[1] * ih) + .applyToPoint(pa[0] * iw, pa[1] * ih); return ( { if (e.button === 0) - return onAddPolygonPoint(r, pa, i + 1) - mouseEvents.onMouseDown(e) + return onAddPolygonPoint( + r, + pa as [number, number], + i + 1 + ); + mouseEvents.onMouseDown(e); }} style={{ cursor: "copy", @@ -169,7 +203,7 @@ export const RegionSelectAndTransformBox = memo( opacity: 0.5, }} /> - ) + ); })} {r.type === "keypoints" && !dragWithPrimary && @@ -181,7 +215,7 @@ export const RegionSelectAndTransformBox = memo( const proj = mat .clone() .inverse() - .applyToPoint(px * iw, py * ih) + .applyToPoint(px * iw, py * ih); return ( { if (e.button === 0 && (!r.open || i === 0)) - return onBeginMoveKeypoint(r, keypointId) - mouseEvents.onMouseDown(e) + return onBeginMoveKeypoint(r, keypointId); + mouseEvents.onMouseDown(e); }} style={{ cursor: !r.open @@ -200,7 +234,8 @@ export const RegionSelectAndTransformBox = memo( : undefined, zIndex: 10, pointerEvents: - r.open && i === r.points.length - 1 + r.open && + i === Array.from(Object.keys(r.points)).length - 1 ? "none" : undefined, left: proj.x - 4, @@ -208,27 +243,31 @@ export const RegionSelectAndTransformBox = memo( }} /> - ) + ); } )} - ) + ); }, arePropsEqual -) +); export const RegionSelectAndTransformBoxes = memo( - (props) => { + ( + props: Omit & { + regions: Region[]; + } + ) => { return props.regions .filter((r) => r.visible || r.visible === undefined) .filter((r) => !r.locked) - .map((r, i) => { - return - }) + .map((r) => { + return ; + }); }, (n, p) => n.regions === p.regions && n.mat === p.mat -) +); -export default RegionSelectAndTransformBoxes +export default RegionSelectAndTransformBoxes; diff --git a/src/RegionSelectorSidebarBox/index.js b/src/RegionSelectorSidebarBox/index.js deleted file mode 100644 index 1b03264a..00000000 --- a/src/RegionSelectorSidebarBox/index.js +++ /dev/null @@ -1,216 +0,0 @@ -// @flow - -import React, { Fragment, useState, memo } from "react" -import SidebarBoxContainer from "../SidebarBoxContainer" -import { makeStyles } from "@mui/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" -import { styled } from "@mui/material/styles" -import { grey } from "@mui/material/colors" -import RegionIcon from "@mui/icons-material/PictureInPicture" -import Grid from "@mui/material/Grid" -import ReorderIcon from "@mui/icons-material/SwapVert" -import PieChartIcon from "@mui/icons-material/PieChart" -import TrashIcon from "@mui/icons-material/Delete" -import LockIcon from "@mui/icons-material/Lock" -import UnlockIcon from "@mui/icons-material/LockOpen" -import VisibleIcon from "@mui/icons-material/Visibility" -import VisibleOffIcon from "@mui/icons-material/VisibilityOff" -import styles from "./styles" -import classnames from "classnames" -import isEqual from "lodash/isEqual" - -const theme = createTheme() -const useStyles = makeStyles((theme) => styles) - -const HeaderSep = styled("div")(({ theme }) => ({ - borderTop: `1px solid ${grey[200]}`, - marginTop: 2, - marginBottom: 2, -})) - -const Chip = ({ color, text }) => { - const classes = useStyles() - return ( - -
-
{text}
- - ) -} - -const RowLayout = ({ - header, - highlighted, - order, - classification, - area, - tags, - trash, - lock, - visible, - onClick, -}) => { - const classes = useStyles() - const [mouseOver, changeMouseOver] = useState(false) - return ( -
changeMouseOver(true)} - onMouseLeave={() => changeMouseOver(false)} - className={classnames(classes.row, { header, highlighted })} - > - - -
{order}
-
- - {classification} - - -
{area}
-
- - {trash} - - - {lock} - - - {visible} - -
-
- ) -} - -const RowHeader = () => { - return ( - } - classification={
Class
} - area={} - trash={} - lock={} - visible={} - /> - ) -} - -const MemoRowHeader = memo(RowHeader) - -const Row = ({ - region: r, - highlighted, - onSelectRegion, - onDeleteRegion, - onChangeRegion, - visible, - locked, - color, - cls, - index, -}) => { - return ( - onSelectRegion(r)} - order={`#${index + 1}`} - classification={} - area="" - trash={ onDeleteRegion(r)} className="icon2" />} - lock={ - r.locked ? ( - onChangeRegion({ ...r, locked: false })} - className="icon2" - /> - ) : ( - onChangeRegion({ ...r, locked: true })} - className="icon2" - /> - ) - } - visible={ - r.visible || r.visible === undefined ? ( - onChangeRegion({ ...r, visible: false })} - className="icon2" - /> - ) : ( - onChangeRegion({ ...r, visible: true })} - className="icon2" - /> - ) - } - /> - ) -} - -const MemoRow = memo( - Row, - (prevProps, nextProps) => - prevProps.highlighted === nextProps.highlighted && - prevProps.visible === nextProps.visible && - prevProps.locked === nextProps.locked && - prevProps.id === nextProps.id && - prevProps.index === nextProps.index && - prevProps.cls === nextProps.cls && - prevProps.color === nextProps.color -) - -const emptyArr = [] - -export const RegionSelectorSidebarBox = ({ - regions = emptyArr, - onDeleteRegion, - onChangeRegion, - onSelectRegion, -}) => { - const classes = useStyles() - return ( - - } - expandedByDefault - > -
- - - {regions.map((r, i) => ( - - ))} -
-
-
- ) -} - -const mapUsedRegionProperties = (r) => [ - r.id, - r.color, - r.locked, - r.visible, - r.highlighted, -] - -export default memo(RegionSelectorSidebarBox, (prevProps, nextProps) => - isEqual( - (prevProps.regions || emptyArr).map(mapUsedRegionProperties), - (nextProps.regions || emptyArr).map(mapUsedRegionProperties) - ) -) diff --git a/src/RegionSelectorSidebarBox/index.tsx b/src/RegionSelectorSidebarBox/index.tsx new file mode 100644 index 00000000..255906ac --- /dev/null +++ b/src/RegionSelectorSidebarBox/index.tsx @@ -0,0 +1,325 @@ + + +import { memo, ReactNode } from "react"; +import SidebarBoxContainer from "../SidebarBoxContainer/index.tsx"; +import { createTheme, styled, ThemeProvider } from "@mui/material/styles"; +import { blue, grey } from "@mui/material/colors"; +import RegionIcon from "@mui/icons-material/PictureInPicture"; +import Grid from "@mui/material/Grid"; +import ReorderIcon from "@mui/icons-material/SwapVert"; +import TrashIcon from "@mui/icons-material/Delete"; +import LockIcon from "@mui/icons-material/Lock"; +import UnlockIcon from "@mui/icons-material/LockOpen"; +import VisibleIcon from "@mui/icons-material/Visibility"; +import VisibleOffIcon from "@mui/icons-material/VisibilityOff"; +import classnames from "classnames"; +import isEqual from "lodash/isEqual"; +import { Region } from "../types/region-tools.ts"; +import { tss } from "tss-react/mui"; +import { RegionAllowedActions } from "../MainLayout/types.ts"; + +const theme = createTheme(); +const useStyles = tss.create({ + container: { + fontSize: 11, + fontWeight: "bold", + color: grey[700], + "& .icon": { + marginTop: 4, + width: 16, + height: 16, + }, + "& .icon2": { + opacity: 0.5, + width: 16, + height: 16, + transition: "200ms opacity", + "&:hover": { + cursor: "pointer", + opacity: 1, + }, + }, + }, + row: { + padding: 4, + cursor: "pointer", + "&.header:hover": { + backgroundColor: "#fff", + }, + "&.highlighted": { + backgroundColor: blue[100], + }, + "&:hover": { + backgroundColor: blue[50], + color: grey[800], + }, + }, + chip: { + display: "flex", + flexDirection: "row", + padding: 2, + borderRadius: 2, + paddingLeft: 4, + paddingRight: 4, + alignItems: "center", + "& .color": { + borderRadius: 5, + width: 10, + minWidth: 10, + height: 10, + marginRight: 4, + }, + "& .text": {}, + }, +}); + +const HeaderSep = styled("div")(() => ({ + borderTop: `1px solid ${grey[200]}`, + marginTop: 2, + marginBottom: 2, +})); + +interface ChipProps { + color: string; + text: string; +} + +const Chip = ({ color, text }: ChipProps) => { + const { classes } = useStyles(); + return ( + +
+
{text}
+ + ); +}; + +interface RowLayoutProps { + header: boolean; + highlighted: boolean; + order: ReactNode; + classification: ReactNode; + trash: ReactNode; + lock: ReactNode; + visible: ReactNode; + onClick?: () => void; +} + +const RowLayout = ({ + header, + highlighted, + order, + classification, + trash, + lock, + visible, + onClick, +}: RowLayoutProps) => { + const { classes } = useStyles(); + return ( +
+ + +
{order}
+
+ + {classification} + + + {trash} + + + {lock} + + + {visible} + +
+
+ ); +}; + +const RowHeader = ({ + regionAllowedActions, +}: { + regionAllowedActions: RegionAllowedActions; +}) => { + return ( + } + classification={
Class
} + trash={ + regionAllowedActions.remove ? : null + } + lock={regionAllowedActions.lock ? : null} + visible={ + regionAllowedActions.visibility ? ( + + ) : null + } + /> + ); +}; + +const MemoRowHeader = memo(RowHeader); + +interface RowProps { + region: Region; + regionClsList?: Array<{ id: string; label: string }> | string[]; + regionAllowedActions: RegionAllowedActions; + highlighted?: boolean; + onSelectRegion: (r: Region) => void; + onDeleteRegion: (r: Region) => void; + onChangeRegion: (r: Region) => void; + visible?: boolean; + locked?: boolean; + color: string; + cls?: string; + index: number; + rId: string | number; +} + +const Row = ({ + region: r, + regionClsList, + highlighted, + onSelectRegion, + onDeleteRegion, + onChangeRegion, + color, + cls, + index, + regionAllowedActions, +}: RowProps) => { + const selectedCls = regionClsList?.find( + (c) => typeof c === "object" && c.id === cls + ); + const clsLabel = + selectedCls && typeof selectedCls === "object" ? selectedCls.label : cls; + return ( + onSelectRegion(r)} + order={`#${index + 1}`} + classification={} + trash={ + regionAllowedActions.remove ? ( + onDeleteRegion(r)} className="icon2" /> + ) : null + } + lock={ + regionAllowedActions.lock ? ( + r.locked ? ( + onChangeRegion({ ...r, locked: false })} + className="icon2" + /> + ) : ( + onChangeRegion({ ...r, locked: true })} + className="icon2" + /> + ) + ) : null + } + visible={ + regionAllowedActions.visibility ? ( + r.visible || r.visible === undefined ? ( + onChangeRegion({ ...r, visible: false })} + className="icon2" + /> + ) : ( + onChangeRegion({ ...r, visible: true })} + className="icon2" + /> + ) + ) : null + } + /> + ); +}; + +const MemoRow = memo( + Row, + (prevProps, nextProps) => + prevProps.highlighted === nextProps.highlighted && + prevProps.visible === nextProps.visible && + prevProps.locked === nextProps.locked && + prevProps.rId === nextProps.rId && + prevProps.index === nextProps.index && + prevProps.cls === nextProps.cls && + prevProps.color === nextProps.color +); + +const emptyArr: Region[] = []; + +interface RegionSelectorSidebarBoxProps { + regions?: Region[]; + regionClsList?: Array<{ id: string; label: string }> | string[]; + regionAllowedActions: RegionAllowedActions; + onDeleteRegion: (r: Region) => void; + onChangeRegion: (r: Region) => void; + onSelectRegion: (r: Region) => void; +} + +export const RegionSelectorSidebarBox = ({ + regions = emptyArr, + regionClsList, + onDeleteRegion, + onChangeRegion, + onSelectRegion, + regionAllowedActions, +}: RegionSelectorSidebarBoxProps) => { + const { classes } = useStyles(); + return ( + + } + expandedByDefault + > +
+ + + {regions.map((r, i) => ( + + ))} +
+
+
+ ); +}; + +const mapUsedRegionProperties = (r: Region) => [ + r.id, + r.color, + r.locked, + r.visible, + r.highlighted, +]; + +export default memo(RegionSelectorSidebarBox, (prevProps, nextProps) => + isEqual( + (prevProps.regions || emptyArr).map(mapUsedRegionProperties), + (nextProps.regions || emptyArr).map(mapUsedRegionProperties) + ) +); diff --git a/src/RegionSelectorSidebarBox/styles.js b/src/RegionSelectorSidebarBox/styles.js deleted file mode 100644 index 3e08db66..00000000 --- a/src/RegionSelectorSidebarBox/styles.js +++ /dev/null @@ -1,54 +0,0 @@ -import { grey, blue, orange, purple } from "@mui/material/colors" - -export default { - container: { - fontSize: 11, - fontWeight: "bold", - color: grey[700], - "& .icon": { - marginTop: 4, - width: 16, - height: 16, - }, - "& .icon2": { - opacity: 0.5, - width: 16, - height: 16, - transition: "200ms opacity", - "&:hover": { - cursor: "pointer", - opacity: 1, - }, - }, - }, - row: { - padding: 4, - cursor: "pointer", - "&.header:hover": { - backgroundColor: "#fff", - }, - "&.highlighted": { - backgroundColor: blue[100], - }, - "&:hover": { - backgroundColor: blue[50], - color: grey[800], - }, - }, - chip: { - display: "flex", - flexDirection: "row", - padding: 2, - borderRadius: 2, - paddingLeft: 4, - paddingRight: 4, - alignItems: "center", - "& .color": { - borderRadius: 5, - width: 10, - height: 10, - marginRight: 4, - }, - "& .text": {}, - }, -} diff --git a/src/RegionShapes/index.js b/src/RegionShapes/index.tsx similarity index 53% rename from src/RegionShapes/index.js rename to src/RegionShapes/index.tsx index 476fad92..ef605477 100644 --- a/src/RegionShapes/index.js +++ b/src/RegionShapes/index.tsx @@ -1,52 +1,67 @@ -// @flow -import React, { memo } from "react" -import colorAlpha from "color-alpha" -function clamp(num, min, max) { - return num <= min ? min : num >= max ? max : num -} +import { memo } from "react"; +import colorAlpha from "color-alpha"; +import { clamp } from "../utils/clamp.ts"; +import { KeypointsDefinition, Line, Region } from "../types/region-tools.ts"; +import { ImagePosition } from "../types/common.ts"; + +type RegionComponentProps = { + iw: number; + ih: number; + region: Region | Line; + keypointDefinitions?: KeypointsDefinition; +}; const RegionComponents = { - point: memo(({ region, iw, ih }) => ( - - - - )), - line: memo(({ region, iw, ih }) => ( - - - - )), - box: memo(({ region, iw, ih }) => ( - - - - )), - polygon: memo(({ region, iw, ih, fullSegmentationMode }) => { - const Component = region.open ? "polyline" : "polygon" - const alphaBase = fullSegmentationMode ? 0.5 : 1 + point: memo(({ region, iw, ih }: RegionComponentProps) => { + if (region.type !== "point") return null; + return ( + + + + ); + }), + line: memo(({ region, iw, ih }: RegionComponentProps) => { + if (region.type !== "line") return null; + return ( + + + + ); + }), + box: memo(({ region, iw, ih }: RegionComponentProps) => { + if (region.type !== "box") return null; + return ( + + + + ); + }), + polygon: memo(({ region, iw, ih }: RegionComponentProps) => { + if (region.type !== "polygon") return null; + const Component = region.open ? "polyline" : "polygon"; return ( - ) + ); }), - keypoints: ({ region, iw, ih, keypointDefinitions }) => { - const { points, keypointsDefinitionId } = region - if (!keypointDefinitions[keypointsDefinitionId]) { + keypoints: ({ + region, + iw, + ih, + keypointDefinitions, + }: RegionComponentProps) => { + if (region.type !== "keypoints") return null; + const { points, keypointsDefinitionId } = region; + if (!keypointDefinitions?.[keypointsDefinitionId]) { throw new Error( `No definition for keypoint configuration "${keypointsDefinitionId}"` - ) + ); } const { landmarks, connections } = - keypointDefinitions[keypointsDefinitionId] + keypointDefinitions[keypointsDefinitionId]; return ( {Object.entries(points).map(([keypointId, { x, y }], i) => ( @@ -75,16 +96,16 @@ const RegionComponents = { ))} {connections.map(([kp1Id, kp2Id]) => { - const kp1 = points[kp1Id] - const kp2 = points[kp2Id] - const midPoint = { x: (kp1.x + kp2.x) / 2, y: (kp1.y + kp2.y) / 2 } - + const kp1 = points[kp1Id]; + const kp2 = points[kp2Id]; + const midPoint = { x: (kp1.x + kp2.x) / 2, y: (kp1.y + kp2.y) / 2 }; return ( - ) + ); })} - ) + ); }, - "expanding-line": memo(({ region, iw, ih }) => { - let { expandingWidth = 0.005, points } = region - expandingWidth = points.slice(-1)[0].width || expandingWidth + "expanding-line": memo(({ region, iw, ih }: RegionComponentProps) => { + if (region.type !== "expanding-line") return null; + let { expandingWidth = 0.005, points } = region; + expandingWidth = points.slice(-1)[0].width || expandingWidth; const pointPairs = points.map(({ x, y, angle, width }, i) => { if (!angle) { - const n = points[clamp(i + 1, 0, points.length - 1)] - const p = points[clamp(i - 1, 0, points.length - 1)] - angle = Math.atan2(p.x - n.x, p.y - n.y) + Math.PI / 2 + const n = points[clamp(i + 1, 0, points.length - 1)]; + const p = points[clamp(i - 1, 0, points.length - 1)]; + angle = Math.atan2(p.x - n.x, p.y - n.y) + Math.PI / 2; } - const dx = (Math.sin(angle) * (width || expandingWidth)) / 2 - const dy = (Math.cos(angle) * (width || expandingWidth)) / 2 + const dx = (Math.sin(angle) * (width || expandingWidth)) / 2; + const dy = (Math.cos(angle) * (width || expandingWidth)) / 2; return [ { x: x + dx, y: y + dy }, { x: x - dx, y: y - dy }, - ] - }) - const firstSection = pointPairs.map(([p1, p2]) => p1) - const secondSection = pointPairs.map(([p1, p2]) => p2).asMutable() - secondSection.reverse() - const lastPoint = points.slice(-1)[0] + ]; + }); + const firstSection = pointPairs.map(([p1]) => p1); + const secondSection = pointPairs.map(([_, p2]) => p2); + secondSection.reverse(); + const lastPoint = points.slice(-1)[0]; return ( <> - ) + ); }), pixel: () => null, +}; + +interface WrappedRegionListProps { + regions: Region[]; + keypointDefinitions?: KeypointsDefinition; + iw: number; + ih: number; } export const WrappedRegionList = memo( - ({ regions, keypointDefinitions, iw, ih, fullSegmentationMode }) => { + ({ regions, keypointDefinitions, iw, ih }: WrappedRegionListProps) => { return regions .filter((r) => r.visible !== false) .map((r) => { - const Component = RegionComponents[r.type] + const Component = RegionComponents[r.type]; return ( - ) - }) + ); + }); }, (n, p) => n.regions === p.regions && n.iw === p.iw && n.ih === p.ih -) +); + +interface RegionShapesProps { + imagePosition: ImagePosition | null; + regions: Region[]; + keypointDefinitions?: KeypointsDefinition; +} export const RegionShapes = ({ - mat, imagePosition, regions = [], keypointDefinitions, - fullSegmentationMode, -}) => { - const iw = imagePosition.bottomRight.x - imagePosition.topLeft.x - const ih = imagePosition.bottomRight.y - imagePosition.topLeft.y - if (isNaN(iw) || isNaN(ih)) return null +}: RegionShapesProps) => { + if (!imagePosition) return null; + const iw = imagePosition.bottomRight.x - imagePosition.topLeft.x; + const ih = imagePosition.bottomRight.y - imagePosition.topLeft.y; + if (isNaN(iw) || isNaN(ih)) return null; return ( - ) -} + ); +}; -export default RegionShapes +export default RegionShapes; diff --git a/src/RegionTags/index.js b/src/RegionTags/index.tsx similarity index 62% rename from src/RegionTags/index.js rename to src/RegionTags/index.tsx index 48e7b36f..12c0a040 100644 --- a/src/RegionTags/index.js +++ b/src/RegionTags/index.tsx @@ -1,53 +1,73 @@ -// @flow weak +import Paper from "@mui/material/Paper"; +import DefaultRegionLabel, { RegionLabelProps } from "../RegionLabel/index.tsx"; +import LockIcon from "@mui/icons-material/Lock"; +import { Region } from "../types/region-tools.ts"; +import { ProjectBox, ProjectBoxFn } from "../ImageCanvas/use-project-box.ts"; +import { MouseEvents } from "../ImageCanvas/use-mouse.ts"; +import { ComponentType, FunctionComponent } from "react"; -import React from "react" -import Paper from "@mui/material/Paper" -import DefaultRegionLabel from "../RegionLabel" -import LockIcon from "@mui/icons-material/Lock" - -const copyWithout = (obj, ...args) => { - const newObj = { ...obj } +const copyWithout = ( + obj: T, + ...args: K[] +) => { + const newObj = { ...obj }; for (const arg of args) { - delete newObj[arg] + delete newObj[arg]; } - return newObj -} + return newObj; +}; +type RegionTagsProps = { + regions: Region[]; + projectRegionBox: ProjectBoxFn; + mouseEvents: MouseEvents; + regionClsList?: Array; + regionTagList?: string[]; + regionTagSingleSelection?: boolean; + onBeginRegionEdit: (r: Region) => void; + onChangeRegion: (r: Region) => void; + onCloseRegionEdit: (r: Region) => void; + onDeleteRegion: (r: Region) => void; + RegionEditLabel: + | ComponentType + | FunctionComponent + | null; + onRegionClassAdded: (cls: string) => void; + allowComments?: boolean; +}; export const RegionTags = ({ regions, projectRegionBox, mouseEvents, regionClsList, regionTagList, + regionTagSingleSelection, onBeginRegionEdit, onChangeRegion, onCloseRegionEdit, onDeleteRegion, - layoutParams, - imageSrc, RegionEditLabel, onRegionClassAdded, allowComments, -}) => { +}: RegionTagsProps) => { const RegionLabel = - RegionEditLabel != null ? RegionEditLabel : DefaultRegionLabel + RegionEditLabel != null ? RegionEditLabel : DefaultRegionLabel; return regions .filter((r) => r.visible || r.visible === undefined) .map((region) => { - const pbox = projectRegionBox(region) - const { iw, ih } = layoutParams.current - let margin = 8 - if (region.highlighted && region.type === "box") margin += 6 + const pbox: ProjectBox = projectRegionBox(region); + let margin = 8; + if (region.highlighted && region.type === "box") margin += 6; const labelBoxHeight = - region.editingLabels && !region.locked ? 170 : region.tags ? 60 : 50 - const displayOnTop = pbox.y > labelBoxHeight + region.editingLabels && !region.locked ? 170 : region.tags ? 60 : 50; + const displayOnTop = pbox.y > labelBoxHeight; const coords = displayOnTop ? { left: pbox.x, top: pbox.y - margin / 2, } - : { left: pbox.x, top: pbox.y + pbox.h + margin / 2 } + : { left: pbox.x, top: pbox.y + pbox.h + margin / 2 }; if (region.locked) { return (
- ) + ); } return (
e.preventDefault()} onMouseEnter={(e) => { if (region.editingLabels) { - mouseEvents.onMouseUp(e) - e.button = 1 - mouseEvents.onMouseUp(e) + mouseEvents.onMouseUp(e); + e.button = 1; + mouseEvents.onMouseUp(e); } }} > @@ -110,21 +130,20 @@ export const RegionTags = ({
- ) - }) -} + ); + }); +}; -export default RegionTags +export default RegionTags; diff --git a/src/SettingsDialog/index.js b/src/SettingsDialog/index.js deleted file mode 100644 index 466f9347..00000000 --- a/src/SettingsDialog/index.js +++ /dev/null @@ -1,58 +0,0 @@ -// @flow - -import React from "react" -import Dialog from "@mui/material/Dialog" -import DialogTitle from "@mui/material/DialogTitle" -import DialogContent from "@mui/material/DialogContent" -import DialogActions from "@mui/material/DialogActions" -import Button from "@mui/material/Button" -import Survey from "material-survey/components/Survey" -import { useSettings } from "../SettingsProvider" - -export const SettingsDialog = ({ open, onClose }) => { - const settings = useSettings() - return ( - - Settings - - settings.changeSetting(q, a)} - form={{ - questions: [ - { - type: "boolean", - title: "Show Crosshairs", - name: "showCrosshairs", - }, - { - type: "boolean", - title: "Show Highlight Box", - name: "showHighlightBox", - }, - { - type: "boolean", - title: "WASD Mode", - name: "wasdMode", - }, - { - type: "dropdown", - title: "Video Playback Speed", - name: "videoPlaybackSpeed", - defaultValue: "1x", - choices: ["0.25x", "0.5x", "1x", "2x"], - }, - ], - }} - /> - - - - - - ) -} - -export default SettingsDialog diff --git a/src/SettingsDialog/index.tsx b/src/SettingsDialog/index.tsx new file mode 100644 index 00000000..202b2492 --- /dev/null +++ b/src/SettingsDialog/index.tsx @@ -0,0 +1,178 @@ + + +import Dialog from "@mui/material/Dialog"; +import DialogTitle from "@mui/material/DialogTitle"; +import DialogContent from "@mui/material/DialogContent"; +import DialogActions from "@mui/material/DialogActions"; +import Button from "@mui/material/Button"; +import Radio from "@mui/material/Radio"; +import { useSettings } from "../SettingsProvider"; +import RadioGroup from "@mui/material/RadioGroup"; +import FormControlLabel from "@mui/material/FormControlLabel"; +import FormControl from "@mui/material/FormControl"; +import FormLabel from "@mui/material/FormLabel"; +import { useState } from "react"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import Select from "@mui/material/Select"; + +interface SettingsDialogProps { + open: boolean; + onClose: () => void; +} + +const bollEnum = { + YES: "1", + NO: "2", +}; + +const getBooleanConditionValue = (value: string) => { + return value === bollEnum.YES; +}; + +const getBooleanConditionValueString = (value: boolean | undefined) => { + return value ? bollEnum.YES : bollEnum.NO; +}; + +const booleanCondition = [ + { + value: bollEnum.YES, + label: "Yes", + }, + { + value: bollEnum.NO, + label: "No", + }, +]; + +const videoPlaybackSpeeds = ["0.25x", "0.5x", "1x", "2x"]; + +export const SettingsDialog = ({ open, onClose }: SettingsDialogProps) => { + const settings = useSettings(); + const [showCrosshairs, setShowCrosshairs] = useState( + getBooleanConditionValueString(settings.showCrosshairs) + ); + const [showHighlightBox, setShowHighlightBox] = useState( + getBooleanConditionValueString(settings.showHighlightBox) + ); + const [wasdMode, setWasdMode] = useState( + getBooleanConditionValueString(settings.wasdMode) + ); + const [videoPlaybackSpeed, setVideoPlaybackSpeed] = useState( + settings.videoPlaybackSpeed ?? videoPlaybackSpeeds[2] + ); + + return ( + + Settings + + + + Show Crosshairs + + { + setShowCrosshairs(value); + if (settings.changeSetting) { + const newValue = getBooleanConditionValue(value); + settings.changeSetting("showCrosshairs", newValue); + } + }} + > + {booleanCondition.map((condition) => ( + } + label={condition.label} + /> + ))} + + + + + Show Highlight Box + + { + setShowHighlightBox(value); + if (settings.changeSetting) { + const newValue = getBooleanConditionValue(value); + settings.changeSetting("showHighlightBox", newValue); + } + }} + > + {booleanCondition.map((condition) => ( + } + label={condition.label} + /> + ))} + + + + WASD Mode + { + setWasdMode(value); + if (settings.changeSetting) { + const newValue = getBooleanConditionValue(value); + settings.changeSetting("wasdMode", newValue); + } + }} + > + {booleanCondition.map((condition) => ( + } + label={condition.label} + /> + ))} + + + + Video Playback Speed + + + + + + + + ); +}; + +export default SettingsDialog; diff --git a/src/SettingsProvider/index.js b/src/SettingsProvider/index.js deleted file mode 100644 index 6d59847c..00000000 --- a/src/SettingsProvider/index.js +++ /dev/null @@ -1,44 +0,0 @@ -// @flow - -import React, { createContext, useContext, useState } from "react" - -const defaultSettings = { - showCrosshairs: false, - showHighlightBox: true, - wasdMode: true, -} - -export const SettingsContext = createContext(defaultSettings) - -const pullSettingsFromLocalStorage = () => { - if (!window || !window.localStorage) return {} - let settings = {} - for (let i = 0; i < window.localStorage.length; i++) { - const key = window.localStorage.key(i) - if (key.startsWith("settings_")) { - try { - settings[key.replace("settings_", "")] = JSON.parse( - window.localStorage.getItem(key) - ) - } catch (e) {} - } - } - return settings -} - -export const useSettings = () => useContext(SettingsContext) - -export const SettingsProvider = ({ children }) => { - const [state, changeState] = useState(() => pullSettingsFromLocalStorage()) - const changeSetting = (setting: string, value: any) => { - changeState({ ...state, [setting]: value }) - window.localStorage.setItem(`settings_${setting}`, JSON.stringify(value)) - } - return ( - - {children} - - ) -} - -export default SettingsProvider diff --git a/src/SettingsProvider/index.tsx b/src/SettingsProvider/index.tsx new file mode 100644 index 00000000..bd0ab6f4 --- /dev/null +++ b/src/SettingsProvider/index.tsx @@ -0,0 +1,62 @@ + + +import { createContext, ReactNode, useContext, useState } from "react"; + +interface SettingsValue { + showCrosshairs: boolean; + showHighlightBox: boolean; + wasdMode: boolean; + videoPlaybackSpeed?: string; + changeSetting: ( + setting: keyof Omit, + value: any + ) => void; +} + +const defaultSettings: SettingsValue = { + showCrosshairs: false, + showHighlightBox: true, + wasdMode: true, + changeSetting: () => {}, +}; + +export const SettingsContext = + createContext>(defaultSettings); + +const pullSettingsFromLocalStorage = (): Partial => { + if (!window || !window.localStorage) return {}; + let settings: Record = {}; + for (let i = 0; i < window.localStorage.length; i++) { + const key = window.localStorage.key(i); + if (key && key?.startsWith("settings_")) { + try { + const value = window.localStorage.getItem(key); + if (value) { + settings[key.replace("settings_", "")] = JSON.parse(value); + } + } catch (e) {} + } + } + return settings; +}; + +export const useSettings = () => useContext(SettingsContext); + +export const SettingsProvider = ({ children }: { children: ReactNode }) => { + const [state, changeState] = useState>(() => + pullSettingsFromLocalStorage() + ); + + const changeSetting = (setting: string, value: any) => { + changeState({ ...state, [setting]: value }); + window.localStorage.setItem(`settings_${setting}`, JSON.stringify(value)); + }; + + return ( + + {children} + + ); +}; + +export default SettingsProvider; diff --git a/src/Shortcuts/ShortcutField.js b/src/Shortcuts/ShortcutField.js deleted file mode 100644 index 9eda4600..00000000 --- a/src/Shortcuts/ShortcutField.js +++ /dev/null @@ -1,44 +0,0 @@ -import React from "react" -import TextField from "@mui/material/TextField" -import { makeStyles } from "@mui/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" - -const theme = createTheme() -const useStyles = makeStyles((theme) => ({ - shortcutKeyFieldWrapper: { - paddingTop: 8, - display: "inline-flex", - width: "100%", - }, - shortcutKeyText: { - lineHeight: 0, - }, - shortcutTextfield: { - width: "100%", - boxSizing: "border-box", - textAlign: "center", - }, -})) - -const ShortcutField = ({ actionId, actionName, keyName, onChangeShortcut }) => { - const classes = useStyles() - - return ( - -
- { - onChangeShortcut(actionId, e.key) - e.stopPropagation() - }} - /> -
-
- ) -} - -export default ShortcutField diff --git a/src/Shortcuts/index.js b/src/Shortcuts/index.js deleted file mode 100644 index 92f3de6a..00000000 --- a/src/Shortcuts/index.js +++ /dev/null @@ -1,129 +0,0 @@ -import React, { useState, useEffect } from "react" -import SidebarBoxContainer from "../SidebarBoxContainer" -import { setIn } from "seamless-immutable" -import ShortcutField from "./ShortcutField" - -const defaultShortcuts = { - select: { - action: { - type: "SELECT_TOOL", - }, - name: "Select Region", - key: "Escape", - }, - zoom: { - action: { - type: "SELECT_TOOL", - }, - name: "Zoom In/Out", - key: "z", - }, - "create-point": { - action: { - type: "SELECT_TOOL", - }, - name: "Create Point", - }, - "create-box": { - action: { - type: "SELECT_TOOL", - }, - name: "Add Bounding Box", - key: "b", - }, - pan: { - action: { - type: "SELECT_TOOL", - }, - name: "Pan", - }, - "create-polygon": { - action: { - type: "SELECT_TOOL", - }, - name: "Create Polygon", - }, - "create-pixel": { - action: { - type: "SELECT_TOOL", - }, - name: "Create Pixel", - }, - "prev-image": { - action: { - type: "HEADER_BUTTON_CLICKED", - buttonName: "Prev", - }, - name: "Previous Image", - key: "a", - }, - "next-image": { - action: { - type: "HEADER_BUTTON_CLICKED", - buttonName: "Next", - }, - name: "Next Image", - key: "d", //"ArrowRight" - }, -} - -export default ({ onShortcutActionDispatched }) => { - const [shortcuts, setShortcuts] = useState({}) // useLocalStorage - - useEffect(() => { - const newShortcuts = { ...shortcuts } - for (const actionId of Object.keys(defaultShortcuts)) { - if (!newShortcuts[actionId]) { - newShortcuts[actionId] = defaultShortcuts[actionId] - } - } - setShortcuts(newShortcuts) - }, []) - - const onChangeShortcut = (actionId, keyName) => { - setShortcuts(setIn(shortcuts, [actionId, "key"], keyName)) - } - - useEffect(() => { - const handleKeyPress = (e) => { - for (const actionId in shortcuts) { - const shortcut = shortcuts[actionId] - if (!shortcut || !shortcut.key) { - continue - } - if (e.key === shortcut.key) { - onShortcutActionDispatched({ - ...shortcut.action, - selectedTool: actionId, - }) - } - } - } - - window.addEventListener("keypress", handleKeyPress) - - return () => { - window.removeEventListener("keypress", handleKeyPress) - document.activeElement.blur() - } - }, [shortcuts]) - - return ( - - {Object.keys(shortcuts) - .map((actionId, index) => { - if (!shortcuts[actionId]) return null - return ( - - ) - }) - .filter(Boolean)} - - ) -} diff --git a/src/ShortcutsManager/index.js b/src/ShortcutsManager/index.tsx similarity index 81% rename from src/ShortcutsManager/index.js rename to src/ShortcutsManager/index.tsx index 2a62bf6e..88f860d3 100644 --- a/src/ShortcutsManager/index.js +++ b/src/ShortcutsManager/index.tsx @@ -1,5 +1,6 @@ -import React, { useMemo } from "react" -import { HotKeys } from "react-hotkeys" +import { ReactNode, useMemo } from "react"; +import { HotKeys } from "react-hotkeys"; +import { Action } from "../MainLayout/types.ts"; export const defaultHotkeys = [ { @@ -63,82 +64,88 @@ export const defaultHotkeys = [ description: "Undo latest change", binding: "Ctrl+z", }, -] -export const defaultKeyMap = {} -for (const { id, binding } of defaultHotkeys) defaultKeyMap[id] = binding +]; -export const useDispatchHotkeyHandlers = ({ dispatch }) => { - const handlers = useMemo( +export const defaultKeyMap: Record = {}; + +for (const { id, binding } of defaultHotkeys) defaultKeyMap[id] = binding; + +export const useDispatchHotkeyHandlers = ({ + dispatch, +}: { + dispatch: (action: Action) => void; +}) => { + return useMemo( () => ({ select_tool: () => { dispatch({ type: "SELECT_TOOL", selectedTool: "select", - }) + }); }, zoom_tool: () => { dispatch({ type: "SELECT_TOOL", selectedTool: "zoom", - }) + }); }, create_point: () => { dispatch({ type: "SELECT_TOOL", selectedTool: "create-point", - }) + }); }, create_bounding_box: () => { dispatch({ type: "SELECT_TOOL", selectedTool: "create-box", - }) + }); }, pan_tool: () => { dispatch({ type: "SELECT_TOOL", selectedTool: "pan", - }) + }); }, create_polygon: () => { dispatch({ type: "SELECT_TOOL", selectedTool: "create-polygon", - }) + }); }, create_pixel: () => { dispatch({ type: "SELECT_TOOL", selectedTool: "create-pixel", - }) + }); }, save_and_previous_sample: () => { dispatch({ type: "HEADER_BUTTON_CLICKED", buttonName: "Prev", - }) + }); }, save_and_next_sample: () => { dispatch({ type: "HEADER_BUTTON_CLICKED", buttonName: "Next", - }) + }); }, save_and_exit_sample: () => { dispatch({ type: "HEADER_BUTTON_CLICKED", buttonName: "Save", - }) + }); }, delete_region: () => { dispatch({ type: "DELETE_SELECTED_REGION", - }) + }); }, undo: () => { dispatch({ type: "RESTORE_HISTORY", - }) + }); }, // TODO // exit_sample: () => { @@ -148,15 +155,20 @@ export const useDispatchHotkeyHandlers = ({ dispatch }) => { // } }), [dispatch] - ) - return handlers -} + ); +}; -export default ({ children, dispatch }) => { - const handlers = useDispatchHotkeyHandlers({ dispatch }) +export default ({ + children, + dispatch, +}: { + children: ReactNode; + dispatch: (action: Action) => void; +}) => { + const handlers = useDispatchHotkeyHandlers({ dispatch }); return ( {children} - ) -} + ); +}; diff --git a/src/Sidebar/index.js b/src/Sidebar/index.js deleted file mode 100644 index 413973a8..00000000 --- a/src/Sidebar/index.js +++ /dev/null @@ -1,117 +0,0 @@ -// @flow - -import React from "react" -import { styled } from "@mui/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" -import TaskDescription from "../TaskDescriptionSidebarBox" -import ImageSelector from "../ImageSelectorSidebarBox" -import RegionSelector from "../RegionSelectorSidebarBox" -import History from "../HistorySidebarBox" -import DebugBox from "../DebugSidebarBox" -import TagsSidebarBox from "../TagsSidebarBox" -import KeyframesSelector from "../KeyframesSelectorSidebarBox" -import type { Region } from "../ImageCanvas/region-tools.js" - -const theme = createTheme() -const Container = styled("div")(({ theme }) => ({})) - -type Image = { - name: string, - src: string, - cls?: string, - tags?: Array, - thumbnailSrc?: string, - regions?: Array, -} - -type Props = { - debug: any, - taskDescription: string, - images?: Array, - regions: Array, - history: Array<{ state: Object, name: string, time: Date }>, - - labelImages?: boolean, - currentImage?: Image, - imageClsList?: Array, - imageTagList?: Array, - - onChangeImage: (Image) => any, - onSelectRegion: (Region) => any, - onSelectImage: (Image) => any, - onChangeRegion: (Region) => any, - onDeleteRegion: (Region) => any, - onRestoreHistory: () => any, - onShortcutActionDispatched: (action: any) => any, -} - -const emptyArr = [] - -export const Sidebar = ({ - debug, - taskDescription, - keyframes, - images, - regions, - history, - labelImages, - currentImage, - currentVideoTime, - imageClsList, - imageTagList, - onChangeImage, - onSelectRegion, - onSelectImage, - onChangeRegion, - onDeleteRegion, - onRestoreHistory, - onChangeVideoTime, - onDeleteKeyframe, - onShortcutActionDispatched, -}: Props) => { - if (!regions) regions = emptyArr - - return ( - - - {debug && } - {taskDescription && (taskDescription || "").length > 1 && ( - - )} - {labelImages && ( - - )} - {/* {images && images.length > 1 && ( - - )} */} - - {keyframes && ( - - )} - onRestoreHistory()} - /> - {/* */} - - - ) -} - -export default Sidebar diff --git a/src/SidebarBoxContainer/index.js b/src/SidebarBoxContainer/index.js deleted file mode 100644 index fffc3c3c..00000000 --- a/src/SidebarBoxContainer/index.js +++ /dev/null @@ -1,93 +0,0 @@ -// @flow - -import React, { useState, memo } from "react" -import Paper from "@mui/material/Paper" -import { makeStyles } from "@mui/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" -import ExpandIcon from "@mui/icons-material/ExpandMore" -import IconButton from "@mui/material/IconButton" -import Collapse from "@mui/material/Collapse" -import { grey } from "@mui/material/colors" -import classnames from "classnames" -import useEventCallback from "use-event-callback" -import SidebarBox from "react-material-workspace-layout/SidebarBox" - -const theme = createTheme() -const useStyles = makeStyles((theme) => ({ - container: { margin: 8 }, - header: { - display: "flex", - flexDirection: "row", - alignItems: "center", - padding: 8, - paddingLeft: 16, - paddingRight: 16, - }, - title: { - fontSize: 14, - fontWeight: "bold", - flexGrow: 1, - paddingLeft: 8, - color: grey[800], - "& span": { - color: grey[600], - fontSize: 12, - }, - }, - expandButton: { - padding: 0, - width: 30, - height: 30, - "& .icon": { - marginTop: -6, - width: 20, - height: 20, - transition: "500ms transform", - "&.expanded": { - transform: "rotate(180deg)", - }, - }, - }, - expandedContent: { - maxHeight: 300, - overflowY: "auto", - "&.noScroll": { - overflowY: "visible", - overflow: "visible", - }, - }, -})) - -export const SidebarBoxContainer = ({ - icon, - title, - subTitle, - children, - noScroll = false, - expandedByDefault = false, -}) => { - const classes = useStyles() - const content = ( -
- {children} -
- ) - - const [expanded, changeExpanded] = useState(expandedByDefault) - const toggleExpanded = useEventCallback(() => changeExpanded(!expanded)) - - return ( - - - {children} - - - ) -} - -export default memo( - SidebarBoxContainer, - (prev, next) => prev.title === next.title && prev.children === next.children -) diff --git a/src/SidebarBoxContainer/index.tsx b/src/SidebarBoxContainer/index.tsx new file mode 100644 index 00000000..cf8db7b2 --- /dev/null +++ b/src/SidebarBoxContainer/index.tsx @@ -0,0 +1,34 @@ + + +import { memo, ReactNode } from "react"; +import { createTheme, ThemeProvider } from "@mui/material/styles"; +import { SidebarBox } from "../workspace/SidebarBox"; + +const theme = createTheme(); + +interface SidebarBoxContainerProps { + icon?: ReactNode; + title: string; + children: ReactNode; + noScroll?: boolean; + expandedByDefault?: boolean; +} + +export const SidebarBoxContainer = ({ + icon, + title, + children, +}: SidebarBoxContainerProps) => { + return ( + + + {children} + + + ); +}; + +export default memo( + SidebarBoxContainer, + (prev, next) => prev.title === next.title && prev.children === next.children +); diff --git a/src/SmallToolButton/index.js b/src/SmallToolButton/index.js deleted file mode 100644 index 4853a3f6..00000000 --- a/src/SmallToolButton/index.js +++ /dev/null @@ -1,57 +0,0 @@ -// @flow - -import React, { createContext, useContext, memo } from "react" -import IconButton from "@mui/material/IconButton" -import Tooltip from "@mui/material/Tooltip" -import { blue } from "@mui/material/colors" - -export const SelectedTool = createContext() - -export const SmallToolButton = ({ - id, - name, - icon, - selected, - togglable, - alwaysShowing = false, -}: { - id: string, - name: string, - icon: any, - alwaysShowing?: boolean, - selected?: boolean, - togglable?: boolean, -}) => { - const { enabledTools, selectedTool, onClickTool } = useContext(SelectedTool) - if (!enabledTools.includes(id) && !alwaysShowing) return null - selected = selected || selectedTool === id - return ( - -
- onClickTool(id)} - size="small" - style={{ - width: 50, - height: 50, - margin: 1, - color: selected ? blue[500] : undefined, - }} - > - {icon} - -
-
- ) -} - -export default memo( - SmallToolButton, - (prevProps, nextProps) => - prevProps.togglable === nextProps.togglable && - prevProps.selected === nextProps.selected && - prevProps.name === nextProps.name && - prevProps.id === nextProps.id -) diff --git a/src/TagsSidebarBox/index.js b/src/TagsSidebarBox/index.tsx similarity index 57% rename from src/TagsSidebarBox/index.js rename to src/TagsSidebarBox/index.tsx index 888491cc..9a22bf37 100644 --- a/src/TagsSidebarBox/index.js +++ b/src/TagsSidebarBox/index.tsx @@ -1,23 +1,22 @@ -// @flow -import React, { useMemo, memo } from "react" -import SidebarBoxContainer from "../SidebarBoxContainer" -import StyleIcon from "@mui/icons-material/Style" -import { grey } from "@mui/material/colors" -import Select from "react-select" -import useEventCallback from "use-event-callback" -import { asMutable } from "seamless-immutable" + +import { memo, useMemo } from "react"; +import SidebarBoxContainer from "../SidebarBoxContainer"; +import StyleIcon from "@mui/icons-material/Style"; +import { grey } from "@mui/material/colors"; +import useEventCallback from "use-event-callback"; +import Select, { MultiValue } from "react-select"; type Props = { - tags: Array, - currentImage: { cls?: string, tags?: Array }, - imageClsList?: Array, - imageTagList?: Array, - onChangeImage: (Array) => any, -} + currentImage: { cls?: string; tags?: Array } | null; + imageClsList?: Array; + imageTagList?: Array; + onChangeImage: (image: { cls?: string; tags?: Array }) => void; + expandedByDefault?: boolean; +}; -const emptyArr = [] -const noop = () => null +const emptyArr: string[] = []; +const noop = ({}) => {}; export const TagsSidebarBox = ({ currentImage, @@ -25,31 +24,32 @@ export const TagsSidebarBox = ({ imageTagList = emptyArr, onChangeImage = noop, }: Props) => { - const { tags = [], cls = null } = currentImage || {} + const { tags = [], cls = null } = currentImage || {}; const onChangeClassification = useEventCallback((o) => onChangeImage({ cls: o.value }) - ) - const onChangeTags = useEventCallback((o) => - onChangeImage({ tags: o.map((a) => a.value) }) - ) + ); + const onChangeTags = useEventCallback( + (o: MultiValue<{ value: string; label: string }>) => + onChangeImage({ tags: o.map((a) => a.value) }) + ); const selectValue = useMemo( () => (cls ? { value: cls, label: cls } : null), [cls] - ) + ); const memoImgClsList = useMemo( - () => asMutable(imageClsList.map((c) => ({ value: c, label: c }))), + () => imageClsList.map((c) => ({ value: c, label: c })), [imageClsList] - ) + ); const memoImgTagList = useMemo( - () => asMutable(imageTagList.map((c) => ({ value: c, label: c }))), + () => imageTagList.map((c) => ({ value: c, label: c })), [imageTagList] - ) + ); const memoCurrentTags = useMemo( () => tags.map((r) => ({ value: r, label: r })), [tags] - ) + ); - if (!currentImage) return null + if (!currentImage) return null; return ( )} - ) -} + ); +}; export default memo( TagsSidebarBox, (prevProps, nextProps) => - prevProps.currentImage.cls === nextProps.currentImage.cls && - prevProps.currentImage.tags === nextProps.currentImage.tags && + prevProps.currentImage?.cls === nextProps.currentImage?.cls && + prevProps.currentImage?.tags === nextProps.currentImage?.tags && prevProps.imageClsList === nextProps.imageClsList && prevProps.imageTagList === nextProps.imageTagList -) +); diff --git a/src/TaskDescriptionSidebarBox/index.js b/src/TaskDescriptionSidebarBox/index.js deleted file mode 100644 index 728f82ca..00000000 --- a/src/TaskDescriptionSidebarBox/index.js +++ /dev/null @@ -1,43 +0,0 @@ -// @flow - -import React, { memo } from "react" -import SidebarBoxContainer from "../SidebarBoxContainer" -import DescriptionIcon from "@mui/icons-material/Description" -import { styled } from "@mui/material/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" -import { grey } from "@mui/material/colors" -import Markdown from "react-markdown" - -const theme = createTheme() -const MarkdownContainer = styled("div")(({ theme }) => ({ - paddingLeft: 16, - paddingRight: 16, - fontSize: 12, - "& h1": { fontSize: 18 }, - "& h2": { fontSize: 14 }, - "& h3": { fontSize: 12 }, - "& h4": { fontSize: 12 }, - "& h5": { fontSize: 12 }, - "& h6": { fontSize: 12 }, - "& p": { fontSize: 12 }, - "& a": {}, - "& img": { width: "100%" }, -})) - -export const TaskDescriptionSidebarBox = ({ description }) => { - return ( - - } - expandedByDefault={description && description !== "" ? false : true} - > - - - - - - ) -} - -export default memo(TaskDescriptionSidebarBox) diff --git a/src/TaskDescriptionSidebarBox/index.tsx b/src/TaskDescriptionSidebarBox/index.tsx new file mode 100644 index 00000000..128d0b46 --- /dev/null +++ b/src/TaskDescriptionSidebarBox/index.tsx @@ -0,0 +1,46 @@ + + +import { memo } from "react"; +import SidebarBoxContainer from "../SidebarBoxContainer"; +import DescriptionIcon from "@mui/icons-material/Description"; +import { createTheme, styled, ThemeProvider } from "@mui/material/styles"; +import { grey } from "@mui/material/colors"; +import Markdown from "react-markdown"; + +const theme = createTheme(); +const MarkdownContainer = styled("div")(() => ({ + paddingLeft: 16, + paddingRight: 16, + fontSize: 12, + "& h1": { fontSize: 18 }, + "& h2": { fontSize: 14 }, + "& h3": { fontSize: 12 }, + "& h4": { fontSize: 12 }, + "& h5": { fontSize: 12 }, + "& h6": { fontSize: 12 }, + "& p": { fontSize: 12 }, + "& a": {}, + "& img": { width: "100%" }, +})); + +export const TaskDescriptionSidebarBox = ({ + description, +}: { + description?: string; +}) => { + return ( + + } + expandedByDefault={!(description && description !== "")} + > + + + + + + ); +}; + +export default memo(TaskDescriptionSidebarBox); diff --git a/src/Theme/index.js b/src/Theme/index.js deleted file mode 100644 index 4c4be964..00000000 --- a/src/Theme/index.js +++ /dev/null @@ -1,36 +0,0 @@ -// @flow - -import React from "react" -import { ThemeProvider, createTheme } from "@mui/material/styles" -import { makeStyles } from "@mui/styles" - -const useStyles = makeStyles((theme) => ({ - container: { - fontFamily: '"Inter", sans-serif', - }, -})) - -const theme = createTheme({ - typography: { - fontFamily: '"Inter", "Roboto", sans-serif', - }, - overrides: { - MuiButton: { - root: { - textTransform: "none", - }, - }, - }, -}) - -export const Theme = ({ children }: any) => { - const classes = useStyles() - return ( - - {/*
{children}
*/} -
{children}
-
- ) -} - -export default Theme diff --git a/src/Theme/index.tsx b/src/Theme/index.tsx new file mode 100644 index 00000000..bb6cdcaa --- /dev/null +++ b/src/Theme/index.tsx @@ -0,0 +1,36 @@ + + +import { createTheme, ThemeProvider } from "@mui/material/styles"; +import { ReactNode } from "react"; + +// const useStyles = makeStyles(() => ({ +// container: { +// fontFamily: '"Inter", sans-serif', +// }, +// })); + +const theme = createTheme({ + typography: { + fontFamily: '"Inter", "Roboto", sans-serif', + }, + components: { + MuiButton: { + styleOverrides: { + root: { + textTransform: "none", + }, + }, + }, + }, +}); + +export const Theme = ({ children }: { children: ReactNode }) => { + return ( + + {/*
{children}
*/} +
{children}
+
+ ); +}; + +export default Theme; diff --git a/src/VideoOrImageCanvasBackground/index.js b/src/VideoOrImageCanvasBackground/index.js deleted file mode 100644 index e6254ed1..00000000 --- a/src/VideoOrImageCanvasBackground/index.js +++ /dev/null @@ -1,170 +0,0 @@ -// @flow weak - -import React, { useRef, useEffect, useMemo, useState } from "react" -import { styled } from "@mui/material/styles" -import { createTheme, ThemeProvider } from "@mui/material/styles" -import useEventCallback from "use-event-callback" -import { useSettings } from "../SettingsProvider" - -const theme = createTheme() -const Video = styled("video")(({ theme }) => ({ - zIndex: 0, - position: "absolute", -})) - -const StyledImage = styled("img")(({ theme }) => ({ - zIndex: 0, - position: "absolute", -})) - -const Error = styled("div")(({ theme }) => ({ - zIndex: 0, - position: "absolute", - left: 0, - right: 0, - bottom: 0, - top: 0, - backgroundColor: "rgba(255,0,0,0.2)", - color: "#ff0000", - fontWeight: "bold", - whiteSpace: "pre-wrap", - padding: 50, -})) - -export default ({ - imagePosition, - mouseEvents, - videoTime, - videoSrc, - imageSrc, - onLoad, - useCrossOrigin = false, - videoPlaying, - onChangeVideoTime, - onChangeVideoPlaying, -}) => { - const settings = useSettings() - const videoRef = useRef() - const imageRef = useRef() - const [error, setError] = useState() - - useEffect(() => { - if (!videoPlaying && videoRef.current) { - videoRef.current.currentTime = (videoTime || 0) / 1000 - } - }, [videoTime]) - - useEffect(() => { - let renderLoopRunning = false - if (videoRef.current) { - if (videoPlaying) { - videoRef.current.play() - renderLoopRunning = true - if (settings.videoPlaybackSpeed) { - videoRef.current.playbackRate = parseFloat( - settings.videoPlaybackSpeed - ) - } - } else { - videoRef.current.pause() - } - } - - function checkForNewFrame() { - if (!renderLoopRunning) return - if (!videoRef.current) return - const newVideoTime = Math.floor(videoRef.current.currentTime * 1000) - if (videoTime !== newVideoTime) { - onChangeVideoTime(newVideoTime) - } - if (videoRef.current.paused) { - renderLoopRunning = false - onChangeVideoPlaying(false) - } - requestAnimationFrame(checkForNewFrame) - } - checkForNewFrame() - - return () => { - renderLoopRunning = false - } - }, [videoPlaying]) - - const onLoadedVideoMetadata = useEventCallback((event) => { - const videoElm = event.currentTarget - videoElm.currentTime = (videoTime || 0) / 1000 - if (onLoad) - onLoad({ - naturalWidth: videoElm.videoWidth, - naturalHeight: videoElm.videoHeight, - videoElm: videoElm, - duration: videoElm.duration, - }) - }) - const onImageLoaded = useEventCallback((event) => { - const imageElm = event.currentTarget - if (onLoad) - onLoad({ - naturalWidth: imageElm.naturalWidth, - naturalHeight: imageElm.naturalHeight, - imageElm, - }) - }) - const onImageError = useEventCallback((event) => { - setError( - `Could not load image\n\nMake sure your image works by visiting ${ - imageSrc || videoSrc - } in a web browser. If that URL works, the server hosting the URL may be not allowing you to access the image from your current domain. Adjust server settings to enable the image to be viewed.${ - !useCrossOrigin - ? "" - : `\n\nYour image may be blocked because it's not being sent with CORs headers. To do pixel segmentation, browser web security requires CORs headers in order for the algorithm to read the pixel data from the image. CORs headers are easy to add if you're using an S3 bucket or own the server hosting your images.` - }\n\n If you need a hand, reach out to the community at universaldatatool.slack.com` - ) - }) - - const stylePosition = useMemo(() => { - let width = imagePosition.bottomRight.x - imagePosition.topLeft.x - let height = imagePosition.bottomRight.y - imagePosition.topLeft.y - return { - imageRendering: "pixelated", - left: imagePosition.topLeft.x, - top: imagePosition.topLeft.y, - width: isNaN(width) ? 0 : width, - height: isNaN(height) ? 0 : height, - } - }, [ - imagePosition.topLeft.x, - imagePosition.topLeft.y, - imagePosition.bottomRight.x, - imagePosition.bottomRight.y, - ]) - - if (!videoSrc && !imageSrc) - return No imageSrc or videoSrc provided - - if (error) return {error} - - return ( - - {imageSrc && videoTime === undefined ? ( - - ) : ( - - ) -} diff --git a/src/colors.js b/src/colors.ts similarity index 57% rename from src/colors.js rename to src/colors.ts index 0c77255f..4dd7564e 100644 --- a/src/colors.js +++ b/src/colors.ts @@ -1,6 +1,6 @@ -// @flow -import * as muiColors from "@mui/material/colors" + +import * as muiColors from "@mui/material/colors"; export const colors = [ muiColors.red[500], @@ -15,18 +15,19 @@ export const colors = [ muiColors.teal[500], muiColors.lime[500], muiColors.blueGrey[500], -] +]; -const transparency = 0x88000000 +const transparency = 0x88000000; -function reverseParseColor(rrggbb) { - rrggbb = rrggbb.replace("#", "") - const bbggrr = rrggbb.substr(4, 2) + rrggbb.substr(2, 2) + rrggbb.substr(0, 2) - return parseInt(bbggrr, 16) +function reverseParseColor(rrggbb: string) { + rrggbb = rrggbb.replace("#", ""); + const bbggrr = + rrggbb.substr(4, 2) + rrggbb.substr(2, 2) + rrggbb.substr(0, 2); + return parseInt(bbggrr, 16); } export const colorInts: Array = colors.map( (c) => (reverseParseColor(c) | transparency) >>> 0 -) +); -export default colors +export default colors; diff --git a/src/hooks/use-event-callback.js b/src/hooks/use-event-callback.js deleted file mode 100644 index a1eab586..00000000 --- a/src/hooks/use-event-callback.js +++ /dev/null @@ -1,11 +0,0 @@ -// @flow - -import { useRef, useCallback, useLayoutEffect, useEffect } from "react" - -export default (fn) => { - let ref = useRef() - useLayoutEffect(() => { - ref.current = fn - }) - return useCallback((...args) => (0, ref.current)(...args), []) -} diff --git a/src/hooks/use-event-callback.tsx b/src/hooks/use-event-callback.tsx new file mode 100644 index 00000000..af83eb1c --- /dev/null +++ b/src/hooks/use-event-callback.tsx @@ -0,0 +1,17 @@ + + +import { useCallback, useLayoutEffect, useRef } from "react"; + +export default (fn: Function) => { + // @ts-ignore + let ref = useRef(); + + useLayoutEffect(() => { + ref.current = fn; + }); + + return useCallback((...args: any) => { + // @ts-ignore + return (0, ref.current!)(...args); + }, []); +}; diff --git a/src/hooks/use-exclude-pattern.js b/src/hooks/use-exclude-pattern.js deleted file mode 100644 index 9d112dd0..00000000 --- a/src/hooks/use-exclude-pattern.js +++ /dev/null @@ -1,27 +0,0 @@ -// @flow weak - -import { useRef } from "react" -import excludePatternSrc from "./xpattern.js" - -export default () => { - const excludePattern = useRef(null) - if (excludePattern.current === null) { - excludePattern.current = { - image: new Image(), - pattern: null, - } - const canvas = document.createElement("canvas") - canvas.width = 100 - canvas.height = 100 - const context = canvas.getContext("2d") - - excludePattern.current.image.onload = () => { - excludePattern.current.pattern = context.createPattern( - excludePattern.current.image, - "repeat" - ) - } - excludePattern.current.image.src = excludePatternSrc - } - return excludePattern.current.pattern -} diff --git a/src/hooks/use-exclude-pattern.tsx b/src/hooks/use-exclude-pattern.tsx new file mode 100644 index 00000000..f7bf6486 --- /dev/null +++ b/src/hooks/use-exclude-pattern.tsx @@ -0,0 +1,31 @@ +import { useRef } from "react"; +import excludePatternSrc from "./xpattern"; + +export default (): CanvasPattern | null => { + const excludePattern = useRef<{ + image: HTMLImageElement; + pattern: CanvasPattern | null; + } | null>(null); + + if (excludePattern.current === null) { + excludePattern.current = { + image: new Image(), + pattern: null, + }; + const canvas = document.createElement("canvas"); + canvas.width = 100; + canvas.height = 100; + const context = canvas.getContext("2d"); + if (!context) return null; + excludePattern.current.image.onload = () => { + if (excludePattern.current) { + excludePattern.current.pattern = context.createPattern( + excludePattern.current.image, + "repeat" + ); + } + }; + excludePattern.current.image.src = excludePatternSrc; + } + return excludePattern.current.pattern; +}; diff --git a/src/hooks/use-load-image.js b/src/hooks/use-load-image.js deleted file mode 100644 index 7018a739..00000000 --- a/src/hooks/use-load-image.js +++ /dev/null @@ -1,21 +0,0 @@ -// @flow weak - -import { useRef, useState } from "react" - -export default (imageSrc, onImageLoaded) => { - const [imageLoaded, changeImageLoaded] = useState(false) - const image = useRef(null) - if (image.current === null) { - image.current = new Image() - image.current.onload = () => { - changeImageLoaded(true) - if (onImageLoaded) - onImageLoaded({ - width: image.current.naturalWidth, - height: image.current.naturalHeight, - }) - } - image.current.src = imageSrc - } - return [image.current, imageLoaded] -} diff --git a/src/hooks/use-load-image.tsx b/src/hooks/use-load-image.tsx new file mode 100644 index 00000000..5e877365 --- /dev/null +++ b/src/hooks/use-load-image.tsx @@ -0,0 +1,22 @@ +import { useRef, useState } from "react"; + +export default ( + imageSrc: string, + onImageLoaded: (metadata: { width: number; height: number }) => void +) => { + const [imageLoaded, changeImageLoaded] = useState(false); + const image = useRef(null); + if (image.current === null) { + image.current = new Image(); + image.current.onload = () => { + changeImageLoaded(true); + if (onImageLoaded && image.current) + onImageLoaded({ + width: image.current.naturalWidth, + height: image.current.naturalHeight, + }); + }; + image.current.src = imageSrc; + } + return [image.current, imageLoaded]; +}; diff --git a/src/hooks/use-window-size.js b/src/hooks/use-window-size.tsx similarity index 99% rename from src/hooks/use-window-size.js rename to src/hooks/use-window-size.tsx index ee6efb0c..ab98b83d 100644 --- a/src/hooks/use-window-size.js +++ b/src/hooks/use-window-size.tsx @@ -1,4 +1,4 @@ -// @flow + import { useEffect } from "react" diff --git a/src/hooks/xpattern.png b/src/hooks/xpattern.png deleted file mode 100644 index 3c71072a..00000000 Binary files a/src/hooks/xpattern.png and /dev/null differ diff --git a/src/hooks/xpattern.js b/src/hooks/xpattern.ts similarity index 100% rename from src/hooks/xpattern.js rename to src/hooks/xpattern.ts diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 2ea54bcb..00000000 --- a/src/index.js +++ /dev/null @@ -1,18 +0,0 @@ -// @flow - -import React from "react" -import ReactDOM from "react-dom" -import Theme from "./Theme" -import DemoSite from "./DemoSite" -import LandingPage from "./LandingPage" -import "./site.css" - -const Site = () => { - const path = window.location.pathname - .replace(/\/$/, "") - .split("/") - .slice(-1)[0] - return {path === "demo" ? : } -} - -ReactDOM.render(, document.getElementById("root")) diff --git a/src/index.tsx b/src/index.tsx new file mode 100644 index 00000000..b951e801 --- /dev/null +++ b/src/index.tsx @@ -0,0 +1,18 @@ + + +import { createRoot } from "react-dom/client"; +import Theme from "./Theme"; +import DemoSite from "./DemoSite"; +import "./site.css"; + +const Site = () => { + return ( + + + + ); +}; + +const container = document.getElementById("root")!; +const root = createRoot(container); // createRoot(container!) if you use TypeScript +root.render(); diff --git a/src/lib.js b/src/lib.js deleted file mode 100644 index 0feffc7a..00000000 --- a/src/lib.js +++ /dev/null @@ -1,7 +0,0 @@ -// @flow - -import Annotator from "./Annotator" - -export { Annotator } - -export default Annotator diff --git a/src/lib.tsx b/src/lib.tsx new file mode 100644 index 00000000..76ddf06c --- /dev/null +++ b/src/lib.tsx @@ -0,0 +1,28 @@ +import Annotator from "./Annotator"; + +// re-export types +export type { AnnotatorProps, AnnotatorRef } from "./Annotator"; +export type { + MainLayoutState, + MainLayoutImageAnnotationState, + MainLayoutStateBase, + AnnotatorToolEnum, +} from "./MainLayout/types"; + +export type { + Region, + BaseRegion, + Box, + PixelRegion, + ExpandingLine, + KeypointDefinition, + Keypoints, + Line, + Polygon, + Point, + KeypointsDefinition, +} from "./types/region-tools"; + +export { Annotator }; + +export default Annotator; diff --git a/src/screenshot.png b/src/screenshot.png deleted file mode 100644 index 7eafcda4..00000000 Binary files a/src/screenshot.png and /dev/null differ diff --git a/src/stories.js b/src/stories.js deleted file mode 100644 index 3888b78f..00000000 --- a/src/stories.js +++ /dev/null @@ -1,2 +0,0 @@ -const importAll = (r) => r.keys().map(r) -importAll(require.context("./", true, /\.story\.js$/)) diff --git a/src/types/austoseg-webworker.d.ts b/src/types/austoseg-webworker.d.ts new file mode 100644 index 00000000..741c930e --- /dev/null +++ b/src/types/austoseg-webworker.d.ts @@ -0,0 +1,22 @@ +declare module "autoseg/webworker" { + type AutosegType = "simple" | "autoseg"; + + export type AutosegOptions = + | { type: "simple" } + | { type: "autoseg"; maxClusters?: number; slicWeightFactor?: number }; + + export type AutosegConfig = { + type: AutosegType; + maxClusters?: number; + classColors?: number[]; + classNames: string[]; + }; + + export const Autoseg: { + setConfig: (config: AutosegConfig) => void; + loadImage: (imageData: ImageData) => void; + getMask: (regions: any[]) => Promise; + }; + + export default Autoseg; +} diff --git a/src/types/common.ts b/src/types/common.ts new file mode 100644 index 00000000..a558a9c6 --- /dev/null +++ b/src/types/common.ts @@ -0,0 +1,13 @@ +export interface ImagePosition { + topLeft: { x: number; y: number }; + bottomRight: { x: number; y: number }; +} + +export interface IconSidebarItem { + name: string; + helperText: string; + alwaysShowing?: boolean; + selected?: boolean; + disabled?: boolean; + onClick?: (item: IconSidebarItem) => void; +} diff --git a/src/types/region-tools.ts b/src/types/region-tools.ts new file mode 100644 index 00000000..14ee68a0 --- /dev/null +++ b/src/types/region-tools.ts @@ -0,0 +1,164 @@ + + +export type BaseRegion = { + id: string | number; + cls?: string; + locked?: boolean; + visible?: boolean; + color: string; + editingLabels?: boolean; + highlighted?: boolean; + tags?: Array; + comment?: string; +}; + +export type Point = BaseRegion & { + type: "point"; + x: number; + y: number; +}; + +export type PixelRegion = + | (BaseRegion & { + type: "pixel"; + sx: number; + sy: number; + w: number; + h: number; + src: string; + }) + | (BaseRegion & { + type: "pixel"; + points: Array<[number, number]>; + }); + +export type Box = BaseRegion & { + type: "box"; + x: number; + y: number; + w: number; + h: number; +}; + +export type Polygon = BaseRegion & { + type: "polygon"; + open?: boolean; + points: Array<[number, number]>; +}; + +export type Line = BaseRegion & { + type: "line"; + x1: number; + y1: number; + x2: number; + y2: number; +}; + +export type ExpandingLine = BaseRegion & { + type: "expanding-line"; + points: Array<{ + x: number; + y: number; + angle: number | null; + width: number | null; + }>; + expandingWidth?: number; + candidatePoint?: { x: number; y: number }; + unfinished?: boolean; +}; + +export type KeypointDefinition = BaseRegion & { + label: string; + color: string; + defaultPosition: [number, number]; +}; + +export type KeypointId = string; + +export type KeypointsDefinition = { + [id: string]: { + connections: Array<[KeypointId, KeypointId]>; + landmarks: { + [key: KeypointId]: KeypointDefinition; + }; + }; +}; + +export type Keypoints = BaseRegion & { + type: "keypoints"; + keypointsDefinitionId: string; + points: { + [key: string]: { x: number; y: number }; + }; + open?: boolean; +}; + +export type Region = + | Point + | PixelRegion + | Box + | Polygon + | ExpandingLine + | Keypoints; +export const getEnclosingBox = (region: Region | Line) => { + switch (region.type) { + case "polygon": { + const box = { + x: Math.min(...region.points.map(([x]) => x)), + y: Math.min(...region.points.map(([_, y]) => y)), + w: 0, + h: 0, + }; + box.w = Math.max(...region.points.map(([x]) => x)) - box.x; + box.h = Math.max(...region.points.map(([_, y]) => y)) - box.y; + return box; + } + case "keypoints": { + const minX = Math.min(...Object.values(region.points).map(({ x }) => x)); + const minY = Math.min(...Object.values(region.points).map(({ y }) => y)); + const maxX = Math.max(...Object.values(region.points).map(({ x }) => x)); + const maxY = Math.max(...Object.values(region.points).map(({ y }) => y)); + return { + x: minX, + y: minY, + w: maxX - minX, + h: maxY - minY, + }; + } + case "expanding-line": { + const box = { + x: Math.min(...region.points.map(({ x }) => x)), + y: Math.min(...region.points.map(({ y }) => y)), + w: 0, + h: 0, + }; + box.w = Math.max(...region.points.map(({ x }) => x)) - box.x; + box.h = Math.max(...region.points.map(({ y }) => y)) - box.y; + return box; + } + case "line": { + return { x: region.x1, y: region.y1, w: 0, h: 0 }; + } + case "box": { + return { x: region.x, y: region.y, w: region.w, h: region.h }; + } + case "point": { + return { x: region.x, y: region.y, w: 0, h: 0 }; + } + default: { + return { x: 0, y: 0, w: 0, h: 0 }; + } + } +}; + +export const moveRegion = (region: Region, x: number, y: number) => { + switch (region.type) { + case "point": { + return { ...region, x, y }; + } + case "box": { + return { ...region, x: x - region.w / 2, y: y - region.h / 2 }; + } + } + return region; +}; diff --git a/src/types/transformation-matrix-js.d.ts b/src/types/transformation-matrix-js.d.ts new file mode 100644 index 00000000..1065dfb9 --- /dev/null +++ b/src/types/transformation-matrix-js.d.ts @@ -0,0 +1,112 @@ +declare module "transformation-matrix-js" { + const Matrix = class Matrix { + constructor(context: CanvasRenderingContext2D, element: HTMLElement); + + concat(matrix: Matrix): Matrix; + + flipX(): Matrix; + + flipY(): Matrix; + + reflectVector(x: number, y: number): Matrix; + + reset(): Matrix; + + rotate(angle: number): Matrix; + + rotateFromVector(x: number, y: number): Matrix; + + rotateDeg(angle: number): Matrix; + + scaleU(scale: number): Matrix; + + scale: (x: number, y: number) => Matrix; + + scaleX(scale: number): Matrix; + + scaleY(scale: number): Matrix; + + scaleFromVector(x: number, y: number): Matrix; + + shear(sx: number, sy: number): Matrix; + + shearX(sx: number): Matrix; + + shearY(sy: number): Matrix; + + skew(ax: number, ay: number): Matrix; + + skewDeg(ax: number, ay: number): Matrix; + + skewX(ax: number): Matrix; + + skewY(ay): Matrix; + + setTransform( + a: number, + b: number, + c: number, + d: number, + e: number, + f: number + ): Matrix; + + translate(tx: number, ty: number): Matrix; + + translateX(tx: number): Matrix; + + translateY(ty: number): Matrix; + + transform( + a: number, + b: number, + c: number, + d: number, + e: number, + f: number + ): Matrix; + + multiply(matrix: Matrix): Matrix; + + divide(matrix: Matrix): Matrix; + + divideScalar(scalar: number): Matrix; + + inverse(cloneContext?: boolean, cloneDom?: boolean): Matrix; + + interpolate( + matrix: Matrix, + t: number, + context: CanvasRenderingContext2D + ): Matrix; + + clone(noContext?: boolean): Matrix; + + applyToPoint(x: number, y: number): Matrix; + + applyToArray(points: { x: number; y: number }[] | number[]): number[]; + + toArray(): number[]; + + static from( + a: number, + b: number, + c: number, + d: number, + e: number, + f: number + ): Matrix; + static from(m: Matrix): Matrix; + static from(m: Matrix, ctx: CanvasRenderingContext2D): Matrix; + }; + + export type IMatrix = Matrix & { + a: number; + b: number; + c: number; + d: number; + e: number; + f: number; + }; + export { Matrix }; +} diff --git a/src/types/use-key-hook.d.ts b/src/types/use-key-hook.d.ts new file mode 100644 index 00000000..582a50ba --- /dev/null +++ b/src/types/use-key-hook.d.ts @@ -0,0 +1,11 @@ +declare module "use-key-hook" { + export type KeyHandler = (event: KeyboardEvent) => void; + export type KeyBinding = string | string[]; + export type KeyBindingConfig = { + detectKeys: string | number | Array; + }; + export default function useKey( + fn: KeyHandler, + keys: KeyBinding | KeyBindingConfig + ): void; +} diff --git a/src/utils/clamp.ts b/src/utils/clamp.ts new file mode 100644 index 00000000..d688a36b --- /dev/null +++ b/src/utils/clamp.ts @@ -0,0 +1,5 @@ +export const clamp = (value: number, min: number, max: number) => { + return min < max + ? (value < min ? min : value > max ? max : value) + : (value < max ? max : value > min ? min : value) +} diff --git a/src/utils/get-from-local-storage.js b/src/utils/get-from-local-storage.js deleted file mode 100644 index 9139137e..00000000 --- a/src/utils/get-from-local-storage.js +++ /dev/null @@ -1,7 +0,0 @@ -export default (key, defaultValue) => { - try { - return JSON.parse(window.localStorage[`__REACT_IMAGE_ANNOTATE_${key}`]) - } catch (e) { - return defaultValue - } -} diff --git a/src/utils/get-from-local-storage.ts b/src/utils/get-from-local-storage.ts new file mode 100644 index 00000000..fe179c35 --- /dev/null +++ b/src/utils/get-from-local-storage.ts @@ -0,0 +1,7 @@ +export default (key: string, defaultValue: any) => { + try { + return JSON.parse(window.localStorage[`__REACT_IMAGE_ANNOTATE_${key}`]); + } catch (e) { + return defaultValue; + } +}; diff --git a/src/utils/get-hotkey-help-text.js b/src/utils/get-hotkey-help-text.js deleted file mode 100644 index c596bede..00000000 --- a/src/utils/get-hotkey-help-text.js +++ /dev/null @@ -1,11 +0,0 @@ -import { getApplicationKeyMap } from "react-hotkeys" - -export const getHotkeyHelpText = (commandName) => { - const firstSequence = - getApplicationKeyMap()[commandName]?.sequences?.[0]?.sequence - - if (!firstSequence) return "" - return ` (${firstSequence})` -} - -export default getHotkeyHelpText diff --git a/src/utils/get-hotkey-help-text.ts b/src/utils/get-hotkey-help-text.ts new file mode 100644 index 00000000..ba443627 --- /dev/null +++ b/src/utils/get-hotkey-help-text.ts @@ -0,0 +1,11 @@ +import { getApplicationKeyMap } from "react-hotkeys"; + +export const getHotkeyHelpText = (commandName: string) => { + const firstSequence = + getApplicationKeyMap()[commandName]?.sequences?.[0]?.sequence; + + if (!firstSequence) return ""; + return ` (${firstSequence})`; +}; + +export default getHotkeyHelpText; diff --git a/src/utils/get-landmarks-with-transform.js b/src/utils/get-landmarks-with-transform.js deleted file mode 100644 index 6cf95b1e..00000000 --- a/src/utils/get-landmarks-with-transform.js +++ /dev/null @@ -1,23 +0,0 @@ -// @flow -import type { KeypointDefinition } from "../ImageCanvas/region-tools" - -type Parameters = { - center: { x: number, y: number }, - scale: number, - landmarks: { - [string]: KeypointDefinition, - }, -} - -export default ({ center, scale, landmarks }: Parameters) => { - const points = {} - for (const [keypointId, { defaultPosition }] of (Object.entries( - landmarks - ): any)) { - points[keypointId] = { - x: defaultPosition[0] * scale + center.x, - y: defaultPosition[1] * scale + center.y, - } - } - return points -} diff --git a/src/utils/get-landmarks-with-transform.ts b/src/utils/get-landmarks-with-transform.ts new file mode 100644 index 00000000..fc29c740 --- /dev/null +++ b/src/utils/get-landmarks-with-transform.ts @@ -0,0 +1,21 @@ + +import type { KeypointDefinition } from "../types/region-tools.ts"; + +type Parameters = { + center: { x: number; y: number }; + scale: number; + landmarks: { + [key: string]: KeypointDefinition; + }; +}; + +export default ({ center, scale, landmarks }: Parameters) => { + const points: Record = {}; + for (const [keypointId, { defaultPosition }] of Object.entries(landmarks)) { + points[keypointId] = { + x: defaultPosition[0] * scale + center.x, + y: defaultPosition[1] * scale + center.y, + }; + } + return points; +}; diff --git a/src/utils/keys.ts b/src/utils/keys.ts new file mode 100644 index 00000000..645e23cf --- /dev/null +++ b/src/utils/keys.ts @@ -0,0 +1,54 @@ +import { EffectCallback } from "react"; + +const codeLowerCaseA = 65; +const codeUpperCaseZ = 122; +const isKeyFromGivenList = ( + keyCode: number, + allowedKeys: Array = [] +): boolean => { + if ( + allowedKeys === null || + allowedKeys.includes(keyCode) || + allowedKeys.length === 0 + ) { + return true; + } + return false; +}; +const onKeyPress = ( + currentKeyCode: number, + callback: (currentKeyCode: number, event: Event) => unknown, + allowedKeys: Array, + event: Event +): ReturnType => { + if (isKeyFromGivenList(currentKeyCode, allowedKeys)) { + callback(currentKeyCode, event); + } +}; + +function getAsciiCode(event: Event): number { + let keyCode = (event as KeyboardEvent).which; + if (keyCode >= codeLowerCaseA && keyCode <= codeUpperCaseZ) { + keyCode = (event as KeyboardEvent).key.charCodeAt(0); + } + return keyCode; +} + +function convertToAsciiEquivalent( + inputArray: Array +): Array { + return inputArray.map((item) => { + const finalVal = item; + if (typeof finalVal === "string") { + return finalVal.charCodeAt(0); + } + return finalVal; + }); +} + +export { + isKeyFromGivenList, + onKeyPress, + convertToAsciiEquivalent, + getAsciiCode, +}; diff --git a/src/utils/not-empty.ts b/src/utils/not-empty.ts new file mode 100644 index 00000000..e3113ee4 --- /dev/null +++ b/src/utils/not-empty.ts @@ -0,0 +1,3 @@ +export const notEmpty = (value: T | null | undefined): value is T => { + return value !== null && value !== undefined; +}; diff --git a/src/utils/set-in-local-storage.js b/src/utils/set-in-local-storage.ts similarity index 63% rename from src/utils/set-in-local-storage.js rename to src/utils/set-in-local-storage.ts index 330cdd51..0a12810e 100644 --- a/src/utils/set-in-local-storage.js +++ b/src/utils/set-in-local-storage.ts @@ -1,6 +1,6 @@ -export default (key, val) => { +export default (key: string, val: any) => { window.localStorage.setItem( `__REACT_IMAGE_ANNOTATE_${key}`, JSON.stringify(val) - ) -} + ); +}; diff --git a/src/utils/use-key-hook.ts b/src/utils/use-key-hook.ts new file mode 100644 index 00000000..d2017f29 --- /dev/null +++ b/src/utils/use-key-hook.ts @@ -0,0 +1,67 @@ +import { EffectCallback, useEffect } from "react"; + +import { convertToAsciiEquivalent, getAsciiCode, onKeyPress } from "./keys"; + +const VALID_KEY_EVENTS = ["keydown", "keyup", "keypress"]; + +interface IParamType { + detectKeys: Array; + keyevent?: "keydown" | "keyup" | "keypress"; +} + +const useKey = ( + callback: (currentKeyCode: number, event: Event) => unknown, + { detectKeys, keyevent }: IParamType, + { dependencies = [] } = {} +): any => { + const event = keyevent || "keydown"; + const isKeyeventValid = VALID_KEY_EVENTS.indexOf(event) > -1; + + if (!isKeyeventValid) { + // eslint-disable-next-line no-console + throw new Error(`Invalid keyevent ${keyevent}. Defaulting to keydown`); + } + + if (!callback) { + throw new Error("Callback is required"); + } + + if (!Array.isArray(dependencies)) { + throw new Error("Dependencies should be an array"); + } + + let allowedKeys = detectKeys; + + if (!Array.isArray(detectKeys)) { + allowedKeys = []; + // eslint-disable-next-line no-console + console.warn("Keys should be array!"); + } + + allowedKeys = convertToAsciiEquivalent(allowedKeys); + + const handleEvent = (event: Event) => { + const asciiCode = getAsciiCode(event); + return onKeyPress(asciiCode, callback, allowedKeys, event); + }; + + useEffect((): ReturnType => { + const canUseDOM = !!( + typeof window !== "undefined" && + window.document && + window.document.createElement + ); + if (!canUseDOM) { + console.error("Window is not defined"); + return (): void => { + // returning null + }; + } + window.document.addEventListener(event, handleEvent); + return () => { + window.document.removeEventListener(event, handleEvent); + }; + }, dependencies); +}; + +export { useKey }; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/workspace/Header/index.tsx b/src/workspace/Header/index.tsx new file mode 100644 index 00000000..5d8910fa --- /dev/null +++ b/src/workspace/Header/index.tsx @@ -0,0 +1,86 @@ +import HeaderButton from "../HeaderButton/index.js"; +import Box from "@mui/material/Box"; +import { createTheme, styled, ThemeProvider } from "@mui/material/styles"; +import { forwardRef, ReactNode, useImperativeHandle, useRef } from "react"; + +const theme = createTheme(); + +const Container = styled("div")(() => ({ + width: "100%", + display: "flex", + backgroundColor: "#fff", + borderBottom: "1px solid #ccc", + alignItems: "center", + flexShrink: 1, + boxSizing: "border-box", +})); + +interface HeaderProps { + leftSideContent?: ReactNode; + hideHeaderText?: boolean; + items: Array<{ name: string }>; + onClickItem: (item: { name: string }) => void; + customeHeaderItem?: { + icon: React.ReactNode, + name: string, + onClickAction: () => void + } +} + +export type HeaderRef = { + clickButtonByName: (name: string) => void; +}; + +export const Header = forwardRef(({ + leftSideContent = null, + hideHeaderText = false, + items, + onClickItem, + customeHeaderItem +}, ref) => { + const buttonRefs = useRef>({}); + + useImperativeHandle(ref, () => ({ + clickButtonByName(name: string) { + const button = buttonRefs.current[name]; + if (button) { + button.click(); + } else { + console.warn(`No button found with name: ${name}`); + } + }, + })); + + return ( + + + {leftSideContent} + {items.map((item, index) => ( + { + buttonRefs.current[item.name] = el; + }} + hideText={hideHeaderText} + onClick={() => onClickItem(item)} + {...item} + /> + ))} + {customeHeaderItem ? ( + { + buttonRefs.current[customeHeaderItem.name] = el; + }} + hideText={hideHeaderText} + onClick={() => customeHeaderItem.onClickAction()} + name={customeHeaderItem.name} + icon={customeHeaderItem.icon} + /> + ): <>} + + + ); +}); + +export default Header; diff --git a/src/workspace/HeaderButton/index.tsx b/src/workspace/HeaderButton/index.tsx new file mode 100644 index 00000000..417a08f8 --- /dev/null +++ b/src/workspace/HeaderButton/index.tsx @@ -0,0 +1,98 @@ + + +import Button from "@mui/material/Button"; +import { createTheme, styled, ThemeProvider } from "@mui/material/styles"; +import { useIconDictionary } from "../icon-dictionary.ts"; +import { iconMapping } from "../icon-mapping.ts"; +import { colors, SvgIconTypeMap } from "@mui/material"; +import { OverridableComponent } from "@mui/material/OverridableComponent"; +import { forwardRef, ReactNode } from "react"; + +const theme = createTheme(); +const defaultNameIconMapping = iconMapping; + +const getIcon = ( + name: string, + customIconMapping: Record> +) => { + const Icon = + customIconMapping[name.toLowerCase()] || + defaultNameIconMapping[name.toLowerCase()] || + defaultNameIconMapping.help; + return ; +}; + +const StyledButton = styled( + forwardRef>((props, ref) => ( +