diff --git a/.github/workflows/react.ci.yml b/.github/workflows/react.ci.yml
new file mode 100644
index 00000000..03b31ea6
--- /dev/null
+++ b/.github/workflows/react.ci.yml
@@ -0,0 +1,53 @@
+name: React - Publish Package
+on:
+ push:
+ branches:
+ - lab
+ - beta
+ - main
+ paths:
+ - 'packages/react/**'
+ - '.github/workflows/react.ci.yml'
+jobs:
+ package:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [20]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9.10.0
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ cache: 'pnpm'
+ - name: Install dependencies
+ run: pnpm install --no-frozen-lockfile
+ env:
+ NPM_CONFIG_USERCONFIG: .npmrc.ci
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ - run: git config --global user.name SuperViz
+ - run: git config --global user.email ci@superviz.com
+ - name: Publish npm package
+ run: npm whoami && pnpm run semantic-release --filter=@superviz/react-sdk
+ env:
+ NPM_CONFIG_USERCONFIG: .npmrc.ci
+ GITHUB_TOKEN: ${{ secrets.TOKEN_GITHUB }}
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ slack:
+ needs: package
+ name: Slack Notification
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Slack Notification
+ uses: rtCamp/action-slack-notify@v2
+ env:
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
+ SLACK_ICON: https://avatars.slack-edge.com/2020-11-18/1496892993975_af721d1c045bea2d5a46_48.png
+ MSG_MINIMAL: true
+ SLACK_USERNAME: Deploy react version ${{ github.ref_name }}
\ No newline at end of file
diff --git a/packages/react/.eslintrc.json b/packages/react/.eslintrc.json
new file mode 100644
index 00000000..fcd74b78
--- /dev/null
+++ b/packages/react/.eslintrc.json
@@ -0,0 +1,43 @@
+{
+ "env": {
+ "browser": true,
+ "es2021": true
+ },
+ "extends": [
+ "eslint:recommended",
+ "plugin:react/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "prettier"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaFeatures": {
+ "tsx": true
+ },
+ "ecmaVersion": "latest",
+ "sourceType": "module"
+ },
+ "plugins": ["react", "@typescript-eslint", "react-hooks", "prettier","simple-import-sort"],
+ "rules": {
+ "camelcase": "error",
+ "no-duplicate-imports": "error",
+ "@typescript-eslint/ban-ts-comment": "off",
+ "@typescript-eslint/no-explicit-any":"off",
+ "react/react-in-jsx-scope":"off",
+ "no-console": "off",
+ "no-alert": "error",
+ "react-hooks/exhaustive-deps": "off",
+ "react/prop-types": 0,
+ "react/display-name": 0,
+ "simple-import-sort/imports": "error",
+ "simple-import-sort/exports": "error",
+ "@typescript-eslint/no-empty-function":"off",
+ "react/no-unknown-property":"off",
+ "react/no-unescaped-entities ":"off"
+ },
+ "settings": {
+ "import/resolver": {
+ "typescript": {}
+ }
+ }
+ }
\ No newline at end of file
diff --git a/packages/react/.gitignore b/packages/react/.gitignore
new file mode 100644
index 00000000..1d229540
--- /dev/null
+++ b/packages/react/.gitignore
@@ -0,0 +1,26 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+public/vendor
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+.env
\ No newline at end of file
diff --git a/packages/react/.npmrc.ci b/packages/react/.npmrc.ci
new file mode 100644
index 00000000..ec2ee41e
--- /dev/null
+++ b/packages/react/.npmrc.ci
@@ -0,0 +1,2 @@
+@superviz:registry=https://registry.npmjs.org/
+//registry.npmjs.org/:_authToken=${NPM_TOKEN}
\ No newline at end of file
diff --git a/packages/react/.prettierrc b/packages/react/.prettierrc
new file mode 100644
index 00000000..d723adfb
--- /dev/null
+++ b/packages/react/.prettierrc
@@ -0,0 +1,8 @@
+{
+ "semi": true,
+ "trailingComma": "all",
+ "arrowParens": "always",
+ "printWidth": 100,
+ "singleQuote": true,
+ "tabWidth": 2
+}
diff --git a/packages/react/.releaserc b/packages/react/.releaserc
new file mode 100644
index 00000000..15a72fc6
--- /dev/null
+++ b/packages/react/.releaserc
@@ -0,0 +1,14 @@
+{
+ "branches": [
+ "main",
+ { "name": "beta", "channel": "beta", "prerelease": true },
+ { "name": "lab", "channel": "lab", "prerelease": true }
+ ],
+ "tagFormat": "@superviz/react/${version}",
+ "plugins": [
+ "@semantic-release/commit-analyzer",
+ "semantic-release-version-file",
+ "@semantic-release/github",
+ "@semantic-release/npm"
+ ]
+}
diff --git a/packages/react/README.md b/packages/react/README.md
new file mode 100644
index 00000000..4770d7f7
--- /dev/null
+++ b/packages/react/README.md
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+SuperViz provides a suite of programmable low-code Collaboration and Communication components, all synchronized with an advanced Real-time Data Engine, enabling real-time and asynchronous collaboration and communication within any JavaScript-based application.
+
+SuperViz offers a comprehensive suite of components, all synchronized with an advanced Real-time Data Engine, facilitating real-time collaboration in JavaScript-based applications. SuperViz SDK enables you to use one of our components:
+
+- Contextual Comments
+ - [Contextual Comments for HTML](https://docs.superviz.com/react-sdk/contextual-comments/HTML)
+ - [Contextual Comments for Canvas element](https://docs.superviz.com/react-sdk/contextual-comments/canvas)
+ - [Contextual Comments for Autodesk](https://docs.superviz.com/react-sdk/contextual-comments/autodesk)
+ - [Contextual Comments for Matterport](https://docs.superviz.com/react-sdk/contextual-comments/matterport)
+- Presence
+ - [Real-time Mouse Pointers](https://docs.superviz.com/react-sdk/presence/mouse-pointers)
+ - [Real-time Data Engine](https://docs.superviz.com/react-sdk/presence/real-time-data-engine)
+ - [Who-is-Online](https://docs.superviz.com/react-sdk/presence/who-is-online)
+ - [Presence in Autodesk](https://docs.superviz.com/react-sdk/presence/AutodeskPresence)
+ - [Presence in Matterport](https://docs.superviz.com/react-sdk/presence/MatterportPresence)
+ - [Presence in ThreeJS](https://docs.superviz.com/react-sdk/presence/ThreeJsPresence)
+- [Video Conference](https://docs.superviz.com/react-sdk/video/video-conference)
+
+You can also combine components to create a custom solution for your application.
+
+How to start coding with SuperViz? After installing this package, you’ll need to [create an account](https://dashboard.superviz.com/) to retrieve a SuperViz Token and start coding.
+
+## Quickstart
+
+### 1. Installation
+
+Install SuperViz SDK in your React app with the npm package:
+
+```bash
+npm install --save @superviz/react-sdk
+```
+
+Or, with yarn:
+
+```bash
+yarn add @superviz/react-sdk
+```
+
+### 2. Import the SDK
+
+Once installed, import the SDK to your code:
+
+```jsx
+import { SuperVizRoomProvider } from "@superviz/react-sdk";
+```
+
+### 3. Initialize the SDK
+
+After importing the SDK, you can initialize our provider by passing your `DEVELOPER_KEY` and important information about the participant. You can see details for the options object on the [React Initialization page](https://docs.superviz.com/react-sdk/initialization).
+
+The SuperVizRoomProvider is your primary gateway to access all SDK features, offering the essential methods to add its components.
+
+```jsx
+",
+ name: "",
+ }}
+ participant={{
+ id: "",
+ name: "",
+ }}
+ roomId="">
+ This is a room
+
+```
+
+## Documentation
+
+You can find the complete documentation for every component and how to initialize them on the [SuperViz SDK Documentation page](https://docs.superviz.com/react-sdk/initialization).
+
+You can also find the complete changelog on the [Release Notes page](https://docs.superviz.com/releases).
+
+## Contributing
+
+If you are interested in contributing to SuperViz SDK, the best place to get involved with the community is through the [Discord server](https://discord.gg/weZ3Bfv6WZ), there you can find the latest news, ask questions, and share your experiences with SuperViz SDK.
+
+## License
+
+SuperViz SDK is licensed under the [BSD 2-Clause License](LICENSE).
\ No newline at end of file
diff --git a/packages/react/eslint.config.mjs b/packages/react/eslint.config.mjs
new file mode 100644
index 00000000..ba968e3c
--- /dev/null
+++ b/packages/react/eslint.config.mjs
@@ -0,0 +1,75 @@
+import react from "eslint-plugin-react";
+import typescriptEslint from "@typescript-eslint/eslint-plugin";
+import reactHooks from "eslint-plugin-react-hooks";
+import prettier from "eslint-plugin-prettier";
+import simpleImportSort from "eslint-plugin-simple-import-sort";
+import { fixupPluginRules } from "@eslint/compat";
+import globals from "globals";
+import tsParser from "@typescript-eslint/parser";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+import js from "@eslint/js";
+import { FlatCompat } from "@eslint/eslintrc";
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+const compat = new FlatCompat({
+ baseDirectory: __dirname,
+ recommendedConfig: js.configs.recommended,
+ allConfig: js.configs.all
+});
+
+export default [...compat.extends(
+ "eslint:recommended",
+ "plugin:react/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+), {
+ plugins: {
+ react,
+ "@typescript-eslint": typescriptEslint,
+ "react-hooks": fixupPluginRules(reactHooks),
+ prettier,
+ "simple-import-sort": simpleImportSort,
+ },
+
+ languageOptions: {
+ globals: {
+ ...globals.browser,
+ },
+
+ parser: tsParser,
+ ecmaVersion: "latest",
+ sourceType: "module",
+
+ parserOptions: {
+ ecmaFeatures: {
+ tsx: true,
+ },
+ },
+ },
+
+ settings: {
+ "import/resolver": {
+ typescript: {},
+ },
+ },
+
+ rules: {
+ camelcase: "error",
+ "no-duplicate-imports": "error",
+ "@typescript-eslint/ban-ts-comment": "off",
+ "@typescript-eslint/no-explicit-any": "off",
+ "react/react-in-jsx-scope": "off",
+ "no-console": "off",
+ "no-alert": "error",
+ "react-hooks/exhaustive-deps": "off",
+ "react/prop-types": 0,
+ "react/display-name": 0,
+ "simple-import-sort/imports": "error",
+ "simple-import-sort/exports": "error",
+ "@typescript-eslint/no-empty-function": "off",
+ "react/no-unknown-property": "off",
+ "react/no-unescaped-entities ": "off",
+ },
+}];
\ No newline at end of file
diff --git a/packages/react/package.json b/packages/react/package.json
new file mode 100644
index 00000000..da25acb4
--- /dev/null
+++ b/packages/react/package.json
@@ -0,0 +1,80 @@
+{
+ "name": "@superviz/react-sdk",
+ "private": false,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "watch": "tsc && vite build --watch",
+ "build": "tsc && vite build && cp package.json dist/package.json && cp README.md dist/README.md",
+ "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
+ "lint:fix": "eslint --fix 'src/**/*.{jsx,ts,tsx}'",
+ "format": "prettier --write src//**/*.{ts,tsx,css} --config ./.prettierrc",
+ "semantic-release": "semantic-release",
+ "commit": "git-cz"
+ },
+ "files": [
+ "dist"
+ ],
+ "exports": {
+ ".": {
+ "import": "./dist/superviz-sdk-react.es.js",
+ "require": "./dist/superviz-sdk-react.cjs.js",
+ "types": "./dist/index.d.ts"
+ },
+ "./dist/style.css": "./dist/style.css"
+ },
+ "main": "./dist/superviz-sdk-react.cjs.js",
+ "module": "./dist/superviz-sdk-react.es.js",
+ "types": "./dist/index.d.ts",
+ "publishConfig": {
+ "access": "public",
+ "scope": "@superviz"
+ },
+ "dependencies": {
+ "@superviz/autodesk-viewer-plugin": "workspace:*",
+ "@superviz/matterport-plugin": "workspace:*",
+ "@superviz/sdk": "workspace:*",
+ "@superviz/socket-client": "workspace:*",
+ "@superviz/threejs-plugin": "workspace:*",
+ "lodash": "^4.17.21",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@rollup/plugin-replace": "^5.0.7",
+ "@eslint/compat": "^1.1.1",
+ "@types/forge-viewer": "^7.89.1",
+ "@types/lodash": "^4.17.6",
+ "@types/node": "^20.14.9",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
+ "@types/three": "^0.166.0",
+ "@typescript-eslint/eslint-plugin": "^7.14.1",
+ "@typescript-eslint/parser": "^7.14.1",
+ "@vitejs/plugin-react": "^4.3.1",
+ "@vitejs/plugin-react-swc": "^3.7.0",
+ "eslint": "^9.6.0",
+ "eslint-config-prettier": "^9.1.0",
+ "eslint-plugin-prettier": "^5.1.3",
+ "eslint-plugin-react": "^7.34.3",
+ "eslint-plugin-react-hooks": "^4.6.2",
+ "eslint-plugin-react-refresh": "^0.4.7",
+ "eslint-plugin-simple-import-sort": "^12.1.0",
+ "glob": "^10.4.2",
+ "husky": "^9.0.11",
+ "lint-staged": "^15.2.7",
+ "prettier": "^3.3.2",
+ "react-hooks": "^1.0.1",
+ "semantic-release": "^24.0.0",
+ "semantic-release-version-file": "^1.0.2",
+ "typescript": "^5.5.2",
+ "vite": "^5.3.2",
+ "vite-plugin-dts": "^3.9.1",
+ "vite-plugin-linter": "^2.1.1",
+ "vite-tsconfig-paths": "^4.3.2"
+ }
+}
diff --git a/packages/react/src/common/types/global.types.ts b/packages/react/src/common/types/global.types.ts
new file mode 100644
index 00000000..637dbb02
--- /dev/null
+++ b/packages/react/src/common/types/global.types.ts
@@ -0,0 +1,4 @@
+export type DefaultComponentProps = {
+ onMount?: () => void;
+ onUnmount?: () => void;
+} & T;
diff --git a/packages/react/src/components/autodesk/autodesk.tsx b/packages/react/src/components/autodesk/autodesk.tsx
new file mode 100644
index 00000000..a4fc76b8
--- /dev/null
+++ b/packages/react/src/components/autodesk/autodesk.tsx
@@ -0,0 +1,164 @@
+import { Presence3D } from '@superviz/autodesk-viewer-plugin';
+import { useEffect, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+import type { AutoDeskComponent } from 'src/contexts/room.types';
+
+import { AutodeskComponentProps, AutodeskViewerComponentProps } from './autodesk.types';
+
+export function AutodeskPresence({ viewer, children, ...params }: AutodeskComponentProps) {
+ const { room, component, addComponent } =
+ useInternalFeatures('presence3dAutodesk');
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+
+ useEffect(() => {
+ if (!room || initializedTimestamp || !viewer) return;
+
+ const autodesk = new Presence3D(viewer, params) as AutoDeskComponent;
+
+ addComponent(autodesk);
+ setInitializedTimestamp(Date.now());
+ }, [room, viewer]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ }
+ }, [component]);
+
+ return children ?? <>>;
+}
+
+export function AutodeskViewer({
+ modelUrn,
+ clientId,
+ clientSecret,
+ authUrl: url,
+ initializeOptions,
+ data,
+ onDocumentLoadError,
+ onDocumentLoadSuccess,
+ onViewerInitialized,
+ isAvatarsEnabled,
+ isLaserEnabled,
+ isNameEnabled,
+ isMouseEnabled,
+ avatarConfig,
+ ...divParams
+}: AutodeskViewerComponentProps) {
+ const [instance, setInstance] = useState(null);
+ const { hasJoinedRoom } = useInternalFeatures('presence3dAutodesk');
+ const authUrl = url || 'https://developer.api.autodesk.com/authentication/v2/token';
+ const token = btoa(`${clientId}:${clientSecret}`);
+ const body = {
+ // eslint-disable-next-line camelcase
+ grant_type: 'client_credentials',
+ scope: 'data:read bucket:read',
+ ...data,
+ };
+
+ useEffect(() => {
+ if (hasJoinedRoom) {
+ loadDocument();
+ return;
+ }
+
+ if (instance) {
+ instance.finish();
+ setInstance(null);
+ }
+ }, [hasJoinedRoom]);
+
+ async function loadDocument() {
+ let viewer: Autodesk.Viewing.GuiViewer3D | null = null;
+
+ if (!window.Autodesk) {
+ console.error('[Superviz] Autodesk not found');
+ return;
+ }
+
+ await fetch(authUrl, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ Authorization: `Basic ${token}`,
+ },
+ body: new URLSearchParams(body).toString(),
+ })
+ .then((response) => response.json())
+ .then((dataToken) => {
+ const modelId = btoa(modelUrn);
+ const documentId = `urn:${modelId}`;
+
+ const options = {
+ env: 'AutodeskProduction2',
+ api: 'streamingV2',
+ accessToken: dataToken.access_token,
+ ...initializeOptions,
+ };
+
+ window.Autodesk.Viewing.Initializer(options, async () => {
+ const container = document.getElementById('autodesk-content');
+
+ if (!container) {
+ console.error('[Superviz] Autodesk container not found');
+ return;
+ }
+
+ viewer = new window.Autodesk.Viewing.GuiViewer3D(container);
+ await viewer.start();
+
+ onViewerInitialized &&
+ onViewerInitialized({
+ viewer,
+ container,
+ });
+
+ window.Autodesk.Viewing.Document.load(documentId, onLoadSuccess, onLoadFailure);
+ });
+ });
+
+ function onLoadSuccess(doc: any) {
+ if (onDocumentLoadSuccess) onDocumentLoadSuccess(doc);
+
+ const viewable = doc.getRoot().getDefaultGeometry();
+ if (!viewable || !viewer) return;
+
+ const options = {
+ applyScaling: 'meters',
+ };
+
+ viewer
+ .loadDocumentNode(doc, viewable, options)
+ .then(() => {
+ if (!viewer) return;
+ setInstance(viewer);
+ })
+ .catch((error) => {
+ console.error('[SuperViz] Failed to load document node', error);
+ });
+ }
+
+ function onLoadFailure(
+ errorCode: Autodesk.Viewing.ErrorCodes,
+ errorMsg: string,
+ messages: any[],
+ ) {
+ if (onDocumentLoadError) onDocumentLoadError(errorCode, errorMsg, messages);
+
+ console.error('[SuperViz] Failed to load document', errorCode, errorMsg, messages);
+ }
+ }
+
+ return (
+
+
+
+ );
+}
diff --git a/packages/react/src/components/autodesk/autodesk.types.ts b/packages/react/src/components/autodesk/autodesk.types.ts
new file mode 100644
index 00000000..9ad7868f
--- /dev/null
+++ b/packages/react/src/components/autodesk/autodesk.types.ts
@@ -0,0 +1,41 @@
+import { AvatarConfig } from '@superviz/autodesk-viewer-plugin/dist/types';
+import type { ReactElement } from 'react';
+
+export type AutodeskComponentProps = {
+ viewer: Autodesk.Viewing.GuiViewer3D;
+ children?: ReactElement | string | ReactElement[] | null;
+ isAvatarsEnabled?: boolean;
+ isLaserEnabled?: boolean;
+ isNameEnabled?: boolean;
+ isMouseEnabled?: boolean;
+ avatarConfig?: AvatarConfig;
+};
+
+type ViewerInitializedParams = {
+ viewer: Autodesk.Viewing.GuiViewer3D;
+ container: HTMLElement;
+};
+
+export type AutodeskViewerComponentProps = {
+ modelUrn: string;
+ clientId: string;
+ clientSecret: string;
+
+ onViewerInitialized?: (params: ViewerInitializedParams) => void;
+ onDocumentLoadSuccess?: (doc: Document) => void;
+ onDocumentLoadError?: (
+ errorCode: Autodesk.Viewing.ErrorCodes,
+ errorMsg: string,
+ messages: any[],
+ ) => void;
+
+ authUrl?: string;
+ initializeOptions?: Omit;
+ data?: {
+ client_id?: string;
+ client_secret?: string;
+ grant_type: string;
+ scope: string;
+ };
+} & Omit &
+ Omit, 'id'>;
diff --git a/packages/react/src/components/autodesk/index.ts b/packages/react/src/components/autodesk/index.ts
new file mode 100644
index 00000000..9e2a8dbf
--- /dev/null
+++ b/packages/react/src/components/autodesk/index.ts
@@ -0,0 +1,2 @@
+export * from './autodesk';
+export * from './autodesk.types';
diff --git a/packages/react/src/components/comments/comments.tsx b/packages/react/src/components/comments/comments.tsx
new file mode 100644
index 00000000..a29d5e1a
--- /dev/null
+++ b/packages/react/src/components/comments/comments.tsx
@@ -0,0 +1,54 @@
+import { useEffect, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { CommentsComponent } from '../../lib/sdk';
+import { CommentsProps } from './comments.types';
+
+export function Comments({
+ pin,
+ children,
+ onPinActive,
+ onPinInactive,
+ onMount,
+ onUnmount,
+ ...params
+}: CommentsProps) {
+ const { room, component, addComponent } = useInternalFeatures('comments');
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+
+ const callbacks = {
+ 'pin-mode.active': onPinActive,
+ 'pin-mode.inactive': onPinInactive,
+ mount: onMount,
+ unmount: onUnmount,
+ };
+
+ useEffect(() => {
+ if (!component) return;
+
+ Object.entries(callbacks).forEach(([event, callback]) => {
+ component.unsubscribe(event, callback);
+
+ if (callback) {
+ component.subscribe(event, callback);
+ }
+ });
+ }, [component, room, onPinActive, onPinInactive, onMount, onUnmount]);
+
+ useEffect(() => {
+ if (!room || initializedTimestamp || !pin) return;
+
+ const commentsInstance = new CommentsComponent(pin, { ...params });
+
+ addComponent(commentsInstance);
+ setInitializedTimestamp(Date.now());
+ }, [room, pin]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ }
+ }, [component]);
+
+ return children ?? <>>;
+}
diff --git a/packages/react/src/components/comments/comments.types.ts b/packages/react/src/components/comments/comments.types.ts
new file mode 100644
index 00000000..e06d3f13
--- /dev/null
+++ b/packages/react/src/components/comments/comments.types.ts
@@ -0,0 +1,26 @@
+import type { AutodeskPin } from '@superviz/autodesk-viewer-plugin';
+import type { MatterportPin } from '@superviz/matterport-plugin';
+import type { ThreeJsPin } from '@superviz/threejs-plugin';
+import { ReactElement } from 'react';
+import { DefaultComponentProps } from 'src/common/types/global.types';
+
+import type { ButtonLocation, CanvasPin, CommentsSide, HTMLPin } from '../../lib/sdk';
+
+export type CommentsProps = DefaultComponentProps<{
+ pin: CanvasPin | HTMLPin | MatterportPin | ThreeJsPin | AutodeskPin | null;
+ children?: ReactElement | string | ReactElement[] | null;
+
+ onPinActive?: () => void;
+ onPinInactive?: () => void;
+
+ position?: `${CommentsSide}`;
+ buttonLocation?: `${ButtonLocation}` | string;
+ hideDefaultButton?: boolean;
+ styles?: string;
+ offset?: {
+ left?: number;
+ top?: number;
+ right?: number;
+ bottom?: number;
+ };
+}>;
diff --git a/packages/react/src/components/comments/index.ts b/packages/react/src/components/comments/index.ts
new file mode 100644
index 00000000..e5479a30
--- /dev/null
+++ b/packages/react/src/components/comments/index.ts
@@ -0,0 +1,2 @@
+export * from './comments';
+export * from './comments.types';
diff --git a/packages/react/src/components/form-elements/form-elements.tsx b/packages/react/src/components/form-elements/form-elements.tsx
new file mode 100644
index 00000000..7954a8bf
--- /dev/null
+++ b/packages/react/src/components/form-elements/form-elements.tsx
@@ -0,0 +1,77 @@
+import { useEffect, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { ComponentLifeCycleEvent, FormElementsComponent } from '../../lib/sdk';
+import { FieldEvents, FormElementsProps } from './form-elements.types';
+
+export function FormElements({
+ onMount,
+ onUnmount,
+ disableOutline,
+ disableRealtimeSync,
+ fields,
+ children,
+ onInteraction,
+ onContentChange,
+}: FormElementsProps) {
+ const { room, component, addComponent } =
+ useInternalFeatures('formElements');
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+
+ useEffect(() => {
+ if (!component) return;
+ component.unsubscribe(ComponentLifeCycleEvent.MOUNT);
+
+ if (onMount) {
+ component.subscribe(ComponentLifeCycleEvent.MOUNT, onMount);
+ }
+ }, [component, onMount]);
+
+ useEffect(() => {
+ if (!component) return;
+ component.unsubscribe(ComponentLifeCycleEvent.UNMOUNT);
+
+ if (onUnmount) {
+ component.subscribe(ComponentLifeCycleEvent.UNMOUNT, onUnmount);
+ }
+ }, [component, onUnmount]);
+
+ useEffect(() => {
+ if (!component) return;
+ component.unsubscribe(FieldEvents.CONTENT_CHANGE);
+
+ if (onContentChange) {
+ component.subscribe(FieldEvents.CONTENT_CHANGE, onContentChange);
+ }
+ }, [component, onContentChange]);
+
+ useEffect(() => {
+ if (!component) return;
+ component.unsubscribe(FieldEvents.INTERACTION);
+
+ if (onInteraction) {
+ component.subscribe(FieldEvents.INTERACTION, onInteraction);
+ }
+ }, [component, onInteraction]);
+
+ useEffect(() => {
+ if (!room || initializedTimestamp) return;
+
+ const formElementsInstance = new FormElementsComponent({
+ fields,
+ disableOutline,
+ disableRealtimeSync,
+ });
+
+ addComponent(formElementsInstance);
+ setInitializedTimestamp(Date.now());
+ }, [room]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ }
+ }, [component]);
+
+ return children ?? <>>;
+}
diff --git a/packages/react/src/components/form-elements/form-elements.types.ts b/packages/react/src/components/form-elements/form-elements.types.ts
new file mode 100644
index 00000000..d7acc090
--- /dev/null
+++ b/packages/react/src/components/form-elements/form-elements.types.ts
@@ -0,0 +1,32 @@
+import { ReactElement } from 'react';
+import { DefaultComponentProps } from 'src/common/types/global.types';
+
+export type FormElementsProps = DefaultComponentProps<{
+ children?: ReactElement | string | ReactElement[] | null;
+ fields?: string[] | string;
+ disableOutline?: boolean;
+ disableRealtimeSync?: boolean;
+ onContentChange?: (data: {
+ value: string;
+ fieldId: string;
+ attribute: string;
+ userId: string;
+ userName: string;
+ timestamp: number;
+ }) => void;
+ onInteraction?: (data: {
+ fieldId: string;
+ userId: string;
+ userName: string;
+ color: string;
+ }) => void;
+}>;
+
+export enum FieldEvents {
+ BLUR = 'field.blur',
+ FOCUS = 'field.focus',
+ CONTENT_CHANGE = 'field.content-change',
+ INTERACTION = 'field.interaction',
+}
+
+export type Field = HTMLInputElement | HTMLTextAreaElement;
diff --git a/packages/react/src/components/form-elements/index.ts b/packages/react/src/components/form-elements/index.ts
new file mode 100644
index 00000000..d9369cca
--- /dev/null
+++ b/packages/react/src/components/form-elements/index.ts
@@ -0,0 +1,2 @@
+export * from './form-elements';
+export * from './form-elements.types';
diff --git a/packages/react/src/components/matterport/index.ts b/packages/react/src/components/matterport/index.ts
new file mode 100644
index 00000000..ce86529b
--- /dev/null
+++ b/packages/react/src/components/matterport/index.ts
@@ -0,0 +1,2 @@
+export * from './matterport';
+export * from './matterport.types';
diff --git a/packages/react/src/components/matterport/matterport.tsx b/packages/react/src/components/matterport/matterport.tsx
new file mode 100644
index 00000000..8631efb9
--- /dev/null
+++ b/packages/react/src/components/matterport/matterport.tsx
@@ -0,0 +1,132 @@
+import { Presence3D } from '@superviz/matterport-plugin';
+import type { MpSdk } from '@superviz/matterport-plugin/dist/common/types/matterport.types';
+import type { MatterportComponentOptions } from '@superviz/matterport-plugin/dist/types';
+import { useCallback, useEffect, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+import { MatterportComponent } from 'src/contexts/room.types';
+
+import { MatterportComponentProps, MatterportIframeProps } from './matterport.types';
+
+export function MatterportPresence({
+ matterportSdkInstance,
+ children,
+ ...params
+}: MatterportComponentProps) {
+ const { room, component, addComponent, removeComponent } =
+ useInternalFeatures('presence3dMatterport');
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+
+ useEffect(() => {
+ if (!room || !matterportSdkInstance) {
+ return;
+ }
+
+ const matterportInstance = new Presence3D(
+ matterportSdkInstance,
+ params as MatterportComponentOptions,
+ ) as MatterportComponent;
+
+ addComponent(matterportInstance);
+ setInitializedTimestamp(Date.now());
+ }, [room, matterportSdkInstance]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ }
+ }, [component]);
+
+ useEffect(() => {
+ if ((!matterportSdkInstance || !room) && component) {
+ removeComponent(component);
+ }
+ }, [matterportSdkInstance, room]);
+
+ return children ?? <>>;
+}
+
+export function MatterportIframe({
+ isAvatarsEnabled,
+ isLaserEnabled,
+ isNameEnabled,
+ avatarConfig,
+ bundleUrl,
+ matterportKey,
+ onMpSdkLoaded,
+ ...iframeProps
+}: MatterportIframeProps) {
+ const { room, removeComponent, component } =
+ useInternalFeatures('presence3dMatterport');
+ const iframe = useRef(null);
+ const [matterportInstance, setMatterportInstance] = useState(null);
+ const url = useRef('');
+
+ useEffect(() => {
+ if (!iframe.current) return;
+
+ initializeMatterportSdk();
+ }, [bundleUrl, iframe.current]);
+
+ useEffect(() => {
+ if (!room && matterportInstance) {
+ setMatterportInstance(null);
+ iframe.current?.remove();
+ }
+ }, [room]);
+
+ const initializeMatterportSdk = useCallback(async () => {
+ if (url.current === bundleUrl) {
+ return;
+ }
+ url.current = bundleUrl;
+
+ if (matterportInstance) {
+ setMatterportInstance(null);
+ removeComponent(component);
+ }
+
+ const showcase = document.getElementById('showcase') as HTMLIFrameElement;
+
+ const showcaseWindow = showcase.contentWindow;
+ showcase.setAttribute('src', bundleUrl);
+
+ if (!showcaseWindow) {
+ console.error('[SuperViz] Matterport Showcase iframe not found');
+ return;
+ }
+
+ const mpsdk = await new Promise((resolve) => {
+ const callback = async () => {
+ // @ts-ignore
+ const mpSdk = (await showcaseWindow.MP_SDK.connect(showcaseWindow, matterportKey)) as MpSdk;
+
+ if (onMpSdkLoaded) {
+ onMpSdkLoaded({
+ matterportSdkInstance: mpSdk,
+ showcaseWindow: iframe.current as HTMLIFrameElement,
+ });
+ }
+
+ resolve(mpSdk);
+ showcase.removeEventListener('load', callback);
+ };
+
+ showcase.addEventListener('load', callback);
+ });
+
+ setMatterportInstance(mpsdk);
+ }, [bundleUrl]);
+
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/packages/react/src/components/matterport/matterport.types.ts b/packages/react/src/components/matterport/matterport.types.ts
new file mode 100644
index 00000000..6dd4b9ce
--- /dev/null
+++ b/packages/react/src/components/matterport/matterport.types.ts
@@ -0,0 +1,27 @@
+import type { MpSdk } from '@superviz/matterport-plugin/dist/common/types/matterport.types';
+import type { AvatarConfig } from '@superviz/matterport-plugin/dist/types';
+import type { ReactElement } from 'react';
+
+export type MatterportComponentProps = {
+ children?: ReactElement | string | ReactElement[] | null;
+ matterportSdkInstance: MpSdk;
+ isAvatarsEnabled?: boolean;
+ isLaserEnabled?: boolean;
+ isNameEnabled?: boolean;
+ avatarConfig?: AvatarConfig;
+};
+
+type MatterportLoadedCallback = {
+ matterportSdkInstance: MpSdk;
+ showcaseWindow: HTMLIFrameElement;
+};
+
+export type MatterportIframeProps = {
+ bundleUrl: string;
+ matterportKey: string;
+ onMpSdkLoaded?: (params: MatterportLoadedCallback) => void;
+} & Omit &
+ Omit<
+ React.DetailedHTMLProps, HTMLIFrameElement>,
+ 'src'
+ >;
diff --git a/packages/react/src/components/mouse-pointers/index.ts b/packages/react/src/components/mouse-pointers/index.ts
new file mode 100644
index 00000000..0568e23b
--- /dev/null
+++ b/packages/react/src/components/mouse-pointers/index.ts
@@ -0,0 +1,2 @@
+export * from './mouse-pointers';
+export * from './mouse-pointers.types';
diff --git a/packages/react/src/components/mouse-pointers/mouse-pointers.tsx b/packages/react/src/components/mouse-pointers/mouse-pointers.tsx
new file mode 100644
index 00000000..a18a3105
--- /dev/null
+++ b/packages/react/src/components/mouse-pointers/mouse-pointers.tsx
@@ -0,0 +1,63 @@
+import { useCallback, useEffect, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { MousePointersComponent, PointersCanvas, PointersHTML } from '../../lib/sdk';
+import { MousePointersProps } from './mouse-pointers.types';
+
+export function MousePointers({
+ children,
+ elementId,
+ onMount,
+ onUnmount,
+ ...params
+}: MousePointersProps) {
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+ const { room, component, addComponent } = useInternalFeatures(
+ 'presence',
+ );
+
+ const callbacks = {
+ mount: onMount,
+ unmount: onUnmount,
+ };
+
+ const goTo = useCallback(
+ (data: { x: number; y: number; scaleX: number; scaleY: number }) => {
+ if (!params.callbacks?.onGoToPresence) return;
+
+ params.callbacks?.onGoToPresence(data);
+ },
+ [params.callbacks?.onGoToPresence],
+ );
+
+ useEffect(() => {
+ if (!component) return;
+
+ Object.entries(callbacks).forEach(([event, callback]) => {
+ component.unsubscribe(event, callback);
+
+ if (callback) {
+ component.subscribe(event, callback);
+ }
+ });
+ }, [component, room, onMount, onUnmount]);
+
+ useEffect(() => {
+ if (!room || initializedTimestamp || !document.getElementById(elementId)) return;
+
+ const mouse = new MousePointersComponent(elementId, {
+ callbacks: { onGoToPresence: goTo },
+ }) as PointersCanvas | PointersHTML;
+
+ addComponent(mouse);
+ setInitializedTimestamp(Date.now());
+ }, [room, elementId]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ }
+ }, [component]);
+
+ return children ?? <>>;
+}
diff --git a/packages/react/src/components/mouse-pointers/mouse-pointers.types.ts b/packages/react/src/components/mouse-pointers/mouse-pointers.types.ts
new file mode 100644
index 00000000..c3f75080
--- /dev/null
+++ b/packages/react/src/components/mouse-pointers/mouse-pointers.types.ts
@@ -0,0 +1,10 @@
+import type { ReactElement } from 'react';
+import { DefaultComponentProps } from 'src/common/types/global.types';
+
+export type MousePointersProps = DefaultComponentProps<{
+ children?: ReactElement | string | ReactElement[] | null;
+ elementId: string;
+ callbacks?: {
+ onGoToPresence?: (position: { x: number; y: number; scaleX: number; scaleY: number }) => void;
+ };
+}>;
diff --git a/packages/react/src/components/realtime/index.ts b/packages/react/src/components/realtime/index.ts
new file mode 100644
index 00000000..f4603a24
--- /dev/null
+++ b/packages/react/src/components/realtime/index.ts
@@ -0,0 +1 @@
+export * from './realtime';
diff --git a/packages/react/src/components/realtime/realtime.tsx b/packages/react/src/components/realtime/realtime.tsx
new file mode 100644
index 00000000..cbdcfb8e
--- /dev/null
+++ b/packages/react/src/components/realtime/realtime.tsx
@@ -0,0 +1,35 @@
+import { useEffect, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { RealtimeComponent, RealtimeComponentEvent } from '../../lib/sdk';
+import { RealtimeProps } from './realtime.types';
+
+export function Realtime({ onStateChange, onMount, onUnmount }: RealtimeProps) {
+ const { room, component, addComponent } = useInternalFeatures('realtime');
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+
+ useEffect(() => {
+ if (!room || initializedTimestamp) return;
+
+ const realtimeInstance = new RealtimeComponent();
+ addComponent(realtimeInstance);
+ setInitializedTimestamp(Date.now());
+
+ if (onStateChange)
+ realtimeInstance.subscribe(
+ RealtimeComponentEvent.REALTIME_STATE_CHANGED,
+ onStateChange as (data: unknown) => void,
+ );
+
+ if (onMount) onMount();
+ }, [room]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ if (onUnmount) onUnmount();
+ }
+ }, [component]);
+
+ return <>>;
+}
diff --git a/packages/react/src/components/realtime/realtime.types.ts b/packages/react/src/components/realtime/realtime.types.ts
new file mode 100644
index 00000000..d4a911c5
--- /dev/null
+++ b/packages/react/src/components/realtime/realtime.types.ts
@@ -0,0 +1,7 @@
+import { DefaultComponentProps } from 'src/common/types/global.types';
+
+import type { RealtimeComponentState } from '../../lib/sdk';
+
+export type RealtimeProps = DefaultComponentProps<{
+ onStateChange?: (state: RealtimeComponentState) => void;
+}>;
diff --git a/packages/react/src/components/three/index.ts b/packages/react/src/components/three/index.ts
new file mode 100644
index 00000000..2db15afc
--- /dev/null
+++ b/packages/react/src/components/three/index.ts
@@ -0,0 +1,2 @@
+export * from './three';
+export * from './three.types';
diff --git a/packages/react/src/components/three/three.tsx b/packages/react/src/components/three/three.tsx
new file mode 100644
index 00000000..3dcd71f6
--- /dev/null
+++ b/packages/react/src/components/three/three.tsx
@@ -0,0 +1,43 @@
+import { Presence3D } from '@superviz/threejs-plugin';
+import { useEffect, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+import { ThreeJsComponent } from 'src/contexts/room.types';
+
+import { ThreeJsComponentProps } from './three.types';
+
+export function ThreeJsPresence({
+ scene,
+ camera,
+ player,
+ children,
+ ...params
+}: ThreeJsComponentProps) {
+ const { room, component, addComponent } =
+ useInternalFeatures('presence3dThreejs');
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+
+ useEffect(() => {
+ if (!room && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ return;
+ }
+
+ if (!room || initializedTimestamp || !scene || !camera || !player) {
+ return;
+ }
+
+ // @ts-ignore
+ const threeInstance = new Presence3D(scene, camera, player, { ...params }) as ThreeJsComponent;
+
+ addComponent(threeInstance);
+ setInitializedTimestamp(Date.now());
+ }, [room, scene, initializedTimestamp]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ }
+ }, [component]);
+
+ return children ?? <>>;
+}
diff --git a/packages/react/src/components/three/three.types.ts b/packages/react/src/components/three/three.types.ts
new file mode 100644
index 00000000..81e8da70
--- /dev/null
+++ b/packages/react/src/components/three/three.types.ts
@@ -0,0 +1,16 @@
+import type { AvatarConfig } from '@superviz/threejs-plugin/dist/types';
+import type { ReactElement } from 'react';
+import type { Camera, Object3D, Scene } from 'three';
+
+export type ThreeJsComponentProps = {
+ children?: ReactElement | ReactElement[] | string | null;
+ scene: Scene;
+ camera: Camera;
+ player: Object3D;
+ isAvatarsEnabled?: boolean;
+ isLaserEnabled?: boolean;
+ isNameEnabled?: boolean;
+ isMouseEnabled?: boolean;
+ renderLocalAvatar?: boolean;
+ avatarConfig?: AvatarConfig;
+};
diff --git a/packages/react/src/components/video/index.ts b/packages/react/src/components/video/index.ts
new file mode 100644
index 00000000..4d19ebb2
--- /dev/null
+++ b/packages/react/src/components/video/index.ts
@@ -0,0 +1,2 @@
+export * from './video';
+export * from './video.types';
diff --git a/packages/react/src/components/video/video.tsx b/packages/react/src/components/video/video.tsx
new file mode 100644
index 00000000..c3d9052d
--- /dev/null
+++ b/packages/react/src/components/video/video.tsx
@@ -0,0 +1,140 @@
+import { useCallback, useEffect, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { FrameEvent, MeetingEvent, VideoConferenceComponent } from '../../lib/sdk';
+import { VideoCallbacks, VideoComponentProps } from './video.types';
+
+const generateCallbackList = (callbacks: VideoCallbacks) => {
+ return {
+ [MeetingEvent.DESTROY]: callbacks.onDestroy,
+ [FrameEvent.FRAME_DIMENSIONS_UPDATE]: callbacks.onFrameDimensionsChange,
+ [MeetingEvent.MEETING_WAITING_FOR_HOST]: callbacks.onWaitingForHostChange,
+ [MeetingEvent.MEETING_CONNECTION_STATUS_CHANGE]: callbacks.onConnectionStatusChange,
+ [MeetingEvent.MEETING_STATE_UPDATE]: callbacks.onMeetingStateChange,
+ [MeetingEvent.MEETING_SAME_PARTICIPANT_ERROR]: callbacks.onSameAccountError,
+ [MeetingEvent.MEETING_DEVICES_CHANGE]: callbacks.onDevicesStateChange,
+ [MeetingEvent.MEETING_HOST_CHANGE]: callbacks.onHostChange,
+ [MeetingEvent.MEETING_HOST_AVAILABLE]: callbacks.onHostAvailable,
+ [MeetingEvent.MEETING_NO_HOST_AVAILABLE]: callbacks.onNoHostAvailable,
+ [MeetingEvent.MEETING_START]: callbacks.onMeetingStart,
+ [MeetingEvent.MEETING_PARTICIPANT_JOINED]: callbacks.onParticipantJoin,
+ [MeetingEvent.MY_PARTICIPANT_JOINED]: callbacks.onLocalParticipantJoin,
+ [MeetingEvent.MEETING_PARTICIPANT_LEFT]: callbacks.onParticipantLeave,
+ [MeetingEvent.MY_PARTICIPANT_LEFT]: callbacks.onLocalParticipantLeave,
+ [MeetingEvent.MEETING_PARTICIPANT_LIST_UPDATE]: callbacks.onParticipantListChange,
+ [MeetingEvent.MEETING_PARTICIPANT_AMOUNT_UPDATE]: callbacks.onParticipantAmountChange,
+ [MeetingEvent.MEETING_KICK_PARTICIPANTS]: callbacks.onKickAllParticipants,
+ [MeetingEvent.MEETING_KICK_PARTICIPANT]: callbacks.onKickLocalParticipant,
+ mount: callbacks.onMount,
+ unmount: callbacks.onUnmount,
+ };
+};
+
+export function VideoConference(params: VideoComponentProps) {
+ const {
+ onMeetingStart,
+ onDestroy,
+ onFrameDimensionsChange,
+ onWaitingForHostChange,
+ onConnectionStatusChange,
+ onMeetingStateChange,
+ onSameAccountError,
+ onDevicesStateChange,
+ onHostChange,
+ onHostAvailable,
+ onNoHostAvailable,
+ onParticipantJoin,
+ onLocalParticipantJoin,
+ onParticipantLeave,
+ onLocalParticipantLeave,
+ onParticipantListChange,
+ onParticipantAmountChange,
+ onKickAllParticipants,
+ onKickLocalParticipant,
+ onMount,
+ onUnmount,
+ } = params;
+ const { room, component, addComponent, removeComponent } =
+ useInternalFeatures('videoConference');
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+ const callbacks = useRef>({});
+ const videoInstance = useRef(null);
+
+ useEffect(() => {
+ if (!room || initializedTimestamp || videoInstance.current) return;
+
+ videoInstance.current = new VideoConferenceComponent(params);
+
+ const destroyCallback = () => {
+ removeComponent(videoInstance.current!);
+ videoInstance.current = null;
+ setInitializedTimestamp(null);
+ };
+
+ videoInstance.current.subscribe('destroy', destroyCallback);
+
+ updateCallbacks(params);
+
+ addComponent(videoInstance.current);
+ setInitializedTimestamp(Date.now());
+ }, [room]);
+
+ useEffect(() => {
+ const updatedList = generateCallbackList(params);
+
+ if (
+ !videoInstance.current ||
+ (!Object.values(callbacks.current).length && Object.values(updatedList).every((cb) => !cb))
+ ) {
+ return;
+ }
+
+ updateCallbacks(params);
+ }, [
+ onMeetingStart,
+ onDestroy,
+ onFrameDimensionsChange,
+ onWaitingForHostChange,
+ onConnectionStatusChange,
+ onMeetingStateChange,
+ onSameAccountError,
+ onDevicesStateChange,
+ onHostChange,
+ onHostAvailable,
+ onNoHostAvailable,
+ onParticipantJoin,
+ onLocalParticipantJoin,
+ onParticipantLeave,
+ onLocalParticipantLeave,
+ onParticipantListChange,
+ onParticipantAmountChange,
+ onKickAllParticipants,
+ onKickLocalParticipant,
+ onMount,
+ onUnmount,
+ ]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ }
+ }, [component]);
+
+ const updateCallbacks = useCallback((params: VideoComponentProps) => {
+ const updatedList = generateCallbackList(params);
+
+ Object.entries(updatedList).forEach(([event, callback]) => {
+ if (callbacks.current[event]) {
+ videoInstance.current!.unsubscribe(event, callbacks.current[event]);
+ callbacks.current[event] = undefined;
+ }
+
+ if (callback) {
+ videoInstance.current!.subscribe(event, callback);
+ callbacks.current[event] = callback;
+ }
+ });
+ }, []);
+
+ return <>>;
+}
diff --git a/packages/react/src/components/video/video.types.ts b/packages/react/src/components/video/video.types.ts
new file mode 100644
index 00000000..1d67d7b9
--- /dev/null
+++ b/packages/react/src/components/video/video.types.ts
@@ -0,0 +1,77 @@
+import type {
+ Avatar,
+ CamerasPosition,
+ DeviceEvent,
+ DevicesOptions,
+ Dimensions,
+ LayoutMode,
+ LayoutPosition,
+ Locale,
+ MeetingConnectionStatus,
+ MeetingState,
+ Offset,
+ Participant,
+ ParticipantType,
+} from '../../lib/sdk';
+
+export interface VideoProps {
+ camsOff?: boolean;
+ screenshareOff?: boolean;
+ chatOff?: boolean;
+ enableRecording?: boolean;
+ defaultAvatars?: boolean;
+ offset?: Offset;
+ enableFollow?: boolean;
+ enableGoTo?: boolean;
+ enableGather?: boolean;
+ defaultToolbar?: boolean;
+ devices?: DevicesOptions;
+ language?: string;
+ locales?: Locale[];
+ avatars?: Avatar[];
+ skipMeetingSettings?: boolean;
+ allowGuests?: boolean;
+ participantType?: `${ParticipantType}`;
+ collaborationMode?: {
+ enabled?: boolean;
+ position?: `${CamerasPosition}`;
+ modalPosition?: `${LayoutPosition}`;
+ initialView?: `${LayoutMode}`;
+ };
+ styles?: string;
+ callbacks?: {
+ onToggleMicrophone?: () => void;
+ onToggleCam?: () => void;
+ onToggleRecording?: () => void;
+ onToggleChat?: () => void;
+ onToggleScreenShare?: () => void;
+ onClickHangup?: () => void;
+ onToggleMeetingSetup?: () => void;
+ };
+}
+
+export interface VideoCallbacks {
+ onDestroy?: () => void;
+ onFrameDimensionsChange?: (dimensions: Dimensions) => void;
+ onWaitingForHostChange?: (waiting: boolean) => void;
+ onConnectionStatusChange?: (status: MeetingConnectionStatus) => void;
+ onMeetingStart?: () => void;
+ onMeetingStateChange?: (state: MeetingState) => void;
+ onSameAccountError?: () => void;
+ onDevicesStateChange?: (state: DeviceEvent) => void;
+ onHostChange?: (participantId: string) => void;
+ onHostAvailable?: () => void;
+ onNoHostAvailable?: () => void;
+ onParticipantJoin?: (participant: Participant) => void;
+ onLocalParticipantJoin?: (participant: Participant) => void;
+ onParticipantLeave?: (participant: Participant) => void;
+ onLocalParticipantLeave?: (participant: Participant) => void;
+ onParticipantListChange?: (participants: Participant[]) => void;
+ onParticipantAmountChange?: (amount: number) => void;
+ onKickAllParticipants?: () => void;
+ onKickLocalParticipant?: () => void;
+ onMount?: () => void;
+ onUnmount?: () => void;
+}
+
+export type VideoComponentProps = VideoProps & VideoCallbacks;
diff --git a/packages/react/src/components/who-is-online/index.ts b/packages/react/src/components/who-is-online/index.ts
new file mode 100644
index 00000000..27a7bfad
--- /dev/null
+++ b/packages/react/src/components/who-is-online/index.ts
@@ -0,0 +1,2 @@
+export * from './who-is-online';
+export * from './who-is-online.types';
diff --git a/packages/react/src/components/who-is-online/who-is-online.tsx b/packages/react/src/components/who-is-online/who-is-online.tsx
new file mode 100644
index 00000000..e8cd3585
--- /dev/null
+++ b/packages/react/src/components/who-is-online/who-is-online.tsx
@@ -0,0 +1,44 @@
+import { useEffect, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { WhoIsOnlineComponent } from '../../lib/sdk';
+import { WhoIsOnlineProps } from './who-is-online.types';
+
+export function WhoIsOnline({ position, styles, onMount, onUnmount, ...flags }: WhoIsOnlineProps) {
+ const { room, component, addComponent } =
+ useInternalFeatures('whoIsOnline');
+ const [initializedTimestamp, setInitializedTimestamp] = useState(null);
+
+ const callbacks = {
+ mount: onMount,
+ unmount: onUnmount,
+ };
+
+ useEffect(() => {
+ if (!component) return;
+
+ Object.entries(callbacks).forEach(([event, callback]) => {
+ component.unsubscribe(event, callback);
+
+ if (callback) {
+ component.subscribe(event, callback);
+ }
+ });
+ }, [component, room, onMount, onUnmount]);
+
+ useEffect(() => {
+ if (!room || initializedTimestamp) return;
+
+ const wioInstance = new WhoIsOnlineComponent({ position, styles, ...flags });
+ addComponent(wioInstance);
+ setInitializedTimestamp(Date.now());
+ }, [room]);
+
+ useEffect(() => {
+ if (!component && initializedTimestamp) {
+ setInitializedTimestamp(null);
+ }
+ }, [component]);
+
+ return <>>;
+}
diff --git a/packages/react/src/components/who-is-online/who-is-online.types.ts b/packages/react/src/components/who-is-online/who-is-online.types.ts
new file mode 100644
index 00000000..3a4a55e5
--- /dev/null
+++ b/packages/react/src/components/who-is-online/who-is-online.types.ts
@@ -0,0 +1,14 @@
+import { DefaultComponentProps } from 'src/common/types/global.types';
+
+import type { Position } from '../../lib/sdk';
+
+export type WhoIsOnlineProps = DefaultComponentProps<{
+ position?: `${Position}` | string;
+ styles?: string;
+ disablePresenceControls?: boolean;
+ disableGoToParticipant?: boolean;
+ disableFollowParticipant?: boolean;
+ disablePrivateMode?: boolean;
+ disableGatherAll?: boolean;
+ disableFollowMe?: boolean;
+}>;
diff --git a/packages/react/src/contexts/room.tsx b/packages/react/src/contexts/room.tsx
new file mode 100644
index 00000000..b4a26a40
--- /dev/null
+++ b/packages/react/src/contexts/room.tsx
@@ -0,0 +1,258 @@
+import { isEqual } from 'lodash';
+import { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react';
+
+import SupervizRoom, {
+ type BaseComponent,
+ type LauncherFacade,
+ type Participant,
+ ParticipantEvent,
+ type SuperVizSdkOptions,
+} from '../lib/sdk';
+import {
+ ComponentNames,
+ InternalFeaturesContextData,
+ RoomContextData,
+ RoomProviderCallbacks,
+ RoomProviderProps,
+ SuperVizComponent,
+} from './room.types';
+
+const generateCallbackList = (callbacks: RoomProviderCallbacks) => {
+ return {
+ [ParticipantEvent.JOINED]: callbacks.onParticipantJoined,
+ [ParticipantEvent.LEFT]: callbacks.onParticipantLeft,
+ [ParticipantEvent.LIST_UPDATED]: callbacks.onParticipantListUpdated,
+ [ParticipantEvent.LOCAL_JOINED]: callbacks.onParticipantLocalJoined,
+ [ParticipantEvent.LOCAL_LEFT]: callbacks.onParticipantLocalLeft,
+ [ParticipantEvent.LOCAL_UPDATED]: callbacks.onParticipantLocalUpdated,
+ };
+};
+
+export const SuperVizRoomContext = createContext({
+ hasProvider: false,
+ room: null,
+} as RoomContextData);
+
+/**
+ * it's exported to be used by the internal components,
+ * `never` be exported to the end-users, this is a private hook
+ */
+export function useInternalFeatures(
+ componentName?: ComponentNames,
+): InternalFeaturesContextData {
+ const { hasProvider, ...context } = useContext(SuperVizRoomContext);
+
+ useEffect(() => {
+ if (!hasProvider) {
+ console.error('[SuperViz] You need to wrap your component with SuperVizRoomProvider');
+ }
+ }, [hasProvider]);
+
+ if (componentName) {
+ return {
+ ...context,
+ component: context.activeComponents[componentName],
+ } as InternalFeaturesContextData;
+ }
+
+ return context as InternalFeaturesContextData;
+}
+
+export function SuperVizRoomProvider(params: RoomProviderProps) {
+ const {
+ roomId,
+ group,
+ debug,
+ children,
+ environment,
+ participant,
+ developerKey,
+ customColors,
+ onParticipantJoined,
+ onParticipantLeft,
+ onParticipantListUpdated,
+ onParticipantLocalJoined,
+ onParticipantLocalLeft,
+ onParticipantLocalUpdated,
+ stopAutoStart,
+ } = params;
+
+ const [hasJoinedRoom, setHasJoinedRoom] = useState(false);
+ const [room, setRoom] = useState(null);
+ const [callbacks, setCallbacks] = useState | null>(null);
+ const [activeComponents, setActiveComponents] = useState<
+ Record
+ >({} as Record);
+
+ const fetchingRoom = useRef(false);
+
+ // This effect will start the room when the component is mounted
+ // and stop the room when the component is unmounted
+ useEffect(() => {
+ if (!startRoom || hasJoinedRoom || stopAutoStart) return;
+
+ if (!fetchingRoom.current) startRoom();
+
+ return () => {
+ if (!stopRoom || !hasJoinedRoom) return;
+
+ stopRoom();
+ };
+ }, []);
+
+ useEffect(() => {
+ const updatedCallbacks = generateCallbackList(params);
+
+ if (!room || isEqual(callbacks, updatedCallbacks)) return;
+
+ updateCallbacks(room, params);
+ }, [
+ onParticipantJoined,
+ onParticipantLeft,
+ onParticipantListUpdated,
+ onParticipantLocalJoined,
+ onParticipantLocalLeft,
+ onParticipantLocalUpdated,
+ room,
+ ]);
+
+ useEffect(() => {
+ if (!hasJoinedRoom) return;
+
+ room?.unsubscribe(ParticipantEvent.LOCAL_UPDATED);
+ room?.subscribe(ParticipantEvent.LOCAL_UPDATED, onMyParticipantUpdated);
+ }, [room, activeComponents]);
+
+ function updateCallbacks(room: LauncherFacade, callbacks: RoomProviderCallbacks) {
+ const updatedList = generateCallbackList(callbacks);
+
+ Object.entries(updatedList).forEach(([event, callback]) => {
+ const currentCallback = callbacks[event as keyof RoomProviderCallbacks];
+
+ if ((!callback && currentCallback) || callback !== currentCallback) {
+ room.unsubscribe(event);
+ }
+
+ if (callback) {
+ room.subscribe(event, callback);
+ }
+ });
+
+ setCallbacks(updatedList);
+ }
+
+ async function startRoom(): Promise {
+ if (hasJoinedRoom || room) {
+ console.log('[SuperViz] Room already started');
+ return;
+ }
+
+ try {
+ fetchingRoom.current = true;
+ const room = await SupervizRoom(developerKey, {
+ participant: participant as SuperVizSdkOptions['participant'],
+ roomId,
+ group,
+ environment,
+ debug,
+ customColors,
+ });
+
+ updateCallbacks(room, params);
+ setRoom(room);
+ setHasJoinedRoom(true);
+
+ room.subscribe(ParticipantEvent.LOCAL_UPDATED, onMyParticipantUpdated);
+ room.subscribe(ParticipantEvent.LOCAL_JOINED, onMyParticipantJoined);
+ room.subscribe(ParticipantEvent.LOCAL_LEFT, onMyParticipantLeft);
+ } catch (error) {
+ fetchingRoom.current = false;
+ console.error('[SuperViz] Error starting room', error);
+ }
+
+ fetchingRoom.current = false;
+ }
+
+ function stopRoom(): void {
+ if (!room) {
+ console.error(
+ '[SuperViz] Room not started yet, you need to start the room before stopping it',
+ );
+ return;
+ }
+
+ room.destroy();
+ setActiveComponents({} as Record);
+ setRoom(null);
+ setHasJoinedRoom(false);
+ }
+
+ function addComponent(component: SuperVizComponent) {
+ if (!room) return;
+
+ if (!activeComponents[component.name]) {
+ room?.addComponent(component as BaseComponent);
+ }
+
+ setActiveComponents((prev) => ({ ...prev, [component.name]: component }));
+ }
+
+ function removeComponent(component: SuperVizComponent) {
+ if (!room) return;
+
+ if (activeComponents[component.name]) {
+ room?.removeComponent(component as BaseComponent);
+ }
+
+ setActiveComponents((prev) => {
+ const updated = { ...prev };
+ delete updated[component.name];
+ return updated;
+ });
+ }
+
+ function onMyParticipantUpdated(participant: Participant) {
+ onParticipantLocalUpdated && onParticipantLocalUpdated(participant);
+
+ if (!participant?.activeComponents || !participant?.activeComponents.length) return;
+
+ const deleteList: string[] = [];
+
+ Object.keys(activeComponents).forEach((componentName) => {
+ if (!participant.activeComponents?.includes(componentName as any)) {
+ deleteList.push(componentName);
+ }
+ });
+
+ setActiveComponents((prev) => {
+ const updated = { ...prev };
+ deleteList.forEach((componentName) => {
+ delete updated[componentName as ComponentNames];
+ });
+ return updated;
+ });
+ }
+
+ function onMyParticipantJoined() {
+ setHasJoinedRoom(true);
+ }
+
+ function onMyParticipantLeft() {
+ setHasJoinedRoom(false);
+ }
+
+ const value = useMemo(() => {
+ return {
+ hasProvider: true,
+ hasJoinedRoom,
+ room,
+ addComponent,
+ removeComponent,
+ activeComponents,
+ startRoom,
+ stopRoom,
+ };
+ }, [room, developerKey, participant, roomId, group, activeComponents, hasJoinedRoom]);
+
+ return {children} ;
+}
diff --git a/packages/react/src/contexts/room.types.ts b/packages/react/src/contexts/room.types.ts
new file mode 100644
index 00000000..58c784ce
--- /dev/null
+++ b/packages/react/src/contexts/room.types.ts
@@ -0,0 +1,79 @@
+import type { Presence3D as AutodeskPresence3D } from '@superviz/autodesk-viewer-plugin';
+import type { Presence3D as MatterportPresence3D } from '@superviz/matterport-plugin';
+import type React from 'react';
+
+import type {
+ CommentsComponent,
+ DefaultComponentNames,
+ FormElementsComponent,
+ LauncherFacade,
+ Participant,
+ PointersCanvas,
+ PointersHTML,
+ RealtimeComponent,
+ SuperVizSdkOptions,
+ ThreeJsPresence3D,
+ VideoConferenceComponent,
+ WhoIsOnlineComponent,
+} from '../lib/sdk';
+
+export type ComponentNames = `${DefaultComponentNames}`;
+
+export type RoomContextData = {
+ addComponent: (component: SuperVizComponent) => void;
+ removeComponent: (component: SuperVizComponent) => void;
+ activeComponents: Record;
+ room: LauncherFacade | null;
+ hasJoinedRoom: boolean;
+ hasProvider: boolean;
+ startRoom: () => void;
+ stopRoom: () => void;
+};
+
+export type RoomProviderCallbacks = {
+ onParticipantJoined?: (participant: Participant) => void;
+ onParticipantLeft?: (participant: Participant) => void;
+ onParticipantLocalJoined?: (participant: Participant) => void;
+ onParticipantLocalLeft?: (participant: Participant) => void;
+ onParticipantLocalUpdated?: (participant: Participant) => void;
+ onParticipantListUpdated?: (participantList: Participant[]) => void;
+};
+
+export type RoomProviderProps = RoomProviderCallbacks & {
+ developerKey: string;
+ roomId: SuperVizSdkOptions['roomId'];
+ participant: {
+ id: string;
+ name: string;
+ avatar?: {
+ model3DUrl?: string;
+ imageUrl?: string;
+ };
+ };
+ group: SuperVizSdkOptions['group'];
+ customColors?: SuperVizSdkOptions['customColors'];
+ environment?: SuperVizSdkOptions['environment'];
+ debug?: SuperVizSdkOptions['debug'];
+ children: React.ReactNode;
+ stopAutoStart?: boolean;
+};
+
+export type MatterportComponent = MatterportPresence3D & { name: ComponentNames };
+export type AutoDeskComponent = AutodeskPresence3D & { name: ComponentNames };
+export type ThreeJsComponent = ThreeJsPresence3D & { name: ComponentNames };
+
+export type SuperVizComponent =
+ | VideoConferenceComponent
+ | CommentsComponent
+ | PointersCanvas
+ | PointersHTML
+ | RealtimeComponent
+ | WhoIsOnlineComponent
+ | MatterportComponent
+ | AutoDeskComponent
+ | FormElementsComponent
+ | ThreeJsComponent;
+
+export type InternalFeaturesContextData = T extends SuperVizComponent
+ ? Omit & { component: T }
+ : Omit;
diff --git a/packages/react/src/demo.tsx b/packages/react/src/demo.tsx
new file mode 100644
index 00000000..48b28cef
--- /dev/null
+++ b/packages/react/src/demo.tsx
@@ -0,0 +1,71 @@
+import './style.css';
+
+import { useCallback, useState } from 'react';
+
+import { VideoConference } from './components/video';
+import { SuperVizRoomProvider } from './contexts/room';
+
+function Room() {
+ const [show, setShow] = useState(true);
+ const toggleShow = () => {
+ setShow(!show);
+ };
+
+ const [destroy, setDestroy] = useState(1);
+
+ const destroyCallback = useCallback(() => {
+ if (destroy === 1) {
+ console.error('state 1');
+ } else {
+ console.error('state 2');
+ }
+ }, [destroy]);
+
+ const toggleDestroy = useCallback(() => {
+ setDestroy(destroy === 1 ? 2 : 1);
+ }, [destroy, setDestroy]);
+
+ return (
+ <>
+ Stop Room
+
+ Toggle Destroy
+
+ {show && (
+
+ )}
+ >
+ );
+}
+
+export default function App() {
+ const url = new URL(window.location.href);
+
+ const key = import.meta.env.VITE_SUPERVIZ_DEVELOPER_TOKEN;
+ const roomId = url.searchParams.get('roomId') || 'default-room-id';
+ const random = Math.floor(Math.random() * 1000);
+
+ return (
+ <>
+
+
+
+ >
+ );
+}
diff --git a/packages/react/src/hooks/useAutodesk.ts b/packages/react/src/hooks/useAutodesk.ts
new file mode 100644
index 00000000..769cbf6b
--- /dev/null
+++ b/packages/react/src/hooks/useAutodesk.ts
@@ -0,0 +1,58 @@
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+import type { AutoDeskComponent } from 'src/contexts/room.types';
+
+type UseAutodesk = {
+ isReady: boolean;
+ /**
+ * @function follow
+ * @description follow a participant
+ * @param participantId - participant id to follow, if not provided, follow is disabled
+ * @returns {void}
+ */
+ follow(participantId?: string): void;
+ /**
+ * @function goTo
+ * @description go to a participant
+ * @param participantId - participant id to go to
+ * @returns {void}
+ */
+ goTo: (participantId: string) => void;
+};
+
+export function useAutodesk(): UseAutodesk {
+ const { component } = useInternalFeatures('presence3dAutodesk');
+ const instance = useRef(null);
+ const [isReady, setIsReady] = useState(false);
+
+ useEffect(() => {
+ if (component) {
+ instance.current = component;
+ setIsReady(true);
+ }
+ }, [component]);
+
+ const follow = useCallback(
+ (participantId?: string) => {
+ if (!instance.current) return;
+ instance.current.follow(participantId);
+ },
+ [instance.current, component],
+ );
+
+ const goTo = useCallback(
+ (participantId: string) => {
+ if (!instance.current) return;
+ instance.current.goTo(participantId);
+ },
+ [instance.current, component],
+ );
+
+ return useMemo(() => {
+ return {
+ isReady,
+ follow,
+ goTo,
+ };
+ }, [component, isReady]);
+}
diff --git a/packages/react/src/hooks/useAutodeskPin.ts b/packages/react/src/hooks/useAutodeskPin.ts
new file mode 100644
index 00000000..bde22c38
--- /dev/null
+++ b/packages/react/src/hooks/useAutodeskPin.ts
@@ -0,0 +1,50 @@
+import { AutodeskPin } from '@superviz/autodesk-viewer-plugin';
+import { useEffect, useMemo, useRef } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+type UseAutodeskPin = {
+ pin: AutodeskPin | null;
+ destroy: () => void;
+};
+
+type Params = {
+ autodeskInstance: Autodesk.Viewing.GuiViewer3D;
+};
+
+export function useAutodeskPin({ autodeskInstance }: Params): UseAutodeskPin {
+ const { room } = useInternalFeatures();
+ const loaded = useRef(false);
+ const adapter = useRef(null);
+
+ useEffect(() => {
+ if (!room && loaded.current) {
+ loaded.current = false;
+ adapter.current?.destroy();
+ adapter.current = null;
+ }
+ }, [room]);
+
+ return useMemo(() => {
+ if (!autodeskInstance) {
+ return {
+ pin: null,
+ destroy: () => {},
+ };
+ }
+
+ if (!loaded.current) {
+ loaded.current = true;
+
+ const pin = new AutodeskPin(autodeskInstance);
+ adapter.current = pin;
+ }
+
+ return {
+ pin: adapter.current,
+ destroy: () => {
+ adapter?.current?.destroy();
+ adapter.current = null;
+ },
+ };
+ }, [autodeskInstance, room, adapter.current]);
+}
diff --git a/packages/react/src/hooks/useCanvasPin.ts b/packages/react/src/hooks/useCanvasPin.ts
new file mode 100644
index 00000000..5afd8e1f
--- /dev/null
+++ b/packages/react/src/hooks/useCanvasPin.ts
@@ -0,0 +1,57 @@
+import { useEffect, useRef } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { CanvasPin } from '../lib/sdk';
+
+type UseCanvasPin = {
+ pin: CanvasPin | null;
+ destroy: () => void;
+};
+
+type GoToPinHandler = (position: { x: number; y: number }) => void;
+
+type Params = {
+ onGoToPin?: GoToPinHandler;
+ canvasId: string;
+};
+
+export function useCanvasPin({ canvasId, onGoToPin: goToPinCallback }: Params): UseCanvasPin {
+ const { room } = useInternalFeatures();
+ const loaded = useRef(false);
+ const adapter = useRef(null);
+
+ function onGoToPin(args: { x: number; y: number }) {
+ goToPinCallback && goToPinCallback(args);
+ }
+
+ useEffect(() => {
+ if (!room && adapter.current) {
+ loaded.current = false;
+ adapter.current = null;
+ }
+ }, [room]);
+
+ if (!canvasId || !document.getElementById(canvasId)) {
+ return {
+ pin: null,
+ destroy: () => {},
+ };
+ }
+
+ if (!loaded.current) {
+ loaded.current = true;
+
+ const pin = new CanvasPin(canvasId, {
+ onGoToPin,
+ });
+ adapter.current = pin;
+ }
+
+ return {
+ pin: adapter.current,
+ destroy: () => {
+ adapter.current?.destroy();
+ adapter.current = null;
+ },
+ };
+}
diff --git a/packages/react/src/hooks/useComments.ts b/packages/react/src/hooks/useComments.ts
new file mode 100644
index 00000000..2a57e1bd
--- /dev/null
+++ b/packages/react/src/hooks/useComments.ts
@@ -0,0 +1,68 @@
+import { useMemo } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { CommentsComponent } from '../lib/sdk';
+
+type UseCommentsData = {
+ /**
+ * @function openThreads
+ * @description - Open comments thread
+ * @returns {void}
+ */
+ openThreads: () => void;
+ /**
+ * @function closeThreads
+ * @description - Close comments thread
+ * @returns {void}
+ */
+ closeThreads: () => void;
+ /**
+ * @function enable
+ * @description - Activates the pin adapter and allows the user to create annotations
+ * @returns {void}
+ */
+ enable(): void;
+ /**
+ * @function disable
+ * @description - Deactivates the pin adapter and prevents the user from creating annotations
+ * @returns {void}
+ */
+ disable(): void;
+ /**
+ * @function url
+ * @description Gets the URL of the client
+ * @returns {void}
+ */
+};
+
+export function useComments(): UseCommentsData {
+ const { component, ...context } = useInternalFeatures('comments');
+
+ return useMemo(() => {
+ if (!component) {
+ return {
+ isReady: false,
+ openThreads: () => {},
+ closeThreads: () => {},
+ enable: () => {},
+ disable: () => {},
+ };
+ }
+
+ return {
+ isReady: true,
+ openThreads: () => {
+ component.openThreads();
+ },
+ closeThreads: () => {
+ component.closeThreads();
+ },
+ enable: () => {
+ component.enable();
+ },
+ disable: () => {
+ component.disable();
+ },
+ };
+ }, [component, context.room, context.activeComponents]);
+}
diff --git a/packages/react/src/hooks/useFormElements.ts b/packages/react/src/hooks/useFormElements.ts
new file mode 100644
index 00000000..3a51d54b
--- /dev/null
+++ b/packages/react/src/hooks/useFormElements.ts
@@ -0,0 +1,124 @@
+import { useMemo } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { FormElementsComponent } from '../lib/sdk';
+
+type UseFormElementsData = {
+ /**
+ * @function enableOutline
+ * @description Enables changes in the color of the outline of a field. Color changes are triggered when, in general, another participant interacts with the field on their side AND they also have color changes enabled.
+ *
+ * Enabling this feature through this method overrides the global flag "disableOutline" set in the constructor for this particular input.
+ * @param fieldId The id of the input field or textarea that will have its outline color changed
+ * @returns {void}
+ */
+ enableOutline(fieldId: string): void;
+
+ /**
+ * @function disableOutline
+ * @description Disables changes in the color of the outline of a field.
+ *
+ * Disabling this feature through this method overrides the global flag "disableOutline" set in the constructor for this particular input.
+ * @param fieldId The id of the input field or textarea that will have its outline color changed
+ * @returns {void}
+ */
+ disableOutline(fieldId: string): void;
+
+ /**
+ * @function enableRealtimeSync
+ * @description Enables the synchronization of the content of a field in real time. The content of the field will be updated in real time when another participant interacts with the field on their side AND they also have content synchronization enabled.
+ *
+ * "Content" may refer to the value the user has typed or selected, or the status of the field (checked or not), depending on the type of field.
+ *
+ * Enabling this feature through this method overrides the global flag "disableRealtimeSync" set in the constructor for this particular input.
+ * @param fieldId The id of the input field or textarea that will have its content synchronized
+ * @returns {void}
+ */
+ enableRealtimeSync(fieldId: string): void;
+
+ /**
+ * @function disableRealtimeSync
+ * @description Disables the synchronization of the content of a field in real time.
+ *
+ * Disabling this feature through this method overrides the global flag "disableRealtimeSync" set in the constructor for this particular input.
+ *
+ * @param fieldId The id of the input field or textarea that will have its content synchronized
+ * @returns {void}
+ */
+ disableRealtimeSync(fieldId: string): void;
+
+ /**
+ * @function sync
+ * @description Sends the value of the field to every other participant with the realtime sync enabled for this field.
+ *
+ * This method is useful when you want to update the content of a field without waiting for the user to interact with it.
+ *
+ * If realtime sync is disabled for the field, even though the content won't be updated, every other participant receives an event with details about the sync attempt.
+ * @param fieldId
+ */
+ sync(fieldId: string): void;
+
+ /**
+ * @function registerField
+ * @description Registers a field element.
+
+ A registered field will be monitored and most interactions with it will be shared with every other user in the room that is tracking the same field.
+
+ Examples of common interactions that will be monitored include typing, focusing, and blurring, but more may apply.
+ * @param {string} fieldId The id of the field that will be registered
+ * @returns {void}
+ */
+ registerField(fieldId: string): void;
+
+ /**
+ * @function deregisterField
+ * @description Deregisters a single field
+ * @param {string} fieldId The id of the field that will be deregistered
+ * @returns {void}
+ */
+ deregisterField(fieldId: string): void;
+};
+
+export function useFormElements(): UseFormElementsData {
+ const { component, ...context } = useInternalFeatures('formElements');
+
+ return useMemo(() => {
+ if (!component) {
+ return {
+ isReady: false,
+ enableOutline: () => {},
+ disableOutline: () => {},
+ enableRealtimeSync() {},
+ disableRealtimeSync() {},
+ sync() {},
+ registerField() {},
+ deregisterField() {},
+ };
+ }
+
+ return {
+ isReady: true,
+ enableOutline: (fieldId: string) => {
+ component.enableOutline(fieldId);
+ },
+ disableOutline: (fieldId: string) => {
+ component.disableOutline(fieldId);
+ },
+ enableRealtimeSync(fieldId: string) {
+ component.enableRealtimeSync(fieldId);
+ },
+ disableRealtimeSync(fieldId: string) {
+ component.disableRealtimeSync(fieldId);
+ },
+ sync(fieldId: string) {
+ component.sync(fieldId);
+ },
+ registerField(fieldId: string) {
+ component.registerField(fieldId);
+ },
+ deregisterField(fieldId: string) {
+ component.deregisterField(fieldId);
+ },
+ };
+ }, [component, context.room, context.activeComponents]);
+}
diff --git a/packages/react/src/hooks/useHtmlPin.ts b/packages/react/src/hooks/useHtmlPin.ts
new file mode 100644
index 00000000..366fdd66
--- /dev/null
+++ b/packages/react/src/hooks/useHtmlPin.ts
@@ -0,0 +1,51 @@
+import { useEffect, useMemo, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { CommentsComponent, HTMLPin } from '../lib/sdk';
+
+type UseHTMLPin = {
+ pin: HTMLPin | null;
+ destroy: () => void;
+};
+
+type Params = {
+ containerId: string;
+ dataAttributeName?: string;
+ dataAttributeValueFilters?: RegExp[];
+};
+
+let pin: HTMLPin | null = null;
+
+export function useHTMLPin({ containerId, ...params }: Params): UseHTMLPin {
+ const { room } = useInternalFeatures();
+ const [loaded, setLoaded] = useState(false);
+
+ useEffect(() => {
+ if (!room && pin) {
+ pin = null;
+ setLoaded(false);
+ }
+ }, [room]);
+
+ return useMemo(() => {
+ if (!containerId || !document.getElementById(containerId)) {
+ return {
+ pin: null,
+ destroy: () => {},
+ };
+ }
+
+ if (!pin) {
+ pin = new HTMLPin(containerId, params);
+ setLoaded(true);
+ }
+
+ return {
+ pin: pin,
+ destroy: () => {
+ pin?.destroy();
+ setLoaded(false);
+ },
+ };
+ }, [containerId, room, loaded]);
+}
diff --git a/packages/react/src/hooks/useMatterport.ts b/packages/react/src/hooks/useMatterport.ts
new file mode 100644
index 00000000..60ce6d57
--- /dev/null
+++ b/packages/react/src/hooks/useMatterport.ts
@@ -0,0 +1,66 @@
+import type { Presence3D } from '@superviz/matterport-plugin';
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+import { MatterportComponent } from 'src/contexts/room.types';
+
+type UseMatterportData = {
+ isReady: boolean;
+ /**
+ * @function follow
+ * @description follow a participant
+ * @param participantId - participant id to follow, if not provided, follow is disabled
+ * @returns {void}
+ */
+ follow(participantId?: string): void;
+ /**
+ * @function goTo
+ * @description go to a participant
+ * @param participantId - participant id to go to
+ * @returns {void}
+ */
+ goTo: (participantId: string) => void;
+};
+
+export function useMatterport(): UseMatterportData {
+ const { component, room, ...context } =
+ useInternalFeatures('presence3dMatterport');
+ const instance = useRef(null);
+ const [isReady, setIsReady] = useState(false);
+
+ useEffect(() => {
+ if (!component) return;
+ instance.current = component;
+ setIsReady(true);
+ }, [component]);
+
+ useEffect(() => {
+ if (!room && instance.current) {
+ instance.current = null;
+ setIsReady(false);
+ }
+ }, [room]);
+
+ const follow = useCallback(
+ (participantId?: string) => {
+ if (!instance.current) return;
+ instance.current.follow(participantId);
+ },
+ [instance.current, component],
+ );
+
+ const goTo = useCallback(
+ (participantId: string) => {
+ if (!instance.current) return;
+ instance.current.goTo(participantId);
+ },
+ [instance.current, component],
+ );
+
+ return useMemo(() => {
+ return {
+ isReady,
+ follow,
+ goTo,
+ };
+ }, [room, context.activeComponents, component, instance.current, isReady]);
+}
diff --git a/packages/react/src/hooks/useMatterportPin.ts b/packages/react/src/hooks/useMatterportPin.ts
new file mode 100644
index 00000000..5721197c
--- /dev/null
+++ b/packages/react/src/hooks/useMatterportPin.ts
@@ -0,0 +1,52 @@
+import { MatterportPin } from '@superviz/matterport-plugin';
+import type { MpSdk } from '@superviz/matterport-plugin/dist/common/types/matterport.types';
+import { useEffect, useMemo, useRef } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+type UseMatterportPin = {
+ pin: MatterportPin | null;
+ destroy: () => void;
+};
+
+type Params = {
+ matterportInstance: MpSdk;
+ showcaseWindow: HTMLIFrameElement;
+};
+
+export function useMatterportPin({ matterportInstance, showcaseWindow }: Params): UseMatterportPin {
+ const { room } = useInternalFeatures();
+ const loaded = useRef(false);
+ const adapter = useRef(null);
+
+ useEffect(() => {
+ if (!room && loaded.current) {
+ loaded.current = false;
+ adapter.current?.destroy();
+ adapter.current = null;
+ }
+ }, [room]);
+
+ return useMemo(() => {
+ if (!showcaseWindow || !matterportInstance) {
+ return {
+ pin: null,
+ destroy: () => {},
+ };
+ }
+
+ if (!loaded.current) {
+ loaded.current = true;
+
+ const pin = new MatterportPin(matterportInstance, showcaseWindow);
+ adapter.current = pin;
+ }
+
+ return {
+ pin: adapter.current,
+ destroy: () => {
+ adapter.current?.destroy();
+ adapter.current = null;
+ },
+ };
+ }, [showcaseWindow, matterportInstance]);
+}
diff --git a/packages/react/src/hooks/useMouse.ts b/packages/react/src/hooks/useMouse.ts
new file mode 100644
index 00000000..397de5a9
--- /dev/null
+++ b/packages/react/src/hooks/useMouse.ts
@@ -0,0 +1,50 @@
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { PointersCanvas, PointersHTML } from '../lib/sdk';
+
+type UseMouseData = {
+ isReady: boolean;
+ /**
+ * @function toggleMeetingSetup
+ * @description open/close meeting setup
+ * @returns {void}
+ */
+ transform: (data: { translate?: { x?: number; y?: number }; scale?: number }) => void;
+};
+
+export function useMouse(): UseMouseData {
+ const { component, room, ...context } = useInternalFeatures(
+ 'presence',
+ );
+ const instance = useRef(null);
+ const [isReady, setIsReady] = useState(false);
+
+ useEffect(() => {
+ if (component) {
+ instance.current = component;
+ setIsReady(true);
+ }
+
+ if (!room && isReady) {
+ instance.current = null;
+ setIsReady(false);
+ }
+ }, [component]);
+
+ const transform = useCallback(
+ (data: { translate?: { x?: number; y?: number }; scale?: number }) => {
+ if (!instance.current) return;
+
+ instance.current.transform(data);
+ },
+ [instance.current],
+ );
+
+ return useMemo(() => {
+ return {
+ isReady,
+ transform,
+ };
+ }, [room, context.activeComponents, component, isReady]);
+}
diff --git a/packages/react/src/hooks/useRealtime.ts b/packages/react/src/hooks/useRealtime.ts
new file mode 100644
index 00000000..c2973ae6
--- /dev/null
+++ b/packages/react/src/hooks/useRealtime.ts
@@ -0,0 +1,172 @@
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import {
+ Channel,
+ RealtimeComponent,
+ RealtimeComponentState,
+ type RealtimeMessage,
+} from '../lib/sdk';
+
+type UseRealtimeData = {
+ /**
+ * @property isReady
+ * @description is the realtime component ready
+ * @returns {boolean}
+ */
+ isReady: boolean;
+ /**
+ * @function subscribe
+ * @description subscribe to a realtime event
+ * @returns {void}
+ */
+ subscribe: (event: string, callback: T) => void;
+ /**
+ * @function unsubscribe
+ * @description unsubscribe from a realtime event
+ * @returns {void}
+ */
+ unsubscribe: (event: string, callback: T) => void;
+ /**
+ * @function publish
+ * @description publish a realtime event
+ * @returns {void}
+ */
+ publish: (event: string, data: T) => void;
+ /**
+ * @function string
+ * @description get realtime client data history
+ * @returns {RealtimeMessage | Record}
+ */
+ fetchHistory: (
+ eventName?: string,
+ ) => Promise | null>;
+};
+
+type Callback = (data: any) => void;
+
+export function useRealtime(channelName: string): UseRealtimeData {
+ const [started, setStarted] = useState(false);
+ const [channelReady, setChannelReady] = useState(false);
+ const { component, room, ...context } = useInternalFeatures('realtime');
+ const eventsToSubscribe = useRef>({});
+ const channel = useRef(null);
+
+ useEffect(() => {
+ if (!component) return;
+
+ if (component['state'] === RealtimeComponentState.STARTED) {
+ setStarted(true);
+ return;
+ }
+
+ component.subscribe('realtime-component.state-changed', (state) => {
+ setStarted(state === RealtimeComponentState.STARTED);
+ });
+ }, [component, eventsToSubscribe.current]);
+
+ useEffect(() => {
+ (async () => {
+ if ((!started && !channel.current) || !component) return;
+ channel.current = await component!.connect(channelName);
+
+ if (channel.current['state'] === 'CONNECTED') {
+ setChannelReady(true);
+ return;
+ }
+
+ channel.current.subscribe('realtime-channel.state-changed', (state) => {
+ setChannelReady(state === 'CONNECTED');
+ });
+ })();
+ }, [started]);
+
+ useEffect(() => {
+ if (channel.current && !room) {
+ channel.current.disconnect();
+ channel.current = null;
+ setChannelReady(false);
+ setStarted(false);
+ }
+ }, [component, room]);
+
+ useEffect(() => {
+ if (!channelReady) return;
+
+ if (Object.keys(eventsToSubscribe.current).length) {
+ Object.entries(eventsToSubscribe.current).forEach(([event, callbacks]) => {
+ callbacks.forEach((callback) => {
+ channel.current!.subscribe(event, callback as Callback);
+ });
+ });
+
+ eventsToSubscribe.current = {};
+ }
+ }, [channelReady]);
+
+ const subscribe = useCallback(
+ (event: string, callback: Callback) => {
+ if (!channel.current) {
+ const previus = eventsToSubscribe.current[event] || [];
+
+ eventsToSubscribe.current[event] = previus.includes(callback)
+ ? previus
+ : [...previus, callback];
+
+ return;
+ }
+
+ channel.current.subscribe(event, callback);
+ },
+ [component, context, eventsToSubscribe.current],
+ );
+
+ const publish = useCallback(
+ (event: string, data: any) => {
+ if (!started || !channelReady) return;
+
+ channel.current!.publish(event, data);
+ },
+ [component, context, started],
+ );
+
+ const unsubscribe = useCallback(
+ (event: string, callback: Callback) => {
+ if (!started || !channelReady) return;
+
+ channel.current!.unsubscribe(event, callback);
+ },
+ [component, context, started],
+ );
+
+ const fetchHistory = useCallback(
+ async (
+ eventName?: string,
+ ): Promise | null> => {
+ if (!started) {
+ console.warn('[SuperViz] Realtime component is not ready - try again later');
+ return Promise.resolve(null);
+ }
+
+ if (!channelReady) {
+ console.warn(`[SuperViz] Channel ${channelName} is not ready - try again later`);
+ return Promise.resolve(null);
+ }
+
+ const response = await channel.current!.fetchHistory(eventName);
+
+ return response;
+ },
+ [component, context, started],
+ );
+
+ return useMemo(() => {
+ return {
+ isReady: channelReady && started,
+ publish,
+ subscribe,
+ unsubscribe,
+ fetchHistory,
+ };
+ }, [component, context, started, channelReady]);
+}
diff --git a/packages/react/src/hooks/useRealtimeParticipant.ts b/packages/react/src/hooks/useRealtimeParticipant.ts
new file mode 100644
index 00000000..ea7c1d63
--- /dev/null
+++ b/packages/react/src/hooks/useRealtimeParticipant.ts
@@ -0,0 +1,172 @@
+import { PresenceCallback, PresenceEvent } from '@superviz/socket-client';
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { Channel, PresenceEvents, RealtimeComponent, RealtimeComponentState } from '../lib/sdk';
+
+type Events = PresenceEvents | `${PresenceEvents}`;
+
+type UseRealtimeParticipantData = {
+ /**
+ * @property isReady
+ * @description is the channel ready
+ * @returns {boolean}
+ */
+ isReady: boolean;
+ /**
+ * @function subscribe
+ * @description subscribe to a presence event
+ * @returns {void}
+ */
+ subscribe: (event: Events, callback: PresenceCallback) => void;
+ /**
+ * @function unsubscribe
+ * @description unsubscribe from a presence event
+ * @returns {void}
+ */
+ unsubscribe: (event: Events) => void;
+ /**
+ * @function update
+ * @description update a realtime presence event
+ * @returns {void}
+ */
+ update: (data: T) => void;
+ /**
+ * @function string
+ * @description get realtime client data history
+ * @returns {RealtimeMessage | Record}
+ */
+ getAll: () => Promise;
+};
+
+export function useRealtimeParticipant(channelName: string): UseRealtimeParticipantData {
+ const [started, setStarted] = useState(false);
+ const [channelReady, setChannelReady] = useState(false);
+ const { component, room, ...context } = useInternalFeatures('realtime');
+ const eventsToSubscribe = useRef[]>>({
+ [PresenceEvents.JOINED_ROOM]: [],
+ [PresenceEvents.LEAVE]: [],
+ [PresenceEvents.UPDATE]: [],
+ });
+
+ const channel = useRef(null);
+
+ useEffect(() => {
+ if (!component) return;
+
+ if (component['state'] === RealtimeComponentState.STARTED) {
+ setStarted(true);
+ return;
+ }
+
+ component.subscribe('realtime-component.state-changed', (state) => {
+ setStarted(state === RealtimeComponentState.STARTED);
+ });
+ }, [component, eventsToSubscribe.current]);
+
+ useEffect(() => {
+ if ((!started && !channel.current) || !component) return;
+ const connectChannel = async () => {
+ channel.current = await component!.connect(channelName);
+
+ if (channel.current['state'] === 'CONNECTED') {
+ setChannelReady(true);
+ return;
+ }
+
+ channel.current.subscribe('realtime-channel.state-changed', (state) => {
+ setChannelReady(state === 'CONNECTED');
+ });
+ };
+
+ connectChannel();
+ }, [started]);
+
+ useEffect(() => {
+ if (channel.current && !room) {
+ channel.current.disconnect();
+ channel.current = null;
+ setChannelReady(false);
+ setStarted(false);
+ }
+ }, [component, room]);
+
+ useEffect(() => {
+ if (!channelReady) return;
+
+ if (Object.keys(eventsToSubscribe.current).length) {
+ Object.entries(eventsToSubscribe.current).forEach(([event, callbacks]) => {
+ callbacks.forEach((callback) => {
+ channel.current!.participant.subscribe(event as PresenceEvents, callback);
+ });
+ });
+
+ eventsToSubscribe.current = {
+ [PresenceEvents.JOINED_ROOM]: [],
+ [PresenceEvents.LEAVE]: [],
+ [PresenceEvents.UPDATE]: [],
+ };
+ }
+ }, [channelReady]);
+
+ const subscribe = useCallback(
+ (event, callback) => {
+ if (!channel.current) {
+ const previous = eventsToSubscribe.current[event] || [];
+
+ eventsToSubscribe.current[event] = previous.includes(callback)
+ ? previous
+ : [...previous, callback];
+
+ return;
+ }
+
+ channel.current.participant.subscribe(event, callback);
+ },
+ [component, context, eventsToSubscribe.current],
+ );
+
+ const update = useCallback(
+ (data: T) => {
+ if (!started || !channelReady) return;
+
+ channel.current!.participant.update(data);
+ },
+ [component, context, started],
+ );
+
+ const unsubscribe = useCallback(
+ (event) => {
+ if (!started || !channelReady) return;
+
+ channel.current!.participant.unsubscribe(event);
+ },
+ [component, context, started],
+ );
+
+ const getAll = useCallback(async (): Promise => {
+ if (!started) {
+ console.warn('[SuperViz] Realtime component is not ready - try again later');
+ return Promise.resolve([]);
+ }
+
+ if (!channelReady) {
+ console.warn(`[SuperViz] Channel ${channelName} is not ready - try again later`);
+ return Promise.resolve([]);
+ }
+
+ const response = await channel.current!.participant.getAll();
+
+ return response;
+ }, [component, context, started]);
+
+ return useMemo(() => {
+ return {
+ isReady: channelReady && started,
+ update,
+ subscribe,
+ unsubscribe,
+ getAll,
+ };
+ }, [component, context, started, channelReady]);
+}
diff --git a/packages/react/src/hooks/useSuperviz.ts b/packages/react/src/hooks/useSuperviz.ts
new file mode 100644
index 00000000..a4dfd051
--- /dev/null
+++ b/packages/react/src/hooks/useSuperviz.ts
@@ -0,0 +1,16 @@
+import { useMemo } from 'react';
+
+import { useInternalFeatures } from '../contexts/room';
+
+export function useSuperviz() {
+ const { startRoom, stopRoom, hasJoinedRoom } = useInternalFeatures();
+
+ return useMemo(
+ () => ({
+ startRoom,
+ stopRoom,
+ hasJoinedRoom,
+ }),
+ [startRoom, stopRoom, hasJoinedRoom],
+ );
+}
diff --git a/packages/react/src/hooks/useThree.ts b/packages/react/src/hooks/useThree.ts
new file mode 100644
index 00000000..65459f95
--- /dev/null
+++ b/packages/react/src/hooks/useThree.ts
@@ -0,0 +1,57 @@
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+import type { ThreeJsComponent } from 'src/contexts/room.types';
+
+type UseThreeData = {
+ isReady: boolean;
+ /**
+ * @function follow
+ * @description follow a participant
+ * @param participantId - participant id to follow, if not provided, follow is disabled
+ * @returns {void}
+ */
+ follow(participantId?: string): void;
+ /**
+ * @function goTo
+ * @description go to a participant
+ * @param participantId - participant id to go to
+ * @returns {void}
+ */
+ goTo: (participantId: string) => void;
+};
+
+export function useThree(): UseThreeData {
+ const { component, ...context } = useInternalFeatures('presence3dThreejs');
+ const instance = useRef(null);
+ const [isReady, setIsReady] = useState(false);
+
+ useEffect(() => {
+ if (!component) return;
+ instance.current = component;
+ setIsReady(true);
+ }, [component]);
+
+ const follow = useCallback(
+ (participantId?: string) => {
+ if (!instance.current) return;
+ instance.current.follow(participantId);
+ },
+ [instance.current, component],
+ );
+
+ const goTo = useCallback(
+ (participantId: string) => {
+ if (!instance.current) return;
+ instance.current.goTo(participantId);
+ },
+ [instance.current, component],
+ );
+
+ return useMemo(() => {
+ return {
+ isReady,
+ follow,
+ goTo,
+ };
+ }, [context.room, context.activeComponents, component, isReady]);
+}
diff --git a/packages/react/src/hooks/useThreePin.ts b/packages/react/src/hooks/useThreePin.ts
new file mode 100644
index 00000000..2aa5549f
--- /dev/null
+++ b/packages/react/src/hooks/useThreePin.ts
@@ -0,0 +1,62 @@
+import { ThreeJsPin } from '@superviz/threejs-plugin';
+import { useEffect, useMemo, useRef } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+import type { Camera, Object3D, Renderer, Scene } from 'three';
+
+type UseThreeJsPin = {
+ pin: ThreeJsPin | null;
+ destroy: () => void;
+};
+
+type Params = {
+ scene: Scene;
+ renderer: Renderer;
+ camera: Camera;
+ player?: Object3D;
+ controls?: any;
+};
+
+export function useThreeJsPin({
+ scene,
+ renderer,
+ camera,
+ player,
+ controls,
+}: Params): UseThreeJsPin {
+ const { room } = useInternalFeatures();
+ const loaded = useRef(false);
+ const adapter = useRef(null);
+
+ useEffect(() => {
+ if (!room && loaded.current) {
+ loaded.current = false;
+ adapter.current?.destroy();
+ adapter.current = null;
+ }
+ }, [room]);
+
+ return useMemo(() => {
+ if (!scene || !renderer || !camera) {
+ return {
+ pin: null,
+ destroy: () => {},
+ };
+ }
+
+ if (!loaded.current) {
+ loaded.current = true;
+
+ // @ts-ignore
+ const pin = new ThreeJsPin(scene, renderer, camera, player, controls);
+ adapter.current = pin;
+ }
+
+ return {
+ pin: adapter.current,
+ destroy: () => {
+ adapter.current?.destroy();
+ adapter.current = null;
+ },
+ };
+ }, [scene, renderer, camera, player, controls]);
+}
diff --git a/packages/react/src/hooks/useVideo.ts b/packages/react/src/hooks/useVideo.ts
new file mode 100644
index 00000000..f8b9a3d3
--- /dev/null
+++ b/packages/react/src/hooks/useVideo.ts
@@ -0,0 +1,119 @@
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import { useInternalFeatures } from 'src/contexts/room';
+
+import { VideoConferenceComponent } from '../lib/sdk';
+
+type UseVideoData = {
+ isReady: boolean;
+ /**
+ * @function toggleMeetingSetup
+ * @description open/close meeting setup
+ * @returns {void}
+ */
+ toggleMeetingSetup: () => void;
+ /**
+ * @function toggleMicrophone
+ * @description mute/unmute user's microphone
+ * @returns {void}
+ */
+ toggleMicrophone: () => void;
+ /**
+ * @function toggleCam
+ * @description enable/disable user's camera
+ * @returns {void}
+ */
+ toggleCam: () => void;
+ /**
+ * @function toggleScreenShare
+ * @description enable/disable user's screen share
+ * @returns {void}
+ */
+ toggleScreenShare: () => void;
+ /**
+ * @function toggleChat
+ * @description open/close meeting chat
+ * @returns {void}
+ */
+ toggleChat: () => void;
+ /**
+ * @function toggleRecording
+ * @description open/close meeting recording
+ * @returns {void}
+ */
+ toggleRecording: () => void;
+ /**
+ * @function hangUp
+ * @description hang up user's call
+ * @returns {void}
+ * */
+ hangUp: () => void;
+};
+
+export function useVideo(): UseVideoData {
+ const { component, room, ...context } =
+ useInternalFeatures('videoConference');
+ const instance = useRef(null);
+ const [isReady, setIsReady] = useState(false);
+
+ useEffect(() => {
+ if (component) {
+ instance.current = component;
+ setIsReady(true);
+ }
+ }, [component]);
+
+ useEffect(() => {
+ if (!room && instance.current) {
+ instance.current = null;
+ setIsReady(false);
+ }
+ }, [room]);
+
+ const toggleMeetingSetup = useCallback(() => {
+ if (!instance.current) return;
+ instance.current.toggleMeetingSetup();
+ }, [instance.current]);
+
+ const toggleMicrophone = useCallback(() => {
+ if (!instance.current) return;
+ instance.current.toggleMicrophone();
+ }, [instance.current]);
+
+ const toggleCam = useCallback(() => {
+ if (!instance.current) return;
+ instance.current.toggleCam();
+ }, [instance.current]);
+
+ const toggleScreenShare = useCallback(() => {
+ if (!instance.current) return;
+ instance.current.toggleScreenShare();
+ }, [instance.current]);
+
+ const toggleChat = useCallback(() => {
+ if (!instance.current) return;
+ instance.current.toggleChat();
+ }, [instance.current]);
+
+ const toggleRecording = useCallback(() => {
+ if (!instance.current) return;
+ instance.current.toggleRecording();
+ }, [instance.current]);
+
+ const hangUp = useCallback(() => {
+ if (!instance.current) return;
+ instance.current.hangUp();
+ }, [instance.current]);
+
+ return useMemo(() => {
+ return {
+ isReady,
+ toggleMeetingSetup,
+ toggleMicrophone,
+ toggleCam,
+ toggleScreenShare,
+ toggleChat,
+ toggleRecording,
+ hangUp,
+ };
+ }, [room, context.activeComponents, component, isReady]);
+}
diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts
new file mode 100644
index 00000000..3480e2e1
--- /dev/null
+++ b/packages/react/src/index.ts
@@ -0,0 +1,26 @@
+export * from './components/autodesk';
+export * from './components/comments';
+export * from './components/form-elements';
+export * from './components/matterport';
+export * from './components/mouse-pointers';
+export * from './components/realtime';
+export * from './components/three';
+export * from './components/video';
+export * from './components/who-is-online';
+export { SuperVizRoomProvider } from './contexts/room';
+export { useAutodesk } from './hooks/useAutodesk';
+export { useAutodeskPin } from './hooks/useAutodeskPin';
+export { useCanvasPin } from './hooks/useCanvasPin';
+export { useComments } from './hooks/useComments';
+export { useFormElements } from './hooks/useFormElements';
+export { useHTMLPin } from './hooks/useHtmlPin';
+export { useMatterport } from './hooks/useMatterport';
+export { useMatterportPin } from './hooks/useMatterportPin';
+export { useMouse } from './hooks/useMouse';
+export { useRealtime } from './hooks/useRealtime';
+export { useRealtimeParticipant } from './hooks/useRealtimeParticipant';
+export { useSuperviz } from './hooks/useSuperviz';
+export { useThree } from './hooks/useThree';
+export { useThreeJsPin } from './hooks/useThreePin';
+export { useVideo } from './hooks/useVideo';
+export { createTheme } from './utils/create-theme';
diff --git a/packages/react/src/lib/sdk/index.ts b/packages/react/src/lib/sdk/index.ts
new file mode 100644
index 00000000..040d206b
--- /dev/null
+++ b/packages/react/src/lib/sdk/index.ts
@@ -0,0 +1,51 @@
+import SupervizRoom from '@superviz/sdk';
+export { SupervizRoom as default };
+
+export type {
+ Avatar,
+ DevicesOptions,
+ LauncherFacade,
+ Participant,
+ ParticipantType,
+ RealtimeMessage,
+ SuperVizSdkOptions,
+} from '@superviz/sdk';
+export {
+ CanvasPin,
+ Comments as CommentsComponent,
+ ComponentLifeCycleEvent,
+ FormElements as FormElementsComponent,
+ FrameEvent,
+ HTMLPin,
+ MeetingEvent,
+ MousePointers as MousePointersComponent,
+ ParticipantEvent,
+ PresenceEvents,
+ Realtime as RealtimeComponent,
+ RealtimeComponentEvent,
+ RealtimeComponentState,
+ VideoConference as VideoConferenceComponent,
+ WhoIsOnline as WhoIsOnlineComponent,
+} from '@superviz/sdk';
+export type { ColorsVariablesNames } from '@superviz/sdk/dist/common/types/colors.types';
+export type {
+ DeviceEvent,
+ Dimensions,
+ MeetingConnectionStatus,
+ MeetingState,
+} from '@superviz/sdk/dist/common/types/events.types';
+export type { BaseComponent } from '@superviz/sdk/dist/components/base';
+export type { ButtonLocation, CommentsSide } from '@superviz/sdk/dist/components/comments/types';
+export type { PointersCanvas } from '@superviz/sdk/dist/components/presence-mouse/canvas';
+export type { PointersHTML } from '@superviz/sdk/dist/components/presence-mouse/html';
+export type { Channel } from '@superviz/sdk/dist/components/realtime/channel';
+export type { ComponentNames as DefaultComponentNames } from '@superviz/sdk/dist/components/types';
+export type { Position } from '@superviz/sdk/dist/components/who-is-online/types';
+export type {
+ CamerasPosition,
+ LayoutMode,
+ LayoutPosition,
+ Locale,
+ Offset,
+} from '@superviz/sdk/dist/services/video-conference-manager/types';
+export type { Presence3D as ThreeJsPresence3D } from '@superviz/threejs-plugin';
diff --git a/packages/react/src/main.tsx b/packages/react/src/main.tsx
new file mode 100644
index 00000000..6c65431a
--- /dev/null
+++ b/packages/react/src/main.tsx
@@ -0,0 +1,10 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+
+import App from './demo';
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+ ,
+);
diff --git a/packages/react/src/style.css b/packages/react/src/style.css
new file mode 100644
index 00000000..375f1c3d
--- /dev/null
+++ b/packages/react/src/style.css
@@ -0,0 +1,124 @@
+* {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ box-sizing: border-box;
+ margin: 0;
+}
+
+body {
+ min-height: 100vh;
+}
+
+#root {
+ background: #e9e5ef;
+ height: 100%;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+}
+
+main {
+ padding: 1rem;
+ width: 100%;
+ height: 100%;
+ gap: 1rem;
+ display: flex;
+ flex-direction: column;
+ overflow: auto;
+}
+
+section {
+ width: 50%;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ width: 100%;
+ border-radius: 6px;
+}
+
+h1 {
+ font-size: 1rem;
+ margin: 0.5rem;
+ color: #39363e;
+ text-align: center;
+}
+
+h2 {
+ font-size: 1rem;
+ line-height: 150%;
+ margin-bottom: 0.5rem;
+ color: #39363e;
+}
+
+button {
+ all: unset;
+ border-radius: 6px;
+ font-size: 1rem;
+ line-height: 1rem;
+ height: 2rem;
+ color: #efefef;
+ text-align: center;
+ background-color: #6210cc;
+ cursor: pointer;
+}
+
+button:hover {
+ background-color: #baa9ff;
+ color: #39363e;
+}
+
+.container {
+ background-color: #c9c4d1;
+ border-radius: 6px;
+ padding: 0.8rem 1rem;
+ width: 100%;
+}
+
+hr {
+ margin: 1rem 0;
+ display: block;
+ height: 1px;
+ border: 0;
+ border-top: 1px solid #c9c4d1;
+ padding: 0;
+ width: 100%;
+}
+
+.container * {
+ width: 100%;
+}
+
+input {
+ all: unset;
+ border-radius: 6px;
+ font-size: 1rem;
+ line-height: 1rem;
+ height: calc(2rem - 6px);
+ color: #39363e;
+ background-color: #fff;
+ transition: 0.15s all ease-in;
+ padding: 3px 10px;
+ width: calc(100% - 20px) !important;
+}
+
+code {
+ display: block;
+}
+
+.subscribe-options {
+ display: flex;
+ flex-direction: row;
+ gap: 0.5rem;
+ margin: 0.5rem 0;
+}
+
+.events-info {
+ display: flex;
+ flex-direction: row;
+ gap: 1rem;
+ width: 100%;
+}
+
+.last-message {
+ margin-top: 1rem;
+ width: 100%;
+}
diff --git a/packages/react/src/utils/create-theme.ts b/packages/react/src/utils/create-theme.ts
new file mode 100644
index 00000000..4c9d2667
--- /dev/null
+++ b/packages/react/src/utils/create-theme.ts
@@ -0,0 +1,35 @@
+import type { ColorsVariablesNames } from '../lib/sdk';
+
+function convertColorFormat(color: string): string {
+ color = color.replace('#', '');
+
+ if (color.length === 6) {
+ const r = parseInt(color.substring(0, 2), 16);
+ const g = parseInt(color.substring(2, 4), 16);
+ const b = parseInt(color.substring(4, 6), 16);
+
+ return `${r} ${g} ${b}`;
+ } else if (color.startsWith('rgb(') && color.endsWith(')')) {
+ const rgbValues = color.substring(4, color.length - 1).split(',');
+
+ return `${rgbValues[0].trim()} ${rgbValues[1].trim()} ${rgbValues[2].trim()}`;
+ } else {
+ return color;
+ }
+}
+
+/**
+ * @function createTheme
+ * @description Creates a theme object by converting color values to a specific format.
+ * @param colors - An object containing color variables and their values.
+ * @returns The theme object with converted color values.
+ */
+export function createTheme(colors: Partial>) {
+ const theme: Record = {};
+
+ for (const [key, value] of Object.entries(colors)) {
+ theme[key] = convertColorFormat(value);
+ }
+
+ return theme;
+}
diff --git a/packages/react/src/vite-env.d.ts b/packages/react/src/vite-env.d.ts
new file mode 100644
index 00000000..11f02fe2
--- /dev/null
+++ b/packages/react/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json
new file mode 100644
index 00000000..4a0d9637
--- /dev/null
+++ b/packages/react/tsconfig.json
@@ -0,0 +1,31 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "useDefineForClassFields": true,
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
+ "allowJs": false,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "declaration": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true ,
+ "declarationMap": true,
+ "baseUrl": ".",
+ "paths": {
+ "react-vite-library": [ "src/component/index.ts" ]
+ },
+ "typeRoots": [
+ "node_modules/@types",
+ "src/component/index.d.ts"
+ ]
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/packages/react/tsconfig.node.json b/packages/react/tsconfig.node.json
new file mode 100644
index 00000000..bdf5d669
--- /dev/null
+++ b/packages/react/tsconfig.node.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "module": "ESNext",
+ "moduleResolution": "Node",
+ "allowSyntheticDefaultImports": true,
+ "resolveJsonModule": true,
+ },
+ "include": ["vite.config.ts","package.json"],
+}
\ No newline at end of file
diff --git a/packages/react/vite.config.ts b/packages/react/vite.config.ts
new file mode 100644
index 00000000..04b1b8b8
--- /dev/null
+++ b/packages/react/vite.config.ts
@@ -0,0 +1,48 @@
+import path from 'node:path';
+import url from 'node:url';
+
+import react from '@vitejs/plugin-react-swc';
+import { glob } from 'glob';
+import { defineConfig } from 'vite';
+import dts from 'vite-plugin-dts';
+import tsConfigPaths from 'vite-tsconfig-paths';
+
+import { peerDependencies } from './package.json';
+import replace from '@rollup/plugin-replace';
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ react(),
+ tsConfigPaths(),
+ dts({
+ include: ['src/**/*.{ts,tsx}'],
+ exclude: ['**/*.spec.ts', '**/*.spec.tsx', 'src/main.tsx', 'src/demo.tsx'],
+ }),
+ replace({
+ 'Object.defineProperty(exports, "__esModule", { value: true });':
+ 'Object.defineProperty(exports || {}, "__esModule", { value: true });',
+ delimiters: ['\n', '\n'],
+ preventAssignment: true,
+ }),
+ ],
+ build: {
+ lib: {
+ entry: path.resolve('src', 'index.ts'),
+ name: 'superviz-sdk-react',
+ formats: ['es', 'cjs'],
+ fileName: (format) => `superviz-sdk-react.${format}.js`,
+ },
+ rollupOptions: {
+ external: [...Object.keys(peerDependencies)],
+ input: Object.fromEntries(
+ glob
+ .sync('src/**/*.{ts,tsx}')
+ .map((file) => [
+ path.relative('src', file.slice(0, file.length - path.extname(file).length)),
+ url.fileURLToPath(new URL(file, import.meta.url)),
+ ]),
+ ),
+ },
+ },
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0669d3a0..2c0c49d0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -35,6 +35,9 @@ importers:
'@superviz/threejs-plugin':
specifier: workspace:*
version: link:../../packages/three
+ '@superviz/yjs':
+ specifier: workspace:*
+ version: link:../../packages/yjs
'@types/three':
specifier: ^0.167.1
version: 0.167.2
@@ -252,6 +255,127 @@ importers:
specifier: ^5.5.2
version: 5.6.2
+ packages/react:
+ dependencies:
+ '@superviz/autodesk-viewer-plugin':
+ specifier: workspace:*
+ version: link:../autodesk
+ '@superviz/matterport-plugin':
+ specifier: workspace:*
+ version: link:../matterport
+ '@superviz/sdk':
+ specifier: workspace:*
+ version: link:../sdk
+ '@superviz/socket-client':
+ specifier: workspace:*
+ version: link:../socket-client
+ '@superviz/threejs-plugin':
+ specifier: workspace:*
+ version: link:../three
+ lodash:
+ specifier: ^4.17.21
+ version: 4.17.21
+ react:
+ specifier: ^18.2.0
+ version: 18.3.1
+ react-dom:
+ specifier: ^18.2.0
+ version: 18.3.1(react@18.3.1)
+ devDependencies:
+ '@eslint/compat':
+ specifier: ^1.1.1
+ version: 1.1.1
+ '@rollup/plugin-replace':
+ specifier: ^5.0.7
+ version: 5.0.7(rollup@4.21.3)
+ '@types/forge-viewer':
+ specifier: ^7.89.1
+ version: 7.89.1
+ '@types/lodash':
+ specifier: ^4.17.6
+ version: 4.17.7
+ '@types/node':
+ specifier: ^20.14.9
+ version: 20.16.5
+ '@types/react':
+ specifier: ^18.3.3
+ version: 18.3.5
+ '@types/react-dom':
+ specifier: ^18.3.0
+ version: 18.3.0
+ '@types/three':
+ specifier: ^0.166.0
+ version: 0.166.0
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^7.14.1
+ version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2))(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+ '@typescript-eslint/parser':
+ specifier: ^7.14.1
+ version: 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+ '@vitejs/plugin-react':
+ specifier: ^4.3.1
+ version: 4.3.1(vite@5.4.5(@types/node@20.16.5)(terser@5.32.0))
+ '@vitejs/plugin-react-swc':
+ specifier: ^3.7.0
+ version: 3.7.0(vite@5.4.5(@types/node@20.16.5)(terser@5.32.0))
+ eslint:
+ specifier: ^9.6.0
+ version: 9.10.0(jiti@1.21.6)
+ eslint-config-prettier:
+ specifier: ^9.1.0
+ version: 9.1.0(eslint@9.10.0(jiti@1.21.6))
+ eslint-plugin-prettier:
+ specifier: ^5.1.3
+ version: 5.2.1(@types/eslint@8.56.2)(eslint-config-prettier@9.1.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3)
+ eslint-plugin-react:
+ specifier: ^7.34.3
+ version: 7.36.1(eslint@9.10.0(jiti@1.21.6))
+ eslint-plugin-react-hooks:
+ specifier: ^4.6.2
+ version: 4.6.2(eslint@9.10.0(jiti@1.21.6))
+ eslint-plugin-react-refresh:
+ specifier: ^0.4.7
+ version: 0.4.11(eslint@9.10.0(jiti@1.21.6))
+ eslint-plugin-simple-import-sort:
+ specifier: ^12.1.0
+ version: 12.1.1(eslint@9.10.0(jiti@1.21.6))
+ glob:
+ specifier: ^10.4.2
+ version: 10.4.5
+ husky:
+ specifier: ^9.0.11
+ version: 9.1.6
+ lint-staged:
+ specifier: ^15.2.7
+ version: 15.2.10
+ prettier:
+ specifier: ^3.3.2
+ version: 3.3.3
+ react-hooks:
+ specifier: ^1.0.1
+ version: 1.0.1
+ semantic-release:
+ specifier: ^24.0.0
+ version: 24.0.0(typescript@5.6.2)
+ semantic-release-version-file:
+ specifier: ^1.0.2
+ version: 1.0.2
+ typescript:
+ specifier: ^5.5.2
+ version: 5.6.2
+ vite:
+ specifier: ^5.3.2
+ version: 5.4.5(@types/node@20.16.5)(terser@5.32.0)
+ vite-plugin-dts:
+ specifier: ^3.9.1
+ version: 3.9.1(@types/node@20.16.5)(rollup@4.21.3)(typescript@5.6.2)(vite@5.4.5(@types/node@20.16.5)(terser@5.32.0))
+ vite-plugin-linter:
+ specifier: ^2.1.1
+ version: 2.1.1(rollup@4.21.3)
+ vite-tsconfig-paths:
+ specifier: ^4.3.2
+ version: 4.3.2(typescript@5.6.2)(vite@5.4.5(@types/node@20.16.5)(terser@5.32.0))
+
packages/realtime:
dependencies:
'@superviz/socket-client':
@@ -1843,6 +1967,10 @@ packages:
resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+ '@eslint/compat@1.1.1':
+ resolution: {integrity: sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
'@eslint/config-array@0.18.0':
resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -2009,6 +2137,19 @@ packages:
'@mdn/browser-compat-data@4.2.1':
resolution: {integrity: sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==}
+ '@microsoft/api-extractor-model@7.28.13':
+ resolution: {integrity: sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==}
+
+ '@microsoft/api-extractor@7.43.0':
+ resolution: {integrity: sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==}
+ hasBin: true
+
+ '@microsoft/tsdoc-config@0.16.2':
+ resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==}
+
+ '@microsoft/tsdoc@0.14.2':
+ resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==}
+
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -2086,6 +2227,10 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
+ '@pkgr/core@0.1.1':
+ resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
+ engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+
'@pnpm/config.env-replace@1.1.0':
resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==}
engines: {node: '>=12.22.0'}
@@ -2125,6 +2270,15 @@ packages:
rollup:
optional: true
+ '@rollup/plugin-replace@5.0.7':
+ resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
'@rollup/pluginutils@5.1.0':
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
engines: {node: '>=14.0.0'}
@@ -2217,6 +2371,28 @@ packages:
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
+ '@rushstack/node-core-library@4.0.2':
+ resolution: {integrity: sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==}
+ peerDependencies:
+ '@types/node': '*'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@rushstack/rig-package@0.5.2':
+ resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==}
+
+ '@rushstack/terminal@0.10.0':
+ resolution: {integrity: sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==}
+ peerDependencies:
+ '@types/node': '*'
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+
+ '@rushstack/ts-command-line@4.19.1':
+ resolution: {integrity: sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==}
+
'@sec-ant/readable-stream@0.4.1':
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
@@ -2275,6 +2451,81 @@ packages:
'@superviz/sdk@6.4.3':
resolution: {integrity: sha512-9G5viuRPdUTEHI5dMboM9hPs8owdqRNQ++ifneLr3zde8Ot4Y4wtyuMIeGGOxLrp77lF1usprnBgWEbYe4FcFQ==}
+ '@swc/core-darwin-arm64@1.7.26':
+ resolution: {integrity: sha512-FF3CRYTg6a7ZVW4yT9mesxoVVZTrcSWtmZhxKCYJX9brH4CS/7PRPjAKNk6kzWgWuRoglP7hkjQcd6EpMcZEAw==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@swc/core-darwin-x64@1.7.26':
+ resolution: {integrity: sha512-az3cibZdsay2HNKmc4bjf62QVukuiMRh5sfM5kHR/JMTrLyS6vSw7Ihs3UTkZjUxkLTT8ro54LI6sV6sUQUbLQ==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@swc/core-linux-arm-gnueabihf@1.7.26':
+ resolution: {integrity: sha512-VYPFVJDO5zT5U3RpCdHE5v1gz4mmR8BfHecUZTmD2v1JeFY6fv9KArJUpjrHEEsjK/ucXkQFmJ0jaiWXmpOV9Q==}
+ engines: {node: '>=10'}
+ cpu: [arm]
+ os: [linux]
+
+ '@swc/core-linux-arm64-gnu@1.7.26':
+ resolution: {integrity: sha512-YKevOV7abpjcAzXrhsl+W48Z9mZvgoVs2eP5nY+uoMAdP2b3GxC0Df1Co0I90o2lkzO4jYBpTMcZlmUXLdXn+Q==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@swc/core-linux-arm64-musl@1.7.26':
+ resolution: {integrity: sha512-3w8iZICMkQQON0uIcvz7+Q1MPOW6hJ4O5ETjA0LSP/tuKqx30hIniCGOgPDnv3UTMruLUnQbtBwVCZTBKR3Rkg==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@swc/core-linux-x64-gnu@1.7.26':
+ resolution: {integrity: sha512-c+pp9Zkk2lqb06bNGkR2Looxrs7FtGDMA4/aHjZcCqATgp348hOKH5WPvNLBl+yPrISuWjbKDVn3NgAvfvpH4w==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@swc/core-linux-x64-musl@1.7.26':
+ resolution: {integrity: sha512-PgtyfHBF6xG87dUSSdTJHwZ3/8vWZfNIXQV2GlwEpslrOkGqy+WaiiyE7Of7z9AvDILfBBBcJvJ/r8u980wAfQ==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@swc/core-win32-arm64-msvc@1.7.26':
+ resolution: {integrity: sha512-9TNXPIJqFynlAOrRD6tUQjMq7KApSklK3R/tXgIxc7Qx+lWu8hlDQ/kVPLpU7PWvMMwC/3hKBW+p5f+Tms1hmA==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@swc/core-win32-ia32-msvc@1.7.26':
+ resolution: {integrity: sha512-9YngxNcG3177GYdsTum4V98Re+TlCeJEP4kEwEg9EagT5s3YejYdKwVAkAsJszzkXuyRDdnHUpYbTrPG6FiXrQ==}
+ engines: {node: '>=10'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@swc/core-win32-x64-msvc@1.7.26':
+ resolution: {integrity: sha512-VR+hzg9XqucgLjXxA13MtV5O3C0bK0ywtLIBw/+a+O+Oc6mxFWHtdUeXDbIi5AiPbn0fjgVJMqYnyjGyyX8u0w==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@swc/core@1.7.26':
+ resolution: {integrity: sha512-f5uYFf+TmMQyYIoxkn/evWhNGuUzC730dFwAKGwBVHHVoPyak1/GvJUm6i1SKl+2Hrj9oN0i3WSoWWZ4pgI8lw==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@swc/helpers': '*'
+ peerDependenciesMeta:
+ '@swc/helpers':
+ optional: true
+
+ '@swc/counter@0.1.3':
+ resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
+
+ '@swc/types@0.1.12':
+ resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==}
+
'@tootallnate/once@2.0.0':
resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==}
engines: {node: '>= 10'}
@@ -2288,6 +2539,9 @@ packages:
'@types/accepts@1.3.7':
resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==}
+ '@types/argparse@1.0.38':
+ resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
+
'@types/babel__code-frame@7.0.6':
resolution: {integrity: sha512-Anitqkl3+KrzcW2k77lRlg/GfLZLWXBuNgbEcIOU6M92yw42vsd3xV/Z/yAHEj8m+KUjL6bWOVOFqX8PFPJ4LA==}
@@ -2336,6 +2590,9 @@ packages:
'@types/debug@4.1.12':
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
+ '@types/eslint@8.56.2':
+ resolution: {integrity: sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==}
+
'@types/estree@1.0.5':
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
@@ -2447,6 +2704,9 @@ packages:
'@types/three@0.165.0':
resolution: {integrity: sha512-AJK8JZAFNBF0kBXiAIl5pggYlzAGGA8geVYQXAcPCEDRbyA+oEjkpUBcJJrtNz6IiALwzGexFJGZG2yV3WsYBw==}
+ '@types/three@0.166.0':
+ resolution: {integrity: sha512-FHMnpcdhdbdOOIYbfkTkUVpYMW53odxbTRwd0/xJpYnTzEsjnVnondGAvHZb4z06UW0vo6WPVuvH0/9qrxKx7g==}
+
'@types/three@0.167.2':
resolution: {integrity: sha512-onxnIUNYpXcZJ5DTiIsxfnr4F9kAWkkxAUWx5yqzz/u0a4IygCLCjMuOl2DEeCxyJdJ2nOJZvKpu48sBMqfmkQ==}
@@ -2593,12 +2853,43 @@ packages:
'@ungap/structured-clone@1.2.0':
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
+ '@vitejs/plugin-react-swc@3.7.0':
+ resolution: {integrity: sha512-yrknSb3Dci6svCd/qhHqhFPDSw0QtjumcqdKMoNNzmOl5lMXTTiqzjWtG4Qask2HdvvzaNgSunbQGet8/GrKdA==}
+ peerDependencies:
+ vite: ^4 || ^5
+
'@vitejs/plugin-react@4.3.1':
resolution: {integrity: sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
vite: ^4.2.0 || ^5.0.0
+ '@volar/language-core@1.11.1':
+ resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==}
+
+ '@volar/source-map@1.11.1':
+ resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==}
+
+ '@volar/typescript@1.11.1':
+ resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==}
+
+ '@vue/compiler-core@3.5.8':
+ resolution: {integrity: sha512-Uzlxp91EPjfbpeO5KtC0KnXPkuTfGsNDeaKQJxQN718uz+RqDYarEf7UhQJGK+ZYloD2taUbHTI2J4WrUaZQNA==}
+
+ '@vue/compiler-dom@3.5.8':
+ resolution: {integrity: sha512-GUNHWvoDSbSa5ZSHT9SnV5WkStWfzJwwTd6NMGzilOE/HM5j+9EB9zGXdtu/fCNEmctBqMs6C9SvVPpVPuk1Eg==}
+
+ '@vue/language-core@1.8.27':
+ resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@vue/shared@3.5.8':
+ resolution: {integrity: sha512-mJleSWbAGySd2RJdX1RBtcrUBX6snyOc0qHpgk3lGi4l9/P/3ny3ELqFWqYdkXIwwNN/kdm8nD9ky8o6l/Lx2A==}
+
'@web/browser-logs@0.3.4':
resolution: {integrity: sha512-0UkoUj1DdQjxaVBArHZRAGoiE5584/dSQ0V3hYWRqVDxaE3CwkfQ7kwb6i3Z1xJ8HZ9nuLMNycu3vLQwfhDnpg==}
engines: {node: '>=16.0.0'}
@@ -2809,6 +3100,10 @@ packages:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
+ array.prototype.findlast@1.2.5:
+ resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
+ engines: {node: '>= 0.4'}
+
array.prototype.findlastindex@1.2.5:
resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==}
engines: {node: '>= 0.4'}
@@ -2821,6 +3116,10 @@ packages:
resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==}
engines: {node: '>= 0.4'}
+ array.prototype.tosorted@1.1.4:
+ resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
+ engines: {node: '>= 0.4'}
+
arraybuffer.prototype.slice@1.0.2:
resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==}
engines: {node: '>= 0.4'}
@@ -2953,6 +3252,10 @@ packages:
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
engines: {node: '>=8'}
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
browser-or-node@3.0.0:
resolution: {integrity: sha512-iczIdVJzGEYhP5DqQxYM9Hh7Ztpqqi+CXZpSmX8ALFs9ecXkQIeqRyM6TfxEfMVpwhl3dSuDvxdzzo9sUOIVBQ==}
@@ -3051,6 +3354,10 @@ packages:
chardet@0.7.0:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
+ chokidar@3.5.3:
+ resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+ engines: {node: '>= 8.10.0'}
+
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
@@ -3080,6 +3387,10 @@ packages:
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
engines: {node: '>=8'}
+ cli-cursor@5.0.0:
+ resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==}
+ engines: {node: '>=18'}
+
cli-highlight@2.1.11:
resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==}
engines: {node: '>=8.0.0', npm: '>=5.0.0'}
@@ -3093,6 +3404,10 @@ packages:
resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==}
engines: {node: 10.* || >= 12.*}
+ cli-truncate@4.0.0:
+ resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
+ engines: {node: '>=18'}
+
cli-width@3.0.0:
resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==}
engines: {node: '>= 10'}
@@ -3136,6 +3451,9 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ colorette@2.0.20:
+ resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
+
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@@ -3148,6 +3466,10 @@ packages:
resolution: {integrity: sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==}
engines: {node: '>=12.20.0'}
+ commander@12.1.0:
+ resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
+ engines: {node: '>=18'}
+
commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
@@ -3155,6 +3477,10 @@ packages:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
+ commander@9.5.0:
+ resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
+ engines: {node: ^12.20.0 || >=14}
+
commitizen@4.3.0:
resolution: {integrity: sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==}
engines: {node: '>= 12'}
@@ -3163,6 +3489,9 @@ packages:
compare-func@2.0.0:
resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
+ computeds@0.0.1:
+ resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==}
+
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@@ -3319,6 +3648,9 @@ packages:
resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
engines: {node: '>=0.11'}
+ de-indent@1.0.2:
+ resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+
debounce@1.2.1:
resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==}
@@ -3512,6 +3844,9 @@ packages:
resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
engines: {node: '>=12'}
+ emoji-regex@10.4.0:
+ resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==}
+
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -3577,6 +3912,10 @@ packages:
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
engines: {node: '>= 0.4'}
+ es-iterator-helpers@1.0.19:
+ resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==}
+ engines: {node: '>= 0.4'}
+
es-module-lexer@1.5.4:
resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
@@ -3719,6 +4058,20 @@ packages:
resolution: {integrity: sha512-2tktqUAT+Q3hCAU0iSf4xAN1k9zOpjK5WO8104mB0rT/dGhOa09582HN5HlbxNbPRZ0THV7nLGvzugcNOSjzfA==}
engines: {node: '>=6'}
+ eslint-plugin-prettier@5.2.1:
+ resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ '@types/eslint': '>=8.0.0'
+ eslint: '>=8.0.0'
+ eslint-config-prettier: '*'
+ prettier: '>=3.0.0'
+ peerDependenciesMeta:
+ '@types/eslint':
+ optional: true
+ eslint-config-prettier:
+ optional: true
+
eslint-plugin-react-hooks@4.6.2:
resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==}
engines: {node: '>=10'}
@@ -3730,6 +4083,17 @@ packages:
peerDependencies:
eslint: '>=7'
+ eslint-plugin-react@7.36.1:
+ resolution: {integrity: sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
+
+ eslint-plugin-simple-import-sort@12.1.1:
+ resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==}
+ peerDependencies:
+ eslint: '>=5.0.0'
+
eslint-plugin-turbo@2.0.0:
resolution: {integrity: sha512-31tZqfGbjBn6BzXVsmW50c2m8NDra6mOS2us/qHxUwN4YrHI/uYSpyItAw4qdVrxk7RmilvmnJ5WXFwtnfuLqw==}
peerDependencies:
@@ -3807,6 +4171,9 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
+ eventemitter3@5.0.1:
+ resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+
execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
@@ -3843,6 +4210,9 @@ packages:
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+ fast-diff@1.3.0:
+ resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
+
fast-fifo@1.3.2:
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
@@ -3902,6 +4272,10 @@ packages:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
find-node-modules@2.1.3:
resolution: {integrity: sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==}
@@ -3972,6 +4346,10 @@ packages:
resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
engines: {node: '>=14.14'}
+ fs-extra@7.0.1:
+ resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
+ engines: {node: '>=6 <7 || >=8'}
+
fs-extra@9.1.0:
resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
engines: {node: '>=10'}
@@ -4011,6 +4389,10 @@ packages:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
+ get-east-asian-width@1.2.0:
+ resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
+ engines: {node: '>=18'}
+
get-intrinsic@1.2.2:
resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==}
@@ -4117,6 +4499,9 @@ packages:
resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==}
engines: {node: '>=18'}
+ globrex@0.1.2:
+ resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
+
gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
@@ -4179,6 +4564,10 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
+ he@1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+
highlight.js@10.7.3:
resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
@@ -4281,6 +4670,10 @@ packages:
resolution: {integrity: sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==}
engines: {node: '>=16.20'}
+ import-lazy@4.0.0:
+ resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
+ engines: {node: '>=8'}
+
import-local@3.2.0:
resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==}
engines: {node: '>=8'}
@@ -4361,6 +4754,10 @@ packages:
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+ is-async-function@2.0.0:
+ resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==}
+ engines: {node: '>= 0.4'}
+
is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
@@ -4404,10 +4801,21 @@ packages:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
+ is-finalizationregistry@1.0.2:
+ resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==}
+
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
+ is-fullwidth-code-point@4.0.0:
+ resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
+ engines: {node: '>=12'}
+
+ is-fullwidth-code-point@5.0.0:
+ resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==}
+ engines: {node: '>=18'}
+
is-generator-fn@2.1.0:
resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
engines: {node: '>=6'}
@@ -4424,6 +4832,10 @@ packages:
resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
engines: {node: '>=8'}
+ is-map@2.0.3:
+ resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
+ engines: {node: '>= 0.4'}
+
is-module@1.0.0:
resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
@@ -4462,6 +4874,10 @@ packages:
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
engines: {node: '>= 0.4'}
+ is-set@2.0.3:
+ resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
+ engines: {node: '>= 0.4'}
+
is-shared-array-buffer@1.0.2:
resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
@@ -4508,9 +4924,17 @@ packages:
is-utf8@0.2.1:
resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
+ is-weakmap@2.0.2:
+ resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
+ engines: {node: '>= 0.4'}
+
is-weakref@1.0.2:
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+ is-weakset@2.0.3:
+ resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==}
+ engines: {node: '>= 0.4'}
+
is-windows@1.0.2:
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
engines: {node: '>=0.10.0'}
@@ -4563,6 +4987,9 @@ packages:
resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
engines: {node: '>=8'}
+ iterator.prototype@1.1.2:
+ resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==}
+
jackspeak@3.4.3:
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
@@ -4733,6 +5160,9 @@ packages:
resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
hasBin: true
+ jju@1.4.0:
+ resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
+
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -4792,9 +5222,16 @@ packages:
engines: {node: '>=6'}
hasBin: true
+ jsonfile@4.0.0:
+ resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
+
jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+ jsx-ast-utils@3.3.5:
+ resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
+ engines: {node: '>=4.0'}
+
keygrip@1.1.0:
resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==}
engines: {node: '>= 0.6'}
@@ -4828,6 +5265,9 @@ packages:
resolution: {integrity: sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==}
engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4}
+ kolorist@1.8.0:
+ resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
+
leven@3.1.0:
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
engines: {node: '>=6'}
@@ -4855,6 +5295,15 @@ packages:
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+ lint-staged@15.2.10:
+ resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==}
+ engines: {node: '>=18.12.0'}
+ hasBin: true
+
+ listr2@8.2.4:
+ resolution: {integrity: sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==}
+ engines: {node: '>=18.0.0'}
+
lit-element@4.1.0:
resolution: {integrity: sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww==}
@@ -4895,6 +5344,9 @@ packages:
lodash.escaperegexp@4.1.2:
resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==}
+ lodash.get@4.4.2:
+ resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
+
lodash.isequal@4.5.0:
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
@@ -4933,6 +5385,10 @@ packages:
resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==}
engines: {node: '>=10'}
+ log-update@6.1.0:
+ resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
+ engines: {node: '>=18'}
+
longest@2.0.1:
resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==}
engines: {node: '>=0.10.0'}
@@ -4967,6 +5423,9 @@ packages:
resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==}
engines: {node: '>=12'}
+ magic-string@0.30.11:
+ resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==}
+
make-dir@4.0.0:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
@@ -5016,6 +5475,10 @@ packages:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
@@ -5037,10 +5500,17 @@ packages:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
+ mimic-function@5.0.1:
+ resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
+ engines: {node: '>=18'}
+
minimatch@10.0.1:
resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
engines: {node: 20 || >=22}
+ minimatch@3.0.8:
+ resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==}
+
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -5093,6 +5563,9 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ muggle-string@0.3.1:
+ resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
+
mute-stream@0.0.8:
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
@@ -5271,6 +5744,10 @@ packages:
resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==}
engines: {node: '>= 0.4'}
+ object.entries@1.1.8:
+ resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==}
+ engines: {node: '>= 0.4'}
+
object.fromentries@2.0.8:
resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
engines: {node: '>= 0.4'}
@@ -5298,6 +5775,10 @@ packages:
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
engines: {node: '>=12'}
+ onetime@7.0.0:
+ resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
+ engines: {node: '>=18'}
+
only@0.0.2:
resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==}
@@ -5420,6 +5901,9 @@ packages:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
path-exists@3.0.0:
resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==}
engines: {node: '>=4'}
@@ -5469,6 +5953,11 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
+ pidtree@0.6.0:
+ resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==}
+ engines: {node: '>=0.10'}
+ hasBin: true
+
pify@2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
@@ -5552,11 +6041,20 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
+ prettier-linter-helpers@1.0.0:
+ resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
+ engines: {node: '>=6.0.0'}
+
prettier@3.2.5:
resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==}
engines: {node: '>=14'}
hasBin: true
+ prettier@3.3.3:
+ resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
+ engines: {node: '>=14'}
+ hasBin: true
+
pretty-format@29.7.0:
resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -5579,6 +6077,9 @@ packages:
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
engines: {node: '>= 6'}
+ prop-types@15.8.1:
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+
proto-list@1.2.4:
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
@@ -5645,7 +6146,13 @@ packages:
peerDependencies:
react: ^16.6.0 || ^17.0.0 || ^18.0.0
- react-is@18.3.1:
+ react-hooks@1.0.1:
+ resolution: {integrity: sha512-PXU08tw4SvKwkW99qgnyV98x939RCmBC6aXqALPQXPjKq6+6EoH79Rz4KdUozzlpSyWmn2IiEm0vh3p+79aP5w==}
+
+ react-is@16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+
+ react-is@18.3.1:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
react-refresh@0.14.2:
@@ -5691,6 +6198,10 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
+ reflect.getprototypeof@1.0.6:
+ resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
+ engines: {node: '>= 0.4'}
+
regenerate-unicode-properties@10.2.0:
resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==}
engines: {node: '>=4'}
@@ -5765,18 +6276,32 @@ packages:
resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==}
engines: {node: '>=10'}
+ resolve@1.19.0:
+ resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
+
resolve@1.22.8:
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true
+ resolve@2.0.0-next.5:
+ resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==}
+ hasBin: true
+
restore-cursor@3.1.0:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
engines: {node: '>=8'}
+ restore-cursor@5.1.0:
+ resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==}
+ engines: {node: '>=18'}
+
reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
deprecated: Rimraf versions prior to v4 are no longer supported
@@ -5884,6 +6409,10 @@ packages:
resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==}
engines: {node: '>= 0.4'}
+ set-function-name@2.0.2:
+ resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+ engines: {node: '>= 0.4'}
+
setprototypeof@1.1.0:
resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==}
@@ -5944,6 +6473,14 @@ packages:
resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
engines: {node: '>=10'}
+ slice-ansi@5.0.0:
+ resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
+ engines: {node: '>=12'}
+
+ slice-ansi@7.1.0:
+ resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
+ engines: {node: '>=18'}
+
smart-buffer@4.2.0:
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
@@ -6027,6 +6564,10 @@ packages:
streamx@2.20.1:
resolution: {integrity: sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==}
+ string-argv@0.3.2:
+ resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
+ engines: {node: '>=0.6.19'}
+
string-length@4.0.2:
resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
engines: {node: '>=10'}
@@ -6039,6 +6580,17 @@ packages:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
+ string-width@7.2.0:
+ resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
+ engines: {node: '>=18'}
+
+ string.prototype.matchall@4.0.11:
+ resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.repeat@1.0.0:
+ resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==}
+
string.prototype.trim@1.2.8:
resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==}
engines: {node: '>= 0.4'}
@@ -6134,6 +6686,10 @@ packages:
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
+ synckit@0.9.1:
+ resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+
systemjs@6.15.1:
resolution: {integrity: sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==}
@@ -6299,6 +6855,16 @@ packages:
resolution: {integrity: sha512-fzoSieZI5KKJVBYGvwbVZs/J5za84f2lSTLPYf6AGiIf43tZ3GNrI1QzTLcjtyDDP4aLxd46RTZq1nQxe7+k5Q==}
hasBin: true
+ tsconfck@3.1.3:
+ resolution: {integrity: sha512-ulNZP1SVpRDesxeMLON/LtWM8HIgAJEIVpVVhBM6gsmvQ8+Rh+ZG7FWGvHh7Ah3pRABwVJWklWCr/BTZSv0xnQ==}
+ engines: {node: ^18 || >=20}
+ hasBin: true
+ peerDependencies:
+ typescript: ^5.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
tsconfig-paths@3.15.0:
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
@@ -6414,6 +6980,11 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
+ typescript@5.4.2:
+ resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
typescript@5.4.5:
resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==}
engines: {node: '>=14.17'}
@@ -6481,6 +7052,10 @@ packages:
universal-user-agent@7.0.2:
resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==}
+ universalify@0.1.2:
+ resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
+ engines: {node: '>= 4.0.0'}
+
universalify@0.2.0:
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
engines: {node: '>= 4.0.0'}
@@ -6529,10 +7104,36 @@ packages:
validate-npm-package-license@3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+ validator@13.12.0:
+ resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==}
+ engines: {node: '>= 0.10'}
+
vary@1.1.2:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
+ vite-plugin-dts@3.9.1:
+ resolution: {integrity: sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ typescript: '*'
+ vite: '*'
+ peerDependenciesMeta:
+ vite:
+ optional: true
+
+ vite-plugin-linter@2.1.1:
+ resolution: {integrity: sha512-qGQq92xXhWL2VbL6SBGxgvX7d1PTJwEjEqiLRcUBJMuwl/M2FOmXOWEMeIrys3u8Csv0ISIH0dEVTERaLPcHdQ==}
+ hasBin: true
+
+ vite-tsconfig-paths@4.3.2:
+ resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==}
+ peerDependencies:
+ vite: '*'
+ peerDependenciesMeta:
+ vite:
+ optional: true
+
vite@5.4.5:
resolution: {integrity: sha512-pXqR0qtb2bTwLkev4SE3r4abCNioP3GkjvIDLlzziPpXtHgiJIjuKl+1GN6ESOT3wMjG3JTeARopj2SwYaHTOA==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -6564,6 +7165,15 @@ packages:
terser:
optional: true
+ vue-template-compiler@2.7.16:
+ resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==}
+
+ vue-tsc@1.8.27:
+ resolution: {integrity: sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==}
+ hasBin: true
+ peerDependencies:
+ typescript: '*'
+
w3c-xmlserializer@4.0.0:
resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==}
engines: {node: '>=14'}
@@ -6602,6 +7212,14 @@ packages:
which-boxed-primitive@1.0.2:
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ which-builtin-type@1.1.4:
+ resolution: {integrity: sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==}
+ engines: {node: '>= 0.4'}
+
+ which-collection@1.0.2:
+ resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
+ engines: {node: '>= 0.4'}
+
which-typed-array@1.1.13:
resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==}
engines: {node: '>= 0.4'}
@@ -6642,6 +7260,10 @@ packages:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
+ wrap-ansi@9.0.0:
+ resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
+ engines: {node: '>=18'}
+
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
@@ -6754,6 +7376,11 @@ packages:
resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==}
engines: {node: '>=18'}
+ z-schema@5.0.5:
+ resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==}
+ engines: {node: '>=8.0.0'}
+ hasBin: true
+
zod@3.23.8:
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
@@ -7905,6 +8532,8 @@ snapshots:
'@eslint-community/regexpp@4.11.0': {}
+ '@eslint/compat@1.1.1': {}
+
'@eslint/config-array@0.18.0':
dependencies:
'@eslint/object-schema': 2.1.4
@@ -8186,6 +8815,41 @@ snapshots:
'@mdn/browser-compat-data@4.2.1': {}
+ '@microsoft/api-extractor-model@7.28.13(@types/node@20.16.5)':
+ dependencies:
+ '@microsoft/tsdoc': 0.14.2
+ '@microsoft/tsdoc-config': 0.16.2
+ '@rushstack/node-core-library': 4.0.2(@types/node@20.16.5)
+ transitivePeerDependencies:
+ - '@types/node'
+
+ '@microsoft/api-extractor@7.43.0(@types/node@20.16.5)':
+ dependencies:
+ '@microsoft/api-extractor-model': 7.28.13(@types/node@20.16.5)
+ '@microsoft/tsdoc': 0.14.2
+ '@microsoft/tsdoc-config': 0.16.2
+ '@rushstack/node-core-library': 4.0.2(@types/node@20.16.5)
+ '@rushstack/rig-package': 0.5.2
+ '@rushstack/terminal': 0.10.0(@types/node@20.16.5)
+ '@rushstack/ts-command-line': 4.19.1(@types/node@20.16.5)
+ lodash: 4.17.21
+ minimatch: 3.0.8
+ resolve: 1.22.8
+ semver: 7.5.4
+ source-map: 0.6.1
+ typescript: 5.4.2
+ transitivePeerDependencies:
+ - '@types/node'
+
+ '@microsoft/tsdoc-config@0.16.2':
+ dependencies:
+ '@microsoft/tsdoc': 0.14.2
+ ajv: 6.12.6
+ jju: 1.4.0
+ resolve: 1.19.0
+
+ '@microsoft/tsdoc@0.14.2': {}
+
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -8274,6 +8938,8 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
+ '@pkgr/core@0.1.1': {}
+
'@pnpm/config.env-replace@1.1.0': {}
'@pnpm/network.ca-file@1.0.2':
@@ -8317,6 +8983,13 @@ snapshots:
optionalDependencies:
rollup: 3.29.4
+ '@rollup/plugin-replace@5.0.7(rollup@4.21.3)':
+ dependencies:
+ '@rollup/pluginutils': 5.1.0(rollup@4.21.3)
+ magic-string: 0.30.11
+ optionalDependencies:
+ rollup: 4.21.3
+
'@rollup/pluginutils@5.1.0(rollup@3.29.4)':
dependencies:
'@types/estree': 1.0.5
@@ -8325,6 +8998,14 @@ snapshots:
optionalDependencies:
rollup: 3.29.4
+ '@rollup/pluginutils@5.1.0(rollup@4.21.3)':
+ dependencies:
+ '@types/estree': 1.0.5
+ estree-walker: 2.0.2
+ picomatch: 2.3.1
+ optionalDependencies:
+ rollup: 4.21.3
+
'@rollup/rollup-android-arm-eabi@4.21.3':
optional: true
@@ -8375,6 +9056,38 @@ snapshots:
'@rtsao/scc@1.1.0': {}
+ '@rushstack/node-core-library@4.0.2(@types/node@20.16.5)':
+ dependencies:
+ fs-extra: 7.0.1
+ import-lazy: 4.0.0
+ jju: 1.4.0
+ resolve: 1.22.8
+ semver: 7.5.4
+ z-schema: 5.0.5
+ optionalDependencies:
+ '@types/node': 20.16.5
+
+ '@rushstack/rig-package@0.5.2':
+ dependencies:
+ resolve: 1.22.8
+ strip-json-comments: 3.1.1
+
+ '@rushstack/terminal@0.10.0(@types/node@20.16.5)':
+ dependencies:
+ '@rushstack/node-core-library': 4.0.2(@types/node@20.16.5)
+ supports-color: 8.1.1
+ optionalDependencies:
+ '@types/node': 20.16.5
+
+ '@rushstack/ts-command-line@4.19.1(@types/node@20.16.5)':
+ dependencies:
+ '@rushstack/terminal': 0.10.0(@types/node@20.16.5)
+ '@types/argparse': 1.0.38
+ argparse: 1.0.10
+ string-argv: 0.3.2
+ transitivePeerDependencies:
+ - '@types/node'
+
'@sec-ant/readable-stream@0.4.1': {}
'@semantic-release/commit-analyzer@13.0.0(semantic-release@24.0.0(typescript@5.6.2))':
@@ -8554,6 +9267,58 @@ snapshots:
- supports-color
- utf-8-validate
+ '@swc/core-darwin-arm64@1.7.26':
+ optional: true
+
+ '@swc/core-darwin-x64@1.7.26':
+ optional: true
+
+ '@swc/core-linux-arm-gnueabihf@1.7.26':
+ optional: true
+
+ '@swc/core-linux-arm64-gnu@1.7.26':
+ optional: true
+
+ '@swc/core-linux-arm64-musl@1.7.26':
+ optional: true
+
+ '@swc/core-linux-x64-gnu@1.7.26':
+ optional: true
+
+ '@swc/core-linux-x64-musl@1.7.26':
+ optional: true
+
+ '@swc/core-win32-arm64-msvc@1.7.26':
+ optional: true
+
+ '@swc/core-win32-ia32-msvc@1.7.26':
+ optional: true
+
+ '@swc/core-win32-x64-msvc@1.7.26':
+ optional: true
+
+ '@swc/core@1.7.26':
+ dependencies:
+ '@swc/counter': 0.1.3
+ '@swc/types': 0.1.12
+ optionalDependencies:
+ '@swc/core-darwin-arm64': 1.7.26
+ '@swc/core-darwin-x64': 1.7.26
+ '@swc/core-linux-arm-gnueabihf': 1.7.26
+ '@swc/core-linux-arm64-gnu': 1.7.26
+ '@swc/core-linux-arm64-musl': 1.7.26
+ '@swc/core-linux-x64-gnu': 1.7.26
+ '@swc/core-linux-x64-musl': 1.7.26
+ '@swc/core-win32-arm64-msvc': 1.7.26
+ '@swc/core-win32-ia32-msvc': 1.7.26
+ '@swc/core-win32-x64-msvc': 1.7.26
+
+ '@swc/counter@0.1.3': {}
+
+ '@swc/types@0.1.12':
+ dependencies:
+ '@swc/counter': 0.1.3
+
'@tootallnate/once@2.0.0': {}
'@tootallnate/quickjs-emscripten@0.23.0': {}
@@ -8564,6 +9329,8 @@ snapshots:
dependencies:
'@types/node': 20.16.5
+ '@types/argparse@1.0.38': {}
+
'@types/babel__code-frame@7.0.6': {}
'@types/babel__core@7.20.5':
@@ -8627,6 +9394,11 @@ snapshots:
dependencies:
'@types/ms': 0.7.34
+ '@types/eslint@8.56.2':
+ dependencies:
+ '@types/estree': 1.0.5
+ '@types/json-schema': 7.0.12
+
'@types/estree@1.0.5': {}
'@types/express-serve-static-core@4.19.5':
@@ -8755,6 +9527,14 @@ snapshots:
fflate: 0.8.2
meshoptimizer: 0.18.1
+ '@types/three@0.166.0':
+ dependencies:
+ '@tweenjs/tween.js': 23.1.3
+ '@types/stats.js': 0.17.3
+ '@types/webxr': 0.5.20
+ fflate: 0.8.2
+ meshoptimizer: 0.18.1
+
'@types/three@0.167.2':
dependencies:
'@tweenjs/tween.js': 23.1.3
@@ -8824,6 +9604,24 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2))(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)':
+ dependencies:
+ '@eslint-community/regexpp': 4.11.0
+ '@typescript-eslint/parser': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/type-utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+ '@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+ '@typescript-eslint/visitor-keys': 7.18.0
+ eslint: 9.10.0(jiti@1.21.6)
+ graphemer: 1.4.0
+ ignore: 5.3.1
+ natural-compare: 1.4.0
+ ts-api-utils: 1.3.0(typescript@5.6.2)
+ optionalDependencies:
+ typescript: 5.6.2
+ transitivePeerDependencies:
+ - supports-color
+
'@typescript-eslint/parser@7.1.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.3.3)':
dependencies:
'@typescript-eslint/scope-manager': 7.1.0
@@ -8850,6 +9648,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
+ '@typescript-eslint/visitor-keys': 7.18.0
+ debug: 4.3.7
+ eslint: 9.10.0(jiti@1.21.6)
+ optionalDependencies:
+ typescript: 5.6.2
+ transitivePeerDependencies:
+ - supports-color
+
'@typescript-eslint/scope-manager@7.1.0':
dependencies:
'@typescript-eslint/types': 7.1.0
@@ -8884,6 +9695,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@typescript-eslint/type-utils@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)':
+ dependencies:
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
+ '@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+ debug: 4.3.7
+ eslint: 9.10.0(jiti@1.21.6)
+ ts-api-utils: 1.3.0(typescript@5.6.2)
+ optionalDependencies:
+ typescript: 5.6.2
+ transitivePeerDependencies:
+ - supports-color
+
'@typescript-eslint/types@7.1.0': {}
'@typescript-eslint/types@7.18.0': {}
@@ -8943,6 +9766,17 @@ snapshots:
- supports-color
- typescript
+ '@typescript-eslint/utils@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@1.21.6))
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
+ eslint: 9.10.0(jiti@1.21.6)
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
'@typescript-eslint/visitor-keys@7.1.0':
dependencies:
'@typescript-eslint/types': 7.1.0
@@ -8955,6 +9789,13 @@ snapshots:
'@ungap/structured-clone@1.2.0': {}
+ '@vitejs/plugin-react-swc@3.7.0(vite@5.4.5(@types/node@20.16.5)(terser@5.32.0))':
+ dependencies:
+ '@swc/core': 1.7.26
+ vite: 5.4.5(@types/node@20.16.5)(terser@5.32.0)
+ transitivePeerDependencies:
+ - '@swc/helpers'
+
'@vitejs/plugin-react@4.3.1(vite@5.4.5(@types/node@20.16.5)(terser@5.32.0))':
dependencies:
'@babel/core': 7.25.2
@@ -8966,6 +9807,48 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@volar/language-core@1.11.1':
+ dependencies:
+ '@volar/source-map': 1.11.1
+
+ '@volar/source-map@1.11.1':
+ dependencies:
+ muggle-string: 0.3.1
+
+ '@volar/typescript@1.11.1':
+ dependencies:
+ '@volar/language-core': 1.11.1
+ path-browserify: 1.0.1
+
+ '@vue/compiler-core@3.5.8':
+ dependencies:
+ '@babel/parser': 7.25.6
+ '@vue/shared': 3.5.8
+ entities: 4.5.0
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.8':
+ dependencies:
+ '@vue/compiler-core': 3.5.8
+ '@vue/shared': 3.5.8
+
+ '@vue/language-core@1.8.27(typescript@5.6.2)':
+ dependencies:
+ '@volar/language-core': 1.11.1
+ '@volar/source-map': 1.11.1
+ '@vue/compiler-dom': 3.5.8
+ '@vue/shared': 3.5.8
+ computeds: 0.0.1
+ minimatch: 9.0.5
+ muggle-string: 0.3.1
+ path-browserify: 1.0.1
+ vue-template-compiler: 2.7.16
+ optionalDependencies:
+ typescript: 5.6.2
+
+ '@vue/shared@3.5.8': {}
+
'@web/browser-logs@0.3.4':
dependencies:
errorstacks: 2.4.1
@@ -9382,6 +10265,15 @@ snapshots:
array-union@2.1.0: {}
+ array.prototype.findlast@1.2.5:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ es-shim-unscopables: 1.0.2
+
array.prototype.findlastindex@1.2.5:
dependencies:
call-bind: 1.0.7
@@ -9405,6 +10297,14 @@ snapshots:
es-abstract: 1.22.3
es-shim-unscopables: 1.0.2
+ array.prototype.tosorted@1.1.4:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-shim-unscopables: 1.0.2
+
arraybuffer.prototype.slice@1.0.2:
dependencies:
array-buffer-byte-length: 1.0.0
@@ -9581,6 +10481,10 @@ snapshots:
dependencies:
fill-range: 7.0.1
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
browser-or-node@3.0.0: {}
browserslist-useragent@4.0.0(browserslist@4.23.3):
@@ -9676,6 +10580,18 @@ snapshots:
chardet@0.7.0: {}
+ chokidar@3.5.3:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.2
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
@@ -9714,6 +10630,10 @@ snapshots:
dependencies:
restore-cursor: 3.1.0
+ cli-cursor@5.0.0:
+ dependencies:
+ restore-cursor: 5.1.0
+
cli-highlight@2.1.11:
dependencies:
chalk: 4.1.2
@@ -9731,6 +10651,11 @@ snapshots:
optionalDependencies:
'@colors/colors': 1.5.0
+ cli-truncate@4.0.0:
+ dependencies:
+ slice-ansi: 5.0.0
+ string-width: 7.2.0
+
cli-width@3.0.0: {}
cliui@7.0.4:
@@ -9773,6 +10698,8 @@ snapshots:
color-name@1.1.4: {}
+ colorette@2.0.20: {}
+
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
@@ -9791,10 +10718,15 @@ snapshots:
table-layout: 4.1.1
typical: 7.1.1
+ commander@12.1.0: {}
+
commander@2.20.3: {}
commander@4.1.1: {}
+ commander@9.5.0:
+ optional: true
+
commitizen@4.3.0(@types/node@20.16.5)(typescript@5.6.2):
dependencies:
cachedir: 2.3.0
@@ -9820,6 +10752,8 @@ snapshots:
array-ify: 1.0.0
dot-prop: 5.3.0
+ computeds@0.0.1: {}
+
concat-map@0.0.1: {}
concurrently@8.2.2:
@@ -10008,6 +10942,8 @@ snapshots:
dependencies:
'@babel/runtime': 7.25.6
+ de-indent@1.0.2: {}
+
debounce@1.2.1: {}
debug@2.6.9:
@@ -10140,6 +11076,8 @@ snapshots:
emittery@0.13.1: {}
+ emoji-regex@10.4.0: {}
+
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
@@ -10285,6 +11223,23 @@ snapshots:
es-errors@1.3.0: {}
+ es-iterator-helpers@1.0.19:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-set-tostringtag: 2.0.3
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ globalthis: 1.0.3
+ has-property-descriptors: 1.0.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ internal-slot: 1.0.7
+ iterator.prototype: 1.1.2
+ safe-array-concat: 1.1.2
+
es-module-lexer@1.5.4: {}
es-module-shims@1.10.0: {}
@@ -10526,14 +11481,58 @@ snapshots:
eslint-plugin-only-warn@1.1.0: {}
+ eslint-plugin-prettier@5.2.1(@types/eslint@8.56.2)(eslint-config-prettier@9.1.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3):
+ dependencies:
+ eslint: 9.10.0(jiti@1.21.6)
+ prettier: 3.3.3
+ prettier-linter-helpers: 1.0.0
+ synckit: 0.9.1
+ optionalDependencies:
+ '@types/eslint': 8.56.2
+ eslint-config-prettier: 9.1.0(eslint@9.10.0(jiti@1.21.6))
+
eslint-plugin-react-hooks@4.6.2(eslint@8.57.0):
dependencies:
eslint: 8.57.0
+ eslint-plugin-react-hooks@4.6.2(eslint@9.10.0(jiti@1.21.6)):
+ dependencies:
+ eslint: 9.10.0(jiti@1.21.6)
+
eslint-plugin-react-refresh@0.4.11(eslint@8.57.0):
dependencies:
eslint: 8.57.0
+ eslint-plugin-react-refresh@0.4.11(eslint@9.10.0(jiti@1.21.6)):
+ dependencies:
+ eslint: 9.10.0(jiti@1.21.6)
+
+ eslint-plugin-react@7.36.1(eslint@9.10.0(jiti@1.21.6)):
+ dependencies:
+ array-includes: 3.1.8
+ array.prototype.findlast: 1.2.5
+ array.prototype.flatmap: 1.3.2
+ array.prototype.tosorted: 1.1.4
+ doctrine: 2.1.0
+ es-iterator-helpers: 1.0.19
+ eslint: 9.10.0(jiti@1.21.6)
+ estraverse: 5.3.0
+ hasown: 2.0.2
+ jsx-ast-utils: 3.3.5
+ minimatch: 3.1.2
+ object.entries: 1.1.8
+ object.fromentries: 2.0.8
+ object.values: 1.2.0
+ prop-types: 15.8.1
+ resolve: 2.0.0-next.5
+ semver: 6.3.1
+ string.prototype.matchall: 4.0.11
+ string.prototype.repeat: 1.0.0
+
+ eslint-plugin-simple-import-sort@12.1.1(eslint@9.10.0(jiti@1.21.6)):
+ dependencies:
+ eslint: 9.10.0(jiti@1.21.6)
+
eslint-plugin-turbo@2.0.0(eslint@9.10.0(jiti@1.21.6)):
dependencies:
dotenv: 16.0.3
@@ -10710,6 +11709,8 @@ snapshots:
etag@1.8.1: {}
+ eventemitter3@5.0.1: {}
+
execa@5.1.1:
dependencies:
cross-spawn: 7.0.3
@@ -10781,6 +11782,8 @@ snapshots:
fast-deep-equal@3.1.3: {}
+ fast-diff@1.3.0: {}
+
fast-fifo@1.3.2: {}
fast-glob@3.3.1:
@@ -10848,6 +11851,10 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
find-node-modules@2.1.3:
dependencies:
findup-sync: 4.0.0
@@ -10930,6 +11937,12 @@ snapshots:
jsonfile: 6.1.0
universalify: 2.0.0
+ fs-extra@7.0.1:
+ dependencies:
+ graceful-fs: 4.2.11
+ jsonfile: 4.0.0
+ universalify: 0.1.2
+
fs-extra@9.1.0:
dependencies:
at-least-node: 1.0.0
@@ -10962,6 +11975,8 @@ snapshots:
get-caller-file@2.0.5: {}
+ get-east-asian-width@1.2.0: {}
+
get-intrinsic@1.2.2:
dependencies:
function-bind: 1.1.2
@@ -11111,6 +12126,8 @@ snapshots:
slash: 5.1.0
unicorn-magic: 0.1.0
+ globrex@0.1.2: {}
+
gopd@1.0.1:
dependencies:
get-intrinsic: 1.2.2
@@ -11166,6 +12183,8 @@ snapshots:
dependencies:
function-bind: 1.1.2
+ he@1.2.0: {}
+
highlight.js@10.7.3: {}
homedir-polyfill@1.0.3:
@@ -11284,6 +12303,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ import-lazy@4.0.0: {}
+
import-local@3.2.0:
dependencies:
pkg-dir: 4.2.0
@@ -11374,6 +12395,10 @@ snapshots:
is-arrayish@0.2.1: {}
+ is-async-function@2.0.0:
+ dependencies:
+ has-tostringtag: 1.0.2
+
is-bigint@1.0.4:
dependencies:
has-bigints: 1.0.2
@@ -11413,8 +12438,18 @@ snapshots:
is-extglob@2.1.1: {}
+ is-finalizationregistry@1.0.2:
+ dependencies:
+ call-bind: 1.0.7
+
is-fullwidth-code-point@3.0.0: {}
+ is-fullwidth-code-point@4.0.0: {}
+
+ is-fullwidth-code-point@5.0.0:
+ dependencies:
+ get-east-asian-width: 1.2.0
+
is-generator-fn@2.1.0: {}
is-generator-function@1.0.10:
@@ -11427,6 +12462,8 @@ snapshots:
is-interactive@1.0.0: {}
+ is-map@2.0.3: {}
+
is-module@1.0.0: {}
is-negative-zero@2.0.2: {}
@@ -11452,6 +12489,8 @@ snapshots:
call-bind: 1.0.5
has-tostringtag: 1.0.0
+ is-set@2.0.3: {}
+
is-shared-array-buffer@1.0.2:
dependencies:
call-bind: 1.0.5
@@ -11488,10 +12527,17 @@ snapshots:
is-utf8@0.2.1: {}
+ is-weakmap@2.0.2: {}
+
is-weakref@1.0.2:
dependencies:
call-bind: 1.0.5
+ is-weakset@2.0.3:
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+
is-windows@1.0.2: {}
is-wsl@2.2.0:
@@ -11557,6 +12603,14 @@ snapshots:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.1
+ iterator.prototype@1.1.2:
+ dependencies:
+ define-properties: 1.2.1
+ get-intrinsic: 1.2.4
+ has-symbols: 1.0.3
+ reflect.getprototypeof: 1.0.6
+ set-function-name: 2.0.1
+
jackspeak@3.4.3:
dependencies:
'@isaacs/cliui': 8.0.2
@@ -11919,6 +12973,8 @@ snapshots:
jiti@1.21.6: {}
+ jju@1.4.0: {}
+
js-tokens@4.0.0: {}
js-yaml@3.14.1:
@@ -11988,12 +13044,23 @@ snapshots:
json5@2.2.3: {}
+ jsonfile@4.0.0:
+ optionalDependencies:
+ graceful-fs: 4.2.11
+
jsonfile@6.1.0:
dependencies:
universalify: 2.0.0
optionalDependencies:
graceful-fs: 4.2.11
+ jsx-ast-utils@3.3.5:
+ dependencies:
+ array-includes: 3.1.8
+ array.prototype.flat: 1.3.2
+ object.assign: 4.1.5
+ object.values: 1.2.0
+
keygrip@1.1.0:
dependencies:
tsscmp: 1.0.6
@@ -12058,6 +13125,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ kolorist@1.8.0: {}
+
leven@3.1.0: {}
levn@0.4.1:
@@ -12082,6 +13151,30 @@ snapshots:
lines-and-columns@1.2.4: {}
+ lint-staged@15.2.10:
+ dependencies:
+ chalk: 5.3.0
+ commander: 12.1.0
+ debug: 4.3.7
+ execa: 8.0.1
+ lilconfig: 3.1.2
+ listr2: 8.2.4
+ micromatch: 4.0.8
+ pidtree: 0.6.0
+ string-argv: 0.3.2
+ yaml: 2.5.1
+ transitivePeerDependencies:
+ - supports-color
+
+ listr2@8.2.4:
+ dependencies:
+ cli-truncate: 4.0.0
+ colorette: 2.0.20
+ eventemitter3: 5.0.1
+ log-update: 6.1.0
+ rfdc: 1.4.1
+ wrap-ansi: 9.0.0
+
lit-element@4.1.0:
dependencies:
'@lit-labs/ssr-dom-shim': 1.2.1
@@ -12128,6 +13221,8 @@ snapshots:
lodash.escaperegexp@4.1.2: {}
+ lodash.get@4.4.2: {}
+
lodash.isequal@4.5.0: {}
lodash.isplainobject@4.0.6: {}
@@ -12161,6 +13256,14 @@ snapshots:
slice-ansi: 4.0.0
wrap-ansi: 6.2.0
+ log-update@6.1.0:
+ dependencies:
+ ansi-escapes: 7.0.0
+ cli-cursor: 5.0.0
+ slice-ansi: 7.1.0
+ strip-ansi: 7.1.0
+ wrap-ansi: 9.0.0
+
longest@2.0.1: {}
loose-envify@1.4.0:
@@ -12185,6 +13288,10 @@ snapshots:
luxon@3.5.0: {}
+ magic-string@0.30.11:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
make-dir@4.0.0:
dependencies:
semver: 7.6.3
@@ -12226,6 +13333,11 @@ snapshots:
braces: 3.0.2
picomatch: 2.3.1
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
mime-db@1.52.0: {}
mime-types@2.1.35:
@@ -12238,10 +13350,16 @@ snapshots:
mimic-fn@4.0.0: {}
+ mimic-function@5.0.1: {}
+
minimatch@10.0.1:
dependencies:
brace-expansion: 2.0.1
+ minimatch@3.0.8:
+ dependencies:
+ brace-expansion: 1.1.11
+
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
@@ -12284,6 +13402,8 @@ snapshots:
ms@2.1.3: {}
+ muggle-string@0.3.1: {}
+
mute-stream@0.0.8: {}
mz@2.7.0:
@@ -12373,6 +13493,12 @@ snapshots:
define-properties: 1.2.1
es-abstract: 1.22.3
+ object.entries@1.1.8:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+
object.fromentries@2.0.8:
dependencies:
call-bind: 1.0.7
@@ -12408,6 +13534,10 @@ snapshots:
dependencies:
mimic-fn: 4.0.0
+ onetime@7.0.0:
+ dependencies:
+ mimic-function: 5.0.1
+
only@0.0.2: {}
open@8.4.2:
@@ -12539,6 +13669,8 @@ snapshots:
parseurl@1.3.3: {}
+ path-browserify@1.0.1: {}
+
path-exists@3.0.0: {}
path-exists@4.0.0: {}
@@ -12571,6 +13703,8 @@ snapshots:
picomatch@2.3.1: {}
+ pidtree@0.6.0: {}
+
pify@2.3.0: {}
pify@3.0.0: {}
@@ -12643,8 +13777,14 @@ snapshots:
prelude-ls@1.2.1: {}
+ prettier-linter-helpers@1.0.0:
+ dependencies:
+ fast-diff: 1.3.0
+
prettier@3.2.5: {}
+ prettier@3.3.3: {}
+
pretty-format@29.7.0:
dependencies:
'@jest/schemas': 29.6.3
@@ -12666,6 +13806,12 @@ snapshots:
kleur: 3.0.3
sisteransi: 1.0.5
+ prop-types@15.8.1:
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+
proto-list@1.2.4: {}
proxy-agent@6.3.0:
@@ -12749,6 +13895,10 @@ snapshots:
react-fast-compare: 3.2.2
shallowequal: 1.1.0
+ react-hooks@1.0.1: {}
+
+ react-is@16.13.1: {}
+
react-is@18.3.1: {}
react-refresh@0.14.2: {}
@@ -12807,6 +13957,16 @@ snapshots:
dependencies:
picomatch: 2.3.1
+ reflect.getprototypeof@1.0.6:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ globalthis: 1.0.3
+ which-builtin-type: 1.1.4
+
regenerate-unicode-properties@10.2.0:
dependencies:
regenerate: 1.4.2
@@ -12880,19 +14040,37 @@ snapshots:
resolve.exports@2.0.2: {}
+ resolve@1.19.0:
+ dependencies:
+ is-core-module: 2.15.1
+ path-parse: 1.0.7
+
resolve@1.22.8:
dependencies:
is-core-module: 2.15.1
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
+ resolve@2.0.0-next.5:
+ dependencies:
+ is-core-module: 2.15.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
restore-cursor@3.1.0:
dependencies:
onetime: 5.1.2
signal-exit: 3.0.7
+ restore-cursor@5.1.0:
+ dependencies:
+ onetime: 7.0.0
+ signal-exit: 4.1.0
+
reusify@1.0.4: {}
+ rfdc@1.4.1: {}
+
rimraf@3.0.2:
dependencies:
glob: 7.2.3
@@ -13085,6 +14263,13 @@ snapshots:
functions-have-names: 1.2.3
has-property-descriptors: 1.0.1
+ set-function-name@2.0.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+
setprototypeof@1.1.0: {}
setprototypeof@1.2.0: {}
@@ -13140,6 +14325,16 @@ snapshots:
astral-regex: 2.0.0
is-fullwidth-code-point: 3.0.0
+ slice-ansi@5.0.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 4.0.0
+
+ slice-ansi@7.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 5.0.0
+
smart-buffer@4.2.0: {}
socket.io-client@4.7.5:
@@ -13236,6 +14431,8 @@ snapshots:
optionalDependencies:
bare-events: 2.4.2
+ string-argv@0.3.2: {}
+
string-length@4.0.2:
dependencies:
char-regex: 1.0.2
@@ -13253,6 +14450,32 @@ snapshots:
emoji-regex: 9.2.2
strip-ansi: 7.1.0
+ string-width@7.2.0:
+ dependencies:
+ emoji-regex: 10.4.0
+ get-east-asian-width: 1.2.0
+ strip-ansi: 7.1.0
+
+ string.prototype.matchall@4.0.11:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ get-intrinsic: 1.2.4
+ gopd: 1.0.1
+ has-symbols: 1.0.3
+ internal-slot: 1.0.7
+ regexp.prototype.flags: 1.5.2
+ set-function-name: 2.0.2
+ side-channel: 1.0.6
+
+ string.prototype.repeat@1.0.0:
+ dependencies:
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+
string.prototype.trim@1.2.8:
dependencies:
call-bind: 1.0.5
@@ -13356,6 +14579,11 @@ snapshots:
symbol-tree@3.2.4: {}
+ synckit@0.9.1:
+ dependencies:
+ '@pkgr/core': 0.1.1
+ tslib: 2.6.2
+
systemjs@6.15.1: {}
table-layout@4.1.1:
@@ -13550,6 +14778,10 @@ snapshots:
tsc@2.0.4: {}
+ tsconfck@3.1.3(typescript@5.6.2):
+ optionalDependencies:
+ typescript: 5.6.2
+
tsconfig-paths@3.15.0:
dependencies:
'@types/json5': 0.0.29
@@ -13672,6 +14904,8 @@ snapshots:
typescript@5.3.3: {}
+ typescript@5.4.2: {}
+
typescript@5.4.5: {}
typescript@5.6.2: {}
@@ -13720,6 +14954,8 @@ snapshots:
universal-user-agent@7.0.2: {}
+ universalify@0.1.2: {}
+
universalify@0.2.0: {}
universalify@2.0.0: {}
@@ -13764,8 +15000,49 @@ snapshots:
spdx-correct: 3.2.0
spdx-expression-parse: 3.0.1
+ validator@13.12.0: {}
+
vary@1.1.2: {}
+ vite-plugin-dts@3.9.1(@types/node@20.16.5)(rollup@4.21.3)(typescript@5.6.2)(vite@5.4.5(@types/node@20.16.5)(terser@5.32.0)):
+ dependencies:
+ '@microsoft/api-extractor': 7.43.0(@types/node@20.16.5)
+ '@rollup/pluginutils': 5.1.0(rollup@4.21.3)
+ '@vue/language-core': 1.8.27(typescript@5.6.2)
+ debug: 4.3.7
+ kolorist: 1.8.0
+ magic-string: 0.30.11
+ typescript: 5.6.2
+ vue-tsc: 1.8.27(typescript@5.6.2)
+ optionalDependencies:
+ vite: 5.4.5(@types/node@20.16.5)(terser@5.32.0)
+ transitivePeerDependencies:
+ - '@types/node'
+ - rollup
+ - supports-color
+
+ vite-plugin-linter@2.1.1(rollup@4.21.3):
+ dependencies:
+ '@rollup/pluginutils': 5.1.0(rollup@4.21.3)
+ '@types/eslint': 8.56.2
+ chokidar: 3.5.3
+ eslint: 8.56.0
+ typescript: 5.3.3
+ transitivePeerDependencies:
+ - rollup
+ - supports-color
+
+ vite-tsconfig-paths@4.3.2(typescript@5.6.2)(vite@5.4.5(@types/node@20.16.5)(terser@5.32.0)):
+ dependencies:
+ debug: 4.3.7
+ globrex: 0.1.2
+ tsconfck: 3.1.3(typescript@5.6.2)
+ optionalDependencies:
+ vite: 5.4.5(@types/node@20.16.5)(terser@5.32.0)
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
vite@5.4.5(@types/node@20.16.5)(terser@5.32.0):
dependencies:
esbuild: 0.21.5
@@ -13776,6 +15053,18 @@ snapshots:
fsevents: 2.3.3
terser: 5.32.0
+ vue-template-compiler@2.7.16:
+ dependencies:
+ de-indent: 1.0.2
+ he: 1.2.0
+
+ vue-tsc@1.8.27(typescript@5.6.2):
+ dependencies:
+ '@volar/typescript': 1.11.1
+ '@vue/language-core': 1.8.27(typescript@5.6.2)
+ semver: 7.6.3
+ typescript: 5.6.2
+
w3c-xmlserializer@4.0.0:
dependencies:
xml-name-validator: 4.0.0
@@ -13818,6 +15107,28 @@ snapshots:
is-string: 1.0.7
is-symbol: 1.0.4
+ which-builtin-type@1.1.4:
+ dependencies:
+ function.prototype.name: 1.1.6
+ has-tostringtag: 1.0.2
+ is-async-function: 2.0.0
+ is-date-object: 1.0.5
+ is-finalizationregistry: 1.0.2
+ is-generator-function: 1.0.10
+ is-regex: 1.1.4
+ is-weakref: 1.0.2
+ isarray: 2.0.5
+ which-boxed-primitive: 1.0.2
+ which-collection: 1.0.2
+ which-typed-array: 1.1.15
+
+ which-collection@1.0.2:
+ dependencies:
+ is-map: 2.0.3
+ is-set: 2.0.3
+ is-weakmap: 2.0.2
+ is-weakset: 2.0.3
+
which-typed-array@1.1.13:
dependencies:
available-typed-arrays: 1.0.5
@@ -13866,6 +15177,12 @@ snapshots:
string-width: 5.1.2
strip-ansi: 7.1.0
+ wrap-ansi@9.0.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 7.2.0
+ strip-ansi: 7.1.0
+
wrappy@1.0.2: {}
write-file-atomic@4.0.2:
@@ -13944,4 +15261,12 @@ snapshots:
yoctocolors@2.1.1: {}
+ z-schema@5.0.5:
+ dependencies:
+ lodash.get: 4.4.2
+ lodash.isequal: 4.5.0
+ validator: 13.12.0
+ optionalDependencies:
+ commander: 9.5.0
+
zod@3.23.8: {}
diff --git a/turbo.json b/turbo.json
index 8b118ed7..a0c3fd3b 100644
--- a/turbo.json
+++ b/turbo.json
@@ -76,6 +76,15 @@
},
"@superviz/sdk#test:unit:ci": {
"dependsOn": ["@superviz/socket-client#build"]
+ },
+ "@superviz/react-sdk#build": {
+ "dependsOn": [
+ "@superviz/autodesk-viewer-plugin#build",
+ "@superviz/matterport-plugin#build",
+ "@superviz/sdk#build",
+ "@superviz/socket-client#build",
+ "@superviz/threejs-plugin#build"
+ ]
}
}
}