This is an automated email from the ASF dual-hosted git repository.

danwatford pushed a commit to branch ofbiz-12789-npm-example-plugin
in repository https://gitbox.apache.org/repos/asf/ofbiz-plugins.git

commit 2b0a6ed8ee7bb3684802de1b565ef82502cfe492
Author: Daniel Watford <dan...@watfordconsulting.com>
AuthorDate: Thu Apr 13 21:33:21 2023 +0100

    Added: React typescript application to example plugin (OFBIZ-12789)
    
    To demonstrate node/npm functionality available to all components, a
    small typescript react web application has been integrated into the
    example plugin.
    
    See example/REAME-react for information about how this integration was
    created.
---
 example/.gitignore                             |    2 +
 example/README-react                           |   72 +
 example/build.gradle                           |   24 +
 example/config/ExampleUiLabels.xml             |    3 +
 example/groovyScripts/LoadReactApp.groovy      |   71 +
 example/vite-react-app/.gitignore              |   24 +
 example/vite-react-app/index.html              |   13 +
 example/vite-react-app/package-lock.json       | 2290 ++++++++++++++++++++++++
 example/vite-react-app/package.json            |   22 +
 example/vite-react-app/public/vite.svg         |    1 +
 example/vite-react-app/src/App.css             |   42 +
 example/vite-react-app/src/App.tsx             |   36 +
 example/vite-react-app/src/assets/react.svg    |    1 +
 example/vite-react-app/src/index.css           |    0
 example/vite-react-app/src/main.tsx            |   10 +
 example/vite-react-app/src/vite-env.d.ts       |    1 +
 example/vite-react-app/tsconfig.json           |   21 +
 example/vite-react-app/tsconfig.node.json      |    9 +
 example/vite-react-app/vite.config.ts          |   12 +
 example/webapp/example/WEB-INF/controller.xml  |   12 +-
 example/webapp/example/WEB-INF/web.xml         |    2 +-
 example/widget/example/CommonScreens.xml       |   20 +
 example/widget/example/ExampleMenus.xml        |    3 +
 example/widget/example/ExampleReactScreens.xml |   51 +
 24 files changed, 2740 insertions(+), 2 deletions(-)

diff --git a/example/.gitignore b/example/.gitignore
new file mode 100644
index 000000000..29c35bebe
--- /dev/null
+++ b/example/.gitignore
@@ -0,0 +1,2 @@
+webapp/example/vite-react-app
+.gradle
diff --git a/example/README-react b/example/README-react
new file mode 100644
index 000000000..559d74968
--- /dev/null
+++ b/example/README-react
@@ -0,0 +1,72 @@
+This README describes the steps taken to add a Vite React app to the example 
plugin.
+
+The react-app was created using the following command from the 
`plugins/example` directory:
+
+    npm create vite@latest vite-react-app --template react-ts
+
+
+
+The generated application is geared towards a web server where the react app 
is the sole component served. We need
+to integrate the app with the example servlet, allowing it to be served 
alongside OFBiz.
+
+The built react app will be served from within the example webapp from a 
directory called `vite-react-app`. We
+therefore need to configure the build to use an appropriate URL path so that 
the main javascript file can locate any
+other javascript chunks it needs to load.
+
+To do this, we added the `base` property to the configuration defined in file 
`vite.config.ts`:
+
+    base: '/example/vite-react-app/'
+
+
+
+The ControlFilter defined in webapp/example/WEB-INF/web.xml needs to be 
configured to allow requests to the
+/example/vite-react-app path. We do this by modifying the `allowedPaths` 
parameter in web.xml:
+
+    <init-param>
+        <param-name>allowedPaths</param-name>
+        
<param-value>/error:/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images:/js:/ws:/vite-react-app</param-value>
+    </init-param>
+
+The `/vite-react-app` path element was added to the other allowed Paths.
+
+
+
+The new react app has been created outside of the example webapp directory. 
This ensures that sources and libraries
+used by the react app build process are not served as part of the webapp. We 
need the output of the build process, i.e.
+the compiled react app, to be available within the webapp. We do this by 
setting the `build.outDir` property in file
+`vite.config.ts`:
+
+    build: {
+        ...
+        outDir: '../webapp/example/vite-react-app',
+    },
+
+
+
+The assets produced by the apps build process include a hash in the filename. 
This is to ensure that the browsers don't
+cache older versions of the assets. To help us identify the files to be served 
by the example plugin we need to write
+a manifest file that contains the names of the files produced by the build 
process. We do this by adding the
+`build.manifest` property to the configuration in file `vite.config.ts`:
+
+    build: {
+        ...
+        manifest: true,
+    },
+
+
+
+The index.css file produced by the `create vite@latest` command above is not 
needed and would interfere with the
+OFBiz theme's CSS. The vite react app build process depends on the file being 
present, so we needed to remove its
+contents.
+
+
+
+To incorporate the react app into pages rendered by the example plugin, we 
added a new screen in ExampleReactScreens.xml
+and a new screen decorator, `example-react-decorator` in CommonScreens.xml.
+
+The screen includes a container widget with id ReactExamplesRootContainer 
which will be rendered in HTML as a div.
+React app source file, main.tsx, was modified to search for this element ID 
which is used as the root element for
+rendering the react app.
+
+The screen decorator does the work of including the react app's CSS and 
Javascript in rendered output. It identifies
+the relevant files by reading the manifest file produced by the react app's 
build process.
diff --git a/example/build.gradle b/example/build.gradle
index 73320c9ab..5f4118bd8 100644
--- a/example/build.gradle
+++ b/example/build.gradle
@@ -17,6 +17,30 @@
  * under the License.
  */
 
+plugins {
+    id 'ofbiz-node-conventions'
+}
+
 dependencies {
     pluginLibsCompile 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.69'
 }
+
+node {
+    nodeProjectDir = file("vite-react-app")
+}
+
+task buildReactApp (type: NpmTask) {
+    inputs.files(fileTree('vite-react-app'))
+
+    outputs.dir('webapp/example/vite-react-app')
+
+    dependsOn npmInstall
+    args = ['run', 'build', '--', '--emptyOutDir']
+}
+
+// Build the react app when the classes task is run.
+project.rootProject.tasks.getByName('classes').dependsOn buildReactApp
+
+// Hook into the root project's clean task to clean up the output from the
+// buildReactApp task.
+project.rootProject.tasks.clean.dependsOn cleanBuildReactApp
diff --git a/example/config/ExampleUiLabels.xml 
b/example/config/ExampleUiLabels.xml
index f1eef6d69..159dfdf7c 100644
--- a/example/config/ExampleUiLabels.xml
+++ b/example/config/ExampleUiLabels.xml
@@ -40,6 +40,9 @@
         <value xml:lang="zh">要使用这个Ajax演示,你必须让你的浏览器启用JavaScript。</value>
         <value xml:lang="zh-TW">要使用這個Ajax演示,你必須讓你的瀏覽器啟用JavaScript.</value>
     </property>
+    <property key="ExampleReactExamples">
+        <value xml:lang="en">React Examples</value>
+    </property>
   <!-- Example component properties -->
     <property key="ExampleApplication">
         <value xml:lang="en">Example Application</value>
diff --git a/example/groovyScripts/LoadReactApp.groovy 
b/example/groovyScripts/LoadReactApp.groovy
new file mode 100644
index 000000000..a42bb8141
--- /dev/null
+++ b/example/groovyScripts/LoadReactApp.groovy
@@ -0,0 +1,71 @@
+import groovy.json.JsonSlurper
+import org.apache.ofbiz.widget.model.ScriptLinkHelper
+
+import java.nio.file.Path
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Useful variables with example values:
+// controlPath ->= /example/control
+// contextRoot -> 
C:\dev\floss\ofbiz\ofbiz-framework\plugins\example\webapp\example\
+// serverRoot -> https://localhost:8443
+// context.application.context.context.path -> /example
+
+// Path component of URL leading to the servlet mount point, e.g. '/example'.
+String contextUrlPath = context.application.context.context.path
+// Filesystem path to the webapp root, e.g. 
'$ofbiz-framework/plugins/example/webapp/example/'.
+String contextFilesystemPath  = context.contextRoot
+
+String reactAppDirectory = 'vite-react-app'
+String reactAppUrlPath = contextUrlPath + '/' + reactAppDirectory + '/'
+
+// Path to the vite react app manifest file. This lists all the files that are 
part of the react app.
+// We read this file to identify the main javascript and css files.
+// Example manifest file:
+// {
+//  "index.css": {
+//    "file": "assets/index-e12e197a.css",
+//    "src": "index.css"
+//  },
+//  "index.html": {
+//    "assets": [
+//      "assets/react-35ef61ed.svg"
+//    ],
+//    "css": [
+//      "assets/index-e12e197a.css"
+//    ],
+//    "file": "assets/index-e5a516b1.js",
+// ...
+Path assetManifestPath = Path.of(contextFilesystemPath, reactAppDirectory, 
'manifest.json')
+
+// Extract the URL paths to the index javascript and css files from the 
manifest file.
+Map<String, Object> assetManifest = new 
JsonSlurper().parse(assetManifestPath.toFile())
+String stylesheetDistRelativePath = assetManifest.'index.css'.file
+String javascriptDistRelativePath = assetManifest.'index.html'.file
+
+// Retrieve the content of the javascript file.
+Path javascriptFilesystemPath = Path.of(contextFilesystemPath, 
reactAppDirectory, javascriptDistRelativePath)
+String javascriptContent = javascriptFilesystemPath.toFile().text
+
+// Prepare a link to the (now cached) javascript file to be included in the 
end of the currently rendering screen.
+ScriptLinkHelper.prepareScriptLinkForBodyEnd(context.request, reactAppUrlPath 
+ javascriptDistRelativePath, javascriptContent)
+
+// Return the stylesheet path for use by the screen.
+context.reactAppStylesheetUrlPath = reactAppUrlPath + 
stylesheetDistRelativePath
\ No newline at end of file
diff --git a/example/vite-react-app/.gitignore 
b/example/vite-react-app/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/example/vite-react-app/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/example/vite-react-app/index.html 
b/example/vite-react-app/index.html
new file mode 100644
index 000000000..e0d1c8408
--- /dev/null
+++ b/example/vite-react-app/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Vite + React + TS</title>
+  </head>
+  <body>
+    <div id="root"></div>
+    <script type="module" src="/src/main.tsx"></script>
+  </body>
+</html>
diff --git a/example/vite-react-app/package-lock.json 
b/example/vite-react-app/package-lock.json
new file mode 100644
index 000000000..10212e874
--- /dev/null
+++ b/example/vite-react-app/package-lock.json
@@ -0,0 +1,2290 @@
+{
+  "name": "vite-react-app",
+  "version": "0.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "vite-react-app",
+      "version": "0.0.0",
+      "dependencies": {
+        "react": "^18.2.0",
+        "react-dom": "^18.2.0"
+      },
+      "devDependencies": {
+        "@types/react": "^18.0.28",
+        "@types/react-dom": "^18.0.11",
+        "@vitejs/plugin-react": "^3.1.0",
+        "typescript": "^4.9.3",
+        "vite": "^4.2.0"
+      }
+    },
+    "node_modules/@ampproject/remapping": {
+      "version": "2.2.1",
+      "resolved": 
"https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz";,
+      "integrity": 
"sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.0",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz";,
+      "integrity": 
"sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/highlight": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz";,
+      "integrity": 
"sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.21.4",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz";,
+      "integrity": 
"sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==",
+      "dev": true,
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.21.4",
+        "@babel/generator": "^7.21.4",
+        "@babel/helper-compilation-targets": "^7.21.4",
+        "@babel/helper-module-transforms": "^7.21.2",
+        "@babel/helpers": "^7.21.0",
+        "@babel/parser": "^7.21.4",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.4",
+        "@babel/types": "^7.21.4",
+        "convert-source-map": "^1.7.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.2",
+        "semver": "^6.3.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel";
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz";,
+      "integrity": 
"sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.21.4",
+        "@jridgewell/gen-mapping": "^0.3.2",
+        "@jridgewell/trace-mapping": "^0.3.17",
+        "jsesc": "^2.5.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz";,
+      "integrity": 
"sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/compat-data": "^7.21.4",
+        "@babel/helper-validator-option": "^7.21.0",
+        "browserslist": "^4.21.3",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-environment-visitor": {
+      "version": "7.18.9",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz";,
+      "integrity": 
"sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-function-name": {
+      "version": "7.21.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz";,
+      "integrity": 
"sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/template": "^7.20.7",
+        "@babel/types": "^7.21.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-hoist-variables": {
+      "version": "7.18.6",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz";,
+      "integrity": 
"sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz";,
+      "integrity": 
"sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.21.4"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.21.2",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz";,
+      "integrity": 
"sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-module-imports": "^7.18.6",
+        "@babel/helper-simple-access": "^7.20.2",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/helper-validator-identifier": "^7.19.1",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.2",
+        "@babel/types": "^7.21.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.20.2",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz";,
+      "integrity": 
"sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-simple-access": {
+      "version": "7.20.2",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz";,
+      "integrity": 
"sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.20.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-split-export-declaration": {
+      "version": "7.18.6",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz";,
+      "integrity": 
"sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.19.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz";,
+      "integrity": 
"sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.19.1",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz";,
+      "integrity": 
"sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-option": {
+      "version": "7.21.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz";,
+      "integrity": 
"sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.21.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz";,
+      "integrity": 
"sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.0",
+        "@babel/types": "^7.21.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/highlight": {
+      "version": "7.18.6",
+      "resolved": 
"https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz";,
+      "integrity": 
"sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.18.6",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz";,
+      "integrity": 
"sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==",
+      "dev": true,
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-self": {
+      "version": "7.21.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz";,
+      "integrity": 
"sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.20.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-source": {
+      "version": "7.19.6",
+      "resolved": 
"https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz";,
+      "integrity": 
"sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.19.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.20.7",
+      "resolved": 
"https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz";,
+      "integrity": 
"sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.18.6",
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz";,
+      "integrity": 
"sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.21.4",
+        "@babel/generator": "^7.21.4",
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-function-name": "^7.21.0",
+        "@babel/helper-hoist-variables": "^7.18.6",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/parser": "^7.21.4",
+        "@babel/types": "^7.21.4",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.21.4",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz";,
+      "integrity": 
"sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.19.4",
+        "@babel/helper-validator-identifier": "^7.19.1",
+        "to-fast-properties": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.16.tgz";,
+      "integrity": 
"sha512-baLqRpLe4JnKrUXLJChoTN0iXZH7El/mu58GE3WIA6/H834k0XWvLRmGLG8y8arTRS9hJJibPnF0tiGhmWeZgw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-QX48qmsEZW+gcHgTmAj+x21mwTz8MlYQBnzF6861cNdQGvj2jzzFjqH0EBabrIa/WVZ2CHolwMoqxVryqKt8+Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-G4wfHhrrz99XJgHnzFvB4UwwPxAWZaZBOFXh+JH1Duf1I4vIVfuYY9uVLpx4eiV2D/Jix8LJY+TAdZ3i40tDow==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-/Ofw8UXZxuzTLsNFmz1+lmarQI6ztMZ9XktvXedTbt3SNWDn0+ODTwxExLYQ/Hod91EZB4vZPQJLoqLF0jvEzA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-SzBQtCV3Pdc9kyizh36Ol+dNVhkDyIrGb/JXZqFq8WL37LIyrXU0gUpADcNV311sCOhvY+f2ivMhb5Tuv8nMOQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-ZqftdfS1UlLiH1DnS2u3It7l4Bc3AskKeu+paJSfk7RNOMrOxmeFDhLTMQqMxycP1C3oj8vgkAT6xfAuq7ZPRA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-rHV6zNWW1tjgsu0dKQTX9L0ByiJHHLvQKrWtnz8r0YYJI27FU3Xu48gpK2IBj1uCSYhJ+pEk6Y0Um7U3rIvV8g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.16.tgz";,
+      "integrity": 
"sha512-n4O8oVxbn7nl4+m+ISb0a68/lcJClIbaGAoXwqeubj/D1/oMMuaAXmJVfFlRjJLu/ZvHkxoiFJnmbfp4n8cdSw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-8yoZhGkU6aHu38WpaM4HrRLTFc7/VVD9Q2SvPcmIQIipQt2I/GMTZNdEHXoypbbGao5kggLcxg0iBKjo0SQYKA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.16.tgz";,
+      "integrity": 
"sha512-9ZBjlkdaVYxPNO8a7OmzDbOH9FMQ1a58j7Xb21UfRU29KcEEU3VTHk+Cvrft/BNv0gpWJMiiZ/f4w0TqSP0gLA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.16.tgz";,
+      "integrity": 
"sha512-TIZTRojVBBzdgChY3UOG7BlPhqJz08AL7jdgeeu+kiObWMFzGnQD7BgBBkWRwOtKR1i2TNlO7YK6m4zxVjjPRQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.16.tgz";,
+      "integrity": 
"sha512-UPeRuFKCCJYpBbIdczKyHLAIU31GEm0dZl1eMrdYeXDH+SJZh/i+2cAmD3A1Wip9pIc5Sc6Kc5cFUrPXtR0XHA==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.16.tgz";,
+      "integrity": 
"sha512-io6yShgIEgVUhExJejJ21xvO5QtrbiSeI7vYUnr7l+v/O9t6IowyhdiYnyivX2X5ysOVHAuyHW+Wyi7DNhdw6Q==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.16.tgz";,
+      "integrity": 
"sha512-WhlGeAHNbSdG/I2gqX2RK2gfgSNwyJuCiFHMc8s3GNEMMHUI109+VMBfhVqRb0ZGzEeRiibi8dItR3ws3Lk+cA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.16.tgz";,
+      "integrity": 
"sha512-gHRReYsJtViir63bXKoFaQ4pgTyah4ruiMRQ6im9YZuv+gp3UFJkNTY4sFA73YDynmXZA6hi45en4BGhNOJUsw==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-mfiiBkxEbUHvi+v0P+TS7UnA9TeGXR48aK4XHkTj0ZwOijxexgMF01UDFaBX7Q6CQsB0d+MFNv9IiXbIHTNd4g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-n8zK1YRDGLRZfVcswcDMDM0j2xKYLNXqei217a4GyBxHIuPMGrrVuJ+Ijfpr0Kufcm7C1k/qaIrGy6eG7wvgmA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-lEEfkfsUbo0xC47eSTBqsItXDSzwzwhKUSsVaVjVji07t8+6KA5INp2rN890dHZeueXJAI8q0tEIfbwVRYf6Ew==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-jlRjsuvG1fgGwnE8Afs7xYDnGz0dBgTNZfgCK6TlvPH3Z13/P5pi6I57vyLE8qZYLrGVtwcm9UbUx1/mZ8Ukag==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-TzoU2qwVe2boOHl/3KNBUv2PNUc38U0TNnzqOAcgPiD/EZxT2s736xfC2dYQbszAwo4MKzzwBV0iHjhfjxMimg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.16.tgz";,
+      "integrity": 
"sha512-B8b7W+oo2yb/3xmwk9Vc99hC9bNolvqjaTZYEfMQhzdpBsjTvZBlXQ/teUE55Ww6sg//wlcDjOaqldOKyigWdA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-xJ7OH/nanouJO9pf03YsL9NAFQBHd8AqfrQd7Pf5laGyyTt/gToul6QYOA/i5i/q8y9iaM5DQFNTgpi995VkOg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.3",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz";,
+      "integrity": 
"sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz";,
+      "integrity": 
"sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.1.2",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz";,
+      "integrity": 
"sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.15",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz";,
+      "integrity": 
"sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+      "dev": true
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.18",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz";,
+      "integrity": 
"sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/resolve-uri": "3.1.0",
+        "@jridgewell/sourcemap-codec": "1.4.14"
+      }
+    },
+    
"node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec":
 {
+      "version": "1.4.14",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz";,
+      "integrity": 
"sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+      "dev": true
+    },
+    "node_modules/@types/prop-types": {
+      "version": "15.7.5",
+      "resolved": 
"https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz";,
+      "integrity": 
"sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
+      "dev": true
+    },
+    "node_modules/@types/react": {
+      "version": "18.0.35",
+      "resolved": 
"https://registry.npmjs.org/@types/react/-/react-18.0.35.tgz";,
+      "integrity": 
"sha512-6Laome31HpetaIUGFWl1VQ3mdSImwxtFZ39rh059a1MNnKGqBpC88J6NJ8n/Is3Qx7CefDGLgf/KhN/sYCf7ag==",
+      "dev": true,
+      "dependencies": {
+        "@types/prop-types": "*",
+        "@types/scheduler": "*",
+        "csstype": "^3.0.2"
+      }
+    },
+    "node_modules/@types/react-dom": {
+      "version": "18.0.11",
+      "resolved": 
"https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz";,
+      "integrity": 
"sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==",
+      "dev": true,
+      "dependencies": {
+        "@types/react": "*"
+      }
+    },
+    "node_modules/@types/scheduler": {
+      "version": "0.16.3",
+      "resolved": 
"https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz";,
+      "integrity": 
"sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
+      "dev": true
+    },
+    "node_modules/@vitejs/plugin-react": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz";,
+      "integrity": 
"sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.20.12",
+        "@babel/plugin-transform-react-jsx-self": "^7.18.6",
+        "@babel/plugin-transform-react-jsx-source": "^7.19.6",
+        "magic-string": "^0.27.0",
+        "react-refresh": "^0.14.0"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^4.1.0-beta.0"
+      }
+    },
+    "node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": 
"https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz";,
+      "integrity": 
"sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.21.5",
+      "resolved": 
"https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz";,
+      "integrity": 
"sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist";
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist";
+        }
+      ],
+      "dependencies": {
+        "caniuse-lite": "^1.0.30001449",
+        "electron-to-chromium": "^1.4.284",
+        "node-releases": "^2.0.8",
+        "update-browserslist-db": "^1.0.10"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001478",
+      "resolved": 
"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz";,
+      "integrity": 
"sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist";
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite";
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai";
+        }
+      ]
+    },
+    "node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz";,
+      "integrity": 
"sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": 
"https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz";,
+      "integrity": 
"sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": 
"https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz";,
+      "integrity": 
"sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "node_modules/convert-source-map": {
+      "version": "1.9.0",
+      "resolved": 
"https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz";,
+      "integrity": 
"sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+      "dev": true
+    },
+    "node_modules/csstype": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz";,
+      "integrity": 
"sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
+      "dev": true
+    },
+    "node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz";,
+      "integrity": 
"sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.4.361",
+      "resolved": 
"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.361.tgz";,
+      "integrity": 
"sha512-VocVwjPp05HUXzf3xmL0boRn5b0iyqC7amtDww84Jb1QJNPBc7F69gJyEeXRoriLBC4a5pSyckdllrXAg4mmRA==",
+      "dev": true
+    },
+    "node_modules/esbuild": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.16.tgz";,
+      "integrity": 
"sha512-aeSuUKr9aFVY9Dc8ETVELGgkj4urg5isYx8pLf4wlGgB0vTFjxJQdHnNH6Shmx4vYYrOTLCHtRI5i1XZ9l2Zcg==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.17.16",
+        "@esbuild/android-arm64": "0.17.16",
+        "@esbuild/android-x64": "0.17.16",
+        "@esbuild/darwin-arm64": "0.17.16",
+        "@esbuild/darwin-x64": "0.17.16",
+        "@esbuild/freebsd-arm64": "0.17.16",
+        "@esbuild/freebsd-x64": "0.17.16",
+        "@esbuild/linux-arm": "0.17.16",
+        "@esbuild/linux-arm64": "0.17.16",
+        "@esbuild/linux-ia32": "0.17.16",
+        "@esbuild/linux-loong64": "0.17.16",
+        "@esbuild/linux-mips64el": "0.17.16",
+        "@esbuild/linux-ppc64": "0.17.16",
+        "@esbuild/linux-riscv64": "0.17.16",
+        "@esbuild/linux-s390x": "0.17.16",
+        "@esbuild/linux-x64": "0.17.16",
+        "@esbuild/netbsd-x64": "0.17.16",
+        "@esbuild/openbsd-x64": "0.17.16",
+        "@esbuild/sunos-x64": "0.17.16",
+        "@esbuild/win32-arm64": "0.17.16",
+        "@esbuild/win32-ia32": "0.17.16",
+        "@esbuild/win32-x64": "0.17.16"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz";,
+      "integrity": 
"sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": 
"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz";,
+      "integrity": 
"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz";,
+      "integrity": 
"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": 
"https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz";,
+      "integrity": 
"sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": 
"https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz";,
+      "integrity": 
"sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz";,
+      "integrity": 
"sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz";,
+      "integrity": 
"sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz";,
+      "integrity": 
"sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.12.0",
+      "resolved": 
"https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz";,
+      "integrity": 
"sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
+      "dev": true,
+      "dependencies": {
+        "has": "^1.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb";
+      }
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz";,
+      "integrity": 
"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+    },
+    "node_modules/jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz";,
+      "integrity": 
"sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz";,
+      "integrity": 
"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true,
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": 
"https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz";,
+      "integrity": 
"sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz";,
+      "integrity": 
"sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.27.0",
+      "resolved": 
"https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz";,
+      "integrity": 
"sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.4.13"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz";,
+      "integrity": 
"sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz";,
+      "integrity": 
"sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai";
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.10",
+      "resolved": 
"https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz";,
+      "integrity": 
"sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
+      "dev": true
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": 
"https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz";,
+      "integrity": 
"sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true
+    },
+    "node_modules/picocolors": {
+      "version": "1.0.0",
+      "resolved": 
"https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz";,
+      "integrity": 
"sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "dev": true
+    },
+    "node_modules/postcss": {
+      "version": "8.4.21",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz";,
+      "integrity": 
"sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/";
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss";
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.4",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/react": {
+      "version": "18.2.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz";,
+      "integrity": 
"sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-dom": {
+      "version": "18.2.0",
+      "resolved": 
"https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz";,
+      "integrity": 
"sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+      "dependencies": {
+        "loose-envify": "^1.1.0",
+        "scheduler": "^0.23.0"
+      },
+      "peerDependencies": {
+        "react": "^18.2.0"
+      }
+    },
+    "node_modules/react-refresh": {
+      "version": "0.14.0",
+      "resolved": 
"https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz";,
+      "integrity": 
"sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/resolve": {
+      "version": "1.22.2",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz";,
+      "integrity": 
"sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.11.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb";
+      }
+    },
+    "node_modules/rollup": {
+      "version": "3.20.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz";,
+      "integrity": 
"sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==",
+      "dev": true,
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=14.18.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/scheduler": {
+      "version": "0.23.0",
+      "resolved": 
"https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz";,
+      "integrity": 
"sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      }
+    },
+    "node_modules/semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz";,
+      "integrity": 
"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.0.2",
+      "resolved": 
"https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz";,
+      "integrity": 
"sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": 
"https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz";,
+      "integrity": 
"sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": 
"https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz";,
+      "integrity": 
"sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb";
+      }
+    },
+    "node_modules/to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": 
"https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz";,
+      "integrity": 
"sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "4.9.5",
+      "resolved": 
"https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz";,
+      "integrity": 
"sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.0.10",
+      "resolved": 
"https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz";,
+      "integrity": 
"sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist";
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist";
+        }
+      ],
+      "dependencies": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      },
+      "bin": {
+        "browserslist-lint": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/vite": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz";,
+      "integrity": 
"sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==",
+      "dev": true,
+      "dependencies": {
+        "esbuild": "^0.17.5",
+        "postcss": "^8.4.21",
+        "resolve": "^1.22.1",
+        "rollup": "^3.18.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      },
+      "peerDependencies": {
+        "@types/node": ">= 14",
+        "less": "*",
+        "sass": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.4.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz";,
+      "integrity": 
"sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    }
+  },
+  "dependencies": {
+    "@ampproject/remapping": {
+      "version": "2.2.1",
+      "resolved": 
"https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz";,
+      "integrity": 
"sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+      "dev": true,
+      "requires": {
+        "@jridgewell/gen-mapping": "^0.3.0",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      }
+    },
+    "@babel/code-frame": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz";,
+      "integrity": 
"sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.18.6"
+      }
+    },
+    "@babel/compat-data": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz";,
+      "integrity": 
"sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==",
+      "dev": true
+    },
+    "@babel/core": {
+      "version": "7.21.4",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz";,
+      "integrity": 
"sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==",
+      "dev": true,
+      "requires": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.21.4",
+        "@babel/generator": "^7.21.4",
+        "@babel/helper-compilation-targets": "^7.21.4",
+        "@babel/helper-module-transforms": "^7.21.2",
+        "@babel/helpers": "^7.21.0",
+        "@babel/parser": "^7.21.4",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.4",
+        "@babel/types": "^7.21.4",
+        "convert-source-map": "^1.7.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.2",
+        "semver": "^6.3.0"
+      }
+    },
+    "@babel/generator": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz";,
+      "integrity": 
"sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.21.4",
+        "@jridgewell/gen-mapping": "^0.3.2",
+        "@jridgewell/trace-mapping": "^0.3.17",
+        "jsesc": "^2.5.1"
+      }
+    },
+    "@babel/helper-compilation-targets": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz";,
+      "integrity": 
"sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.21.4",
+        "@babel/helper-validator-option": "^7.21.0",
+        "browserslist": "^4.21.3",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.0"
+      }
+    },
+    "@babel/helper-environment-visitor": {
+      "version": "7.18.9",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz";,
+      "integrity": 
"sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+      "dev": true
+    },
+    "@babel/helper-function-name": {
+      "version": "7.21.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz";,
+      "integrity": 
"sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.20.7",
+        "@babel/types": "^7.21.0"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.18.6",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz";,
+      "integrity": 
"sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.18.6"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz";,
+      "integrity": 
"sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.21.4"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.21.2",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz";,
+      "integrity": 
"sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-module-imports": "^7.18.6",
+        "@babel/helper-simple-access": "^7.20.2",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/helper-validator-identifier": "^7.19.1",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.2",
+        "@babel/types": "^7.21.2"
+      }
+    },
+    "@babel/helper-plugin-utils": {
+      "version": "7.20.2",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz";,
+      "integrity": 
"sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+      "dev": true
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.20.2",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz";,
+      "integrity": 
"sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.20.2"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.18.6",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz";,
+      "integrity": 
"sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.18.6"
+      }
+    },
+    "@babel/helper-string-parser": {
+      "version": "7.19.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz";,
+      "integrity": 
"sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+      "dev": true
+    },
+    "@babel/helper-validator-identifier": {
+      "version": "7.19.1",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz";,
+      "integrity": 
"sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+      "dev": true
+    },
+    "@babel/helper-validator-option": {
+      "version": "7.21.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz";,
+      "integrity": 
"sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==",
+      "dev": true
+    },
+    "@babel/helpers": {
+      "version": "7.21.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz";,
+      "integrity": 
"sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.0",
+        "@babel/types": "^7.21.0"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.18.6",
+      "resolved": 
"https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz";,
+      "integrity": 
"sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.18.6",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      }
+    },
+    "@babel/parser": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz";,
+      "integrity": 
"sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==",
+      "dev": true
+    },
+    "@babel/plugin-transform-react-jsx-self": {
+      "version": "7.21.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz";,
+      "integrity": 
"sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.20.2"
+      }
+    },
+    "@babel/plugin-transform-react-jsx-source": {
+      "version": "7.19.6",
+      "resolved": 
"https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz";,
+      "integrity": 
"sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.19.0"
+      }
+    },
+    "@babel/template": {
+      "version": "7.20.7",
+      "resolved": 
"https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz";,
+      "integrity": 
"sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.18.6",
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.21.4",
+      "resolved": 
"https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz";,
+      "integrity": 
"sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.21.4",
+        "@babel/generator": "^7.21.4",
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-function-name": "^7.21.0",
+        "@babel/helper-hoist-variables": "^7.18.6",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/parser": "^7.21.4",
+        "@babel/types": "^7.21.4",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0"
+      }
+    },
+    "@babel/types": {
+      "version": "7.21.4",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz";,
+      "integrity": 
"sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-string-parser": "^7.19.4",
+        "@babel/helper-validator-identifier": "^7.19.1",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@esbuild/android-arm": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.16.tgz";,
+      "integrity": 
"sha512-baLqRpLe4JnKrUXLJChoTN0iXZH7El/mu58GE3WIA6/H834k0XWvLRmGLG8y8arTRS9hJJibPnF0tiGhmWeZgw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/android-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-QX48qmsEZW+gcHgTmAj+x21mwTz8MlYQBnzF6861cNdQGvj2jzzFjqH0EBabrIa/WVZ2CHolwMoqxVryqKt8+Q==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/android-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-G4wfHhrrz99XJgHnzFvB4UwwPxAWZaZBOFXh+JH1Duf1I4vIVfuYY9uVLpx4eiV2D/Jix8LJY+TAdZ3i40tDow==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/darwin-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-/Ofw8UXZxuzTLsNFmz1+lmarQI6ztMZ9XktvXedTbt3SNWDn0+ODTwxExLYQ/Hod91EZB4vZPQJLoqLF0jvEzA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/darwin-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-SzBQtCV3Pdc9kyizh36Ol+dNVhkDyIrGb/JXZqFq8WL37LIyrXU0gUpADcNV311sCOhvY+f2ivMhb5Tuv8nMOQ==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/freebsd-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-ZqftdfS1UlLiH1DnS2u3It7l4Bc3AskKeu+paJSfk7RNOMrOxmeFDhLTMQqMxycP1C3oj8vgkAT6xfAuq7ZPRA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/freebsd-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-rHV6zNWW1tjgsu0dKQTX9L0ByiJHHLvQKrWtnz8r0YYJI27FU3Xu48gpK2IBj1uCSYhJ+pEk6Y0Um7U3rIvV8g==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-arm": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.16.tgz";,
+      "integrity": 
"sha512-n4O8oVxbn7nl4+m+ISb0a68/lcJClIbaGAoXwqeubj/D1/oMMuaAXmJVfFlRjJLu/ZvHkxoiFJnmbfp4n8cdSw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-8yoZhGkU6aHu38WpaM4HrRLTFc7/VVD9Q2SvPcmIQIipQt2I/GMTZNdEHXoypbbGao5kggLcxg0iBKjo0SQYKA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-ia32": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.16.tgz";,
+      "integrity": 
"sha512-9ZBjlkdaVYxPNO8a7OmzDbOH9FMQ1a58j7Xb21UfRU29KcEEU3VTHk+Cvrft/BNv0gpWJMiiZ/f4w0TqSP0gLA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-loong64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.16.tgz";,
+      "integrity": 
"sha512-TIZTRojVBBzdgChY3UOG7BlPhqJz08AL7jdgeeu+kiObWMFzGnQD7BgBBkWRwOtKR1i2TNlO7YK6m4zxVjjPRQ==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-mips64el": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.16.tgz";,
+      "integrity": 
"sha512-UPeRuFKCCJYpBbIdczKyHLAIU31GEm0dZl1eMrdYeXDH+SJZh/i+2cAmD3A1Wip9pIc5Sc6Kc5cFUrPXtR0XHA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-ppc64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.16.tgz";,
+      "integrity": 
"sha512-io6yShgIEgVUhExJejJ21xvO5QtrbiSeI7vYUnr7l+v/O9t6IowyhdiYnyivX2X5ysOVHAuyHW+Wyi7DNhdw6Q==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-riscv64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.16.tgz";,
+      "integrity": 
"sha512-WhlGeAHNbSdG/I2gqX2RK2gfgSNwyJuCiFHMc8s3GNEMMHUI109+VMBfhVqRb0ZGzEeRiibi8dItR3ws3Lk+cA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-s390x": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.16.tgz";,
+      "integrity": 
"sha512-gHRReYsJtViir63bXKoFaQ4pgTyah4ruiMRQ6im9YZuv+gp3UFJkNTY4sFA73YDynmXZA6hi45en4BGhNOJUsw==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/linux-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-mfiiBkxEbUHvi+v0P+TS7UnA9TeGXR48aK4XHkTj0ZwOijxexgMF01UDFaBX7Q6CQsB0d+MFNv9IiXbIHTNd4g==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/netbsd-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-n8zK1YRDGLRZfVcswcDMDM0j2xKYLNXqei217a4GyBxHIuPMGrrVuJ+Ijfpr0Kufcm7C1k/qaIrGy6eG7wvgmA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/openbsd-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-lEEfkfsUbo0xC47eSTBqsItXDSzwzwhKUSsVaVjVji07t8+6KA5INp2rN890dHZeueXJAI8q0tEIfbwVRYf6Ew==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/sunos-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-jlRjsuvG1fgGwnE8Afs7xYDnGz0dBgTNZfgCK6TlvPH3Z13/P5pi6I57vyLE8qZYLrGVtwcm9UbUx1/mZ8Ukag==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-arm64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.16.tgz";,
+      "integrity": 
"sha512-TzoU2qwVe2boOHl/3KNBUv2PNUc38U0TNnzqOAcgPiD/EZxT2s736xfC2dYQbszAwo4MKzzwBV0iHjhfjxMimg==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-ia32": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.16.tgz";,
+      "integrity": 
"sha512-B8b7W+oo2yb/3xmwk9Vc99hC9bNolvqjaTZYEfMQhzdpBsjTvZBlXQ/teUE55Ww6sg//wlcDjOaqldOKyigWdA==",
+      "dev": true,
+      "optional": true
+    },
+    "@esbuild/win32-x64": {
+      "version": "0.17.16",
+      "resolved": 
"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.16.tgz";,
+      "integrity": 
"sha512-xJ7OH/nanouJO9pf03YsL9NAFQBHd8AqfrQd7Pf5laGyyTt/gToul6QYOA/i5i/q8y9iaM5DQFNTgpi995VkOg==",
+      "dev": true,
+      "optional": true
+    },
+    "@jridgewell/gen-mapping": {
+      "version": "0.3.3",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz";,
+      "integrity": 
"sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+      "dev": true,
+      "requires": {
+        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      }
+    },
+    "@jridgewell/resolve-uri": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz";,
+      "integrity": 
"sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+      "dev": true
+    },
+    "@jridgewell/set-array": {
+      "version": "1.1.2",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz";,
+      "integrity": 
"sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "dev": true
+    },
+    "@jridgewell/sourcemap-codec": {
+      "version": "1.4.15",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz";,
+      "integrity": 
"sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+      "dev": true
+    },
+    "@jridgewell/trace-mapping": {
+      "version": "0.3.18",
+      "resolved": 
"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz";,
+      "integrity": 
"sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
+      "dev": true,
+      "requires": {
+        "@jridgewell/resolve-uri": "3.1.0",
+        "@jridgewell/sourcemap-codec": "1.4.14"
+      },
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": {
+          "version": "1.4.14",
+          "resolved": 
"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz";,
+          "integrity": 
"sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+          "dev": true
+        }
+      }
+    },
+    "@types/prop-types": {
+      "version": "15.7.5",
+      "resolved": 
"https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz";,
+      "integrity": 
"sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
+      "dev": true
+    },
+    "@types/react": {
+      "version": "18.0.35",
+      "resolved": 
"https://registry.npmjs.org/@types/react/-/react-18.0.35.tgz";,
+      "integrity": 
"sha512-6Laome31HpetaIUGFWl1VQ3mdSImwxtFZ39rh059a1MNnKGqBpC88J6NJ8n/Is3Qx7CefDGLgf/KhN/sYCf7ag==",
+      "dev": true,
+      "requires": {
+        "@types/prop-types": "*",
+        "@types/scheduler": "*",
+        "csstype": "^3.0.2"
+      }
+    },
+    "@types/react-dom": {
+      "version": "18.0.11",
+      "resolved": 
"https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz";,
+      "integrity": 
"sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==",
+      "dev": true,
+      "requires": {
+        "@types/react": "*"
+      }
+    },
+    "@types/scheduler": {
+      "version": "0.16.3",
+      "resolved": 
"https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz";,
+      "integrity": 
"sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
+      "dev": true
+    },
+    "@vitejs/plugin-react": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz";,
+      "integrity": 
"sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.20.12",
+        "@babel/plugin-transform-react-jsx-self": "^7.18.6",
+        "@babel/plugin-transform-react-jsx-source": "^7.19.6",
+        "magic-string": "^0.27.0",
+        "react-refresh": "^0.14.0"
+      }
+    },
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": 
"https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz";,
+      "integrity": 
"sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.0"
+      }
+    },
+    "browserslist": {
+      "version": "4.21.5",
+      "resolved": 
"https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz";,
+      "integrity": 
"sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30001449",
+        "electron-to-chromium": "^1.4.284",
+        "node-releases": "^2.0.8",
+        "update-browserslist-db": "^1.0.10"
+      }
+    },
+    "caniuse-lite": {
+      "version": "1.0.30001478",
+      "resolved": 
"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001478.tgz";,
+      "integrity": 
"sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==",
+      "dev": true
+    },
+    "chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz";,
+      "integrity": 
"sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": 
"https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz";,
+      "integrity": 
"sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": 
"https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz";,
+      "integrity": 
"sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.9.0",
+      "resolved": 
"https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz";,
+      "integrity": 
"sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+      "dev": true
+    },
+    "csstype": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz";,
+      "integrity": 
"sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
+      "dev": true
+    },
+    "debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz";,
+      "integrity": 
"sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dev": true,
+      "requires": {
+        "ms": "2.1.2"
+      }
+    },
+    "electron-to-chromium": {
+      "version": "1.4.361",
+      "resolved": 
"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.361.tgz";,
+      "integrity": 
"sha512-VocVwjPp05HUXzf3xmL0boRn5b0iyqC7amtDww84Jb1QJNPBc7F69gJyEeXRoriLBC4a5pSyckdllrXAg4mmRA==",
+      "dev": true
+    },
+    "esbuild": {
+      "version": "0.17.16",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.16.tgz";,
+      "integrity": 
"sha512-aeSuUKr9aFVY9Dc8ETVELGgkj4urg5isYx8pLf4wlGgB0vTFjxJQdHnNH6Shmx4vYYrOTLCHtRI5i1XZ9l2Zcg==",
+      "dev": true,
+      "requires": {
+        "@esbuild/android-arm": "0.17.16",
+        "@esbuild/android-arm64": "0.17.16",
+        "@esbuild/android-x64": "0.17.16",
+        "@esbuild/darwin-arm64": "0.17.16",
+        "@esbuild/darwin-x64": "0.17.16",
+        "@esbuild/freebsd-arm64": "0.17.16",
+        "@esbuild/freebsd-x64": "0.17.16",
+        "@esbuild/linux-arm": "0.17.16",
+        "@esbuild/linux-arm64": "0.17.16",
+        "@esbuild/linux-ia32": "0.17.16",
+        "@esbuild/linux-loong64": "0.17.16",
+        "@esbuild/linux-mips64el": "0.17.16",
+        "@esbuild/linux-ppc64": "0.17.16",
+        "@esbuild/linux-riscv64": "0.17.16",
+        "@esbuild/linux-s390x": "0.17.16",
+        "@esbuild/linux-x64": "0.17.16",
+        "@esbuild/netbsd-x64": "0.17.16",
+        "@esbuild/openbsd-x64": "0.17.16",
+        "@esbuild/sunos-x64": "0.17.16",
+        "@esbuild/win32-arm64": "0.17.16",
+        "@esbuild/win32-ia32": "0.17.16",
+        "@esbuild/win32-x64": "0.17.16"
+      }
+    },
+    "escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz";,
+      "integrity": 
"sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": 
"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz";,
+      "integrity": 
"sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz";,
+      "integrity": 
"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": 
"https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz";,
+      "integrity": 
"sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": 
"https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz";,
+      "integrity": 
"sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true
+    },
+    "globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz";,
+      "integrity": 
"sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz";,
+      "integrity": 
"sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz";,
+      "integrity": 
"sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true
+    },
+    "is-core-module": {
+      "version": "2.12.0",
+      "resolved": 
"https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz";,
+      "integrity": 
"sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
+    "js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz";,
+      "integrity": 
"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+    },
+    "jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz";,
+      "integrity": 
"sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "dev": true
+    },
+    "json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz";,
+      "integrity": 
"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true
+    },
+    "loose-envify": {
+      "version": "1.4.0",
+      "resolved": 
"https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz";,
+      "integrity": 
"sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "requires": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      }
+    },
+    "lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz";,
+      "integrity": 
"sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "requires": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "magic-string": {
+      "version": "0.27.0",
+      "resolved": 
"https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz";,
+      "integrity": 
"sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+      "dev": true,
+      "requires": {
+        "@jridgewell/sourcemap-codec": "^1.4.13"
+      }
+    },
+    "ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz";,
+      "integrity": 
"sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
+    "nanoid": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz";,
+      "integrity": 
"sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+      "dev": true
+    },
+    "node-releases": {
+      "version": "2.0.10",
+      "resolved": 
"https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz";,
+      "integrity": 
"sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.7",
+      "resolved": 
"https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz";,
+      "integrity": 
"sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true
+    },
+    "picocolors": {
+      "version": "1.0.0",
+      "resolved": 
"https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz";,
+      "integrity": 
"sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "dev": true
+    },
+    "postcss": {
+      "version": "8.4.21",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz";,
+      "integrity": 
"sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
+      "dev": true,
+      "requires": {
+        "nanoid": "^3.3.4",
+        "picocolors": "^1.0.0",
+        "source-map-js": "^1.0.2"
+      }
+    },
+    "react": {
+      "version": "18.2.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz";,
+      "integrity": 
"sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+      "requires": {
+        "loose-envify": "^1.1.0"
+      }
+    },
+    "react-dom": {
+      "version": "18.2.0",
+      "resolved": 
"https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz";,
+      "integrity": 
"sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+      "requires": {
+        "loose-envify": "^1.1.0",
+        "scheduler": "^0.23.0"
+      }
+    },
+    "react-refresh": {
+      "version": "0.14.0",
+      "resolved": 
"https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz";,
+      "integrity": 
"sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
+      "dev": true
+    },
+    "resolve": {
+      "version": "1.22.2",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz";,
+      "integrity": 
"sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
+      "dev": true,
+      "requires": {
+        "is-core-module": "^2.11.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      }
+    },
+    "rollup": {
+      "version": "3.20.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz";,
+      "integrity": 
"sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==",
+      "dev": true,
+      "requires": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "scheduler": {
+      "version": "0.23.0",
+      "resolved": 
"https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz";,
+      "integrity": 
"sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+      "requires": {
+        "loose-envify": "^1.1.0"
+      }
+    },
+    "semver": {
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz";,
+      "integrity": 
"sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+      "dev": true
+    },
+    "source-map-js": {
+      "version": "1.0.2",
+      "resolved": 
"https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz";,
+      "integrity": 
"sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+      "dev": true
+    },
+    "supports-color": {
+      "version": "5.5.0",
+      "resolved": 
"https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz";,
+      "integrity": 
"sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "requires": {
+        "has-flag": "^3.0.0"
+      }
+    },
+    "supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": 
"https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz";,
+      "integrity": 
"sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true
+    },
+    "to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": 
"https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz";,
+      "integrity": 
"sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+      "dev": true
+    },
+    "typescript": {
+      "version": "4.9.5",
+      "resolved": 
"https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz";,
+      "integrity": 
"sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+      "dev": true
+    },
+    "update-browserslist-db": {
+      "version": "1.0.10",
+      "resolved": 
"https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz";,
+      "integrity": 
"sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+      "dev": true,
+      "requires": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      }
+    },
+    "vite": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz";,
+      "integrity": 
"sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==",
+      "dev": true,
+      "requires": {
+        "esbuild": "^0.17.5",
+        "fsevents": "~2.3.2",
+        "postcss": "^8.4.21",
+        "resolve": "^1.22.1",
+        "rollup": "^3.18.0"
+      }
+    },
+    "yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz";,
+      "integrity": 
"sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    }
+  }
+}
diff --git a/example/vite-react-app/package.json 
b/example/vite-react-app/package.json
new file mode 100644
index 000000000..2f28da946
--- /dev/null
+++ b/example/vite-react-app/package.json
@@ -0,0 +1,22 @@
+{
+  "name": "vite-react-app",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "tsc && vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "react": "^18.2.0",
+    "react-dom": "^18.2.0"
+  },
+  "devDependencies": {
+    "@types/react": "^18.0.28",
+    "@types/react-dom": "^18.0.11",
+    "@vitejs/plugin-react": "^3.1.0",
+    "typescript": "^4.9.3",
+    "vite": "^4.2.0"
+  }
+}
diff --git a/example/vite-react-app/public/vite.svg 
b/example/vite-react-app/public/vite.svg
new file mode 100644
index 000000000..e7b8dfb1b
--- /dev/null
+++ b/example/vite-react-app/public/vite.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; aria-hidden="true" role="img" 
class="iconify iconify--logos" width="31.88" height="32" 
preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient 
id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" 
y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" 
stop-color="#BD34FE"></stop></linearGradient><linearGradient 
id="IconifyId1813088fe1fbc01fb [...]
\ No newline at end of file
diff --git a/example/vite-react-app/src/App.css 
b/example/vite-react-app/src/App.css
new file mode 100644
index 000000000..b9d355df2
--- /dev/null
+++ b/example/vite-react-app/src/App.css
@@ -0,0 +1,42 @@
+#root {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 2rem;
+  text-align: center;
+}
+
+.logo {
+  height: 6em;
+  padding: 1.5em;
+  will-change: filter;
+  transition: filter 300ms;
+}
+.logo:hover {
+  filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.react:hover {
+  filter: drop-shadow(0 0 2em #61dafbaa);
+}
+
+@keyframes logo-spin {
+  from {
+    transform: rotate(0deg);
+  }
+  to {
+    transform: rotate(360deg);
+  }
+}
+
+@media (prefers-reduced-motion: no-preference) {
+  a:nth-of-type(2) .logo {
+    animation: logo-spin infinite 20s linear;
+  }
+}
+
+.card {
+  padding: 2em;
+}
+
+.read-the-docs {
+  color: #888;
+}
diff --git a/example/vite-react-app/src/App.tsx 
b/example/vite-react-app/src/App.tsx
new file mode 100644
index 000000000..7182e2bf8
--- /dev/null
+++ b/example/vite-react-app/src/App.tsx
@@ -0,0 +1,36 @@
+import { useState } from 'react'
+import reactLogo from './assets/react.svg'
+import viteLogo from '/vite.svg'
+import './App.css'
+
+function App() {
+  const [count, setCount] = useState(0)
+
+  return (
+    <div className="App">
+      <div>
+        <a href="https://vitejs.dev"; target="_blank">
+          <img src={viteLogo} className="logo" alt="Vite logo" />
+        </a>
+        <a href="https://reactjs.org"; target="_blank">
+          <img src={reactLogo} className="logo react" alt="React logo" />
+        </a>
+      </div>
+      <h1>Vite + React</h1>
+      <div className="card">
+        <p>Click this button to see the counter increment</p>
+        <button onClick={() => setCount((count) => count + 1)}>
+          count is {count}
+        </button>
+        <p>
+          Edit <code>src/App.tsx</code> and save to test HMR
+        </p>
+      </div>
+      <p className="read-the-docs">
+        Click on the Vite and React logos to learn more
+      </p>
+    </div>
+  )
+}
+
+export default App
diff --git a/example/vite-react-app/src/assets/react.svg 
b/example/vite-react-app/src/assets/react.svg
new file mode 100644
index 000000000..6c87de9bb
--- /dev/null
+++ b/example/vite-react-app/src/assets/react.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; aria-hidden="true" role="img" 
class="iconify iconify--logos" width="35.93" height="32" 
preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" 
d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 
1.273-5.621c6.238-30.281 
2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 
0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587 [...]
\ No newline at end of file
diff --git a/example/vite-react-app/src/index.css 
b/example/vite-react-app/src/index.css
new file mode 100644
index 000000000..e69de29bb
diff --git a/example/vite-react-app/src/main.tsx 
b/example/vite-react-app/src/main.tsx
new file mode 100644
index 000000000..141eee2d5
--- /dev/null
+++ b/example/vite-react-app/src/main.tsx
@@ -0,0 +1,10 @@
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import App from './App'
+import './index.css'
+
+ReactDOM.createRoot(document.getElementById('ReactExamplesRootContainer') as 
HTMLElement).render(
+  <React.StrictMode>
+    <App />
+  </React.StrictMode>,
+)
diff --git a/example/vite-react-app/src/vite-env.d.ts 
b/example/vite-react-app/src/vite-env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/example/vite-react-app/src/vite-env.d.ts
@@ -0,0 +1 @@
+/// <reference types="vite/client" />
diff --git a/example/vite-react-app/tsconfig.json 
b/example/vite-react-app/tsconfig.json
new file mode 100644
index 000000000..3d0a51a86
--- /dev/null
+++ b/example/vite-react-app/tsconfig.json
@@ -0,0 +1,21 @@
+{
+  "compilerOptions": {
+    "target": "ESNext",
+    "useDefineForClassFields": true,
+    "lib": ["DOM", "DOM.Iterable", "ESNext"],
+    "allowJs": false,
+    "skipLibCheck": true,
+    "esModuleInterop": false,
+    "allowSyntheticDefaultImports": true,
+    "strict": true,
+    "forceConsistentCasingInFileNames": true,
+    "module": "ESNext",
+    "moduleResolution": "Node",
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "noEmit": true,
+    "jsx": "react-jsx"
+  },
+  "include": ["src"],
+  "references": [{ "path": "./tsconfig.node.json" }]
+}
diff --git a/example/vite-react-app/tsconfig.node.json 
b/example/vite-react-app/tsconfig.node.json
new file mode 100644
index 000000000..9d31e2aed
--- /dev/null
+++ b/example/vite-react-app/tsconfig.node.json
@@ -0,0 +1,9 @@
+{
+  "compilerOptions": {
+    "composite": true,
+    "module": "ESNext",
+    "moduleResolution": "Node",
+    "allowSyntheticDefaultImports": true
+  },
+  "include": ["vite.config.ts"]
+}
diff --git a/example/vite-react-app/vite.config.ts 
b/example/vite-react-app/vite.config.ts
new file mode 100644
index 000000000..f44269b96
--- /dev/null
+++ b/example/vite-react-app/vite.config.ts
@@ -0,0 +1,12 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+    plugins: [react()],
+    base: '/example/vite-react-app/',
+    build: {
+        manifest: true,
+        outDir: '../webapp/example/vite-react-app',
+    },
+})
diff --git a/example/webapp/example/WEB-INF/controller.xml 
b/example/webapp/example/WEB-INF/controller.xml
index bfbb282ba..646484d1f 100644
--- a/example/webapp/example/WEB-INF/controller.xml
+++ b/example/webapp/example/WEB-INF/controller.xml
@@ -239,7 +239,13 @@ under the License.
         <security https="true" auth="true"/>
         <response name="success" type="view" value="ExampleReportPdfBarcode"/>
     </request-map>
-    
+
+    <!-- React example requests -->
+    <request-map uri="ReactExample">
+        <security https="true" auth="true"/>
+        <response name="success" type="view" value="ExampleReact"/>
+    </request-map>
+
     <!-- end of request mappings -->
 
     <!-- View Mappings -->
@@ -305,5 +311,9 @@ under the License.
      -->
 
     <view-map name="ExampleReportPdfOptions" type="screen" 
page="component://example/widget/example/ExampleScreens.xml#ExampleReportPdfOptions"/>
+
+    <!-- React view mapping -->
+    <view-map name="ExampleReact" type="screen" 
page="component://example/widget/example/ExampleReactScreens.xml#ReactExample"/>
+
     <!-- end of view mappings -->
 </site-conf>
diff --git a/example/webapp/example/WEB-INF/web.xml 
b/example/webapp/example/WEB-INF/web.xml
index a015cb924..c5ebc4801 100644
--- a/example/webapp/example/WEB-INF/web.xml
+++ b/example/webapp/example/WEB-INF/web.xml
@@ -48,7 +48,7 @@ under the License.
         
<filter-class>org.apache.ofbiz.webapp.control.ControlFilter</filter-class>
         <init-param>
             <param-name>allowedPaths</param-name>
-            
<param-value>/error:/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images:/js:/ws</param-value>
+            
<param-value>/error:/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images:/js:/ws:/vite-react-app</param-value>
         </init-param>
         <init-param>
             <param-name>redirectPath</param-name>
diff --git a/example/widget/example/CommonScreens.xml 
b/example/widget/example/CommonScreens.xml
index c9662541c..a7d1613ce 100644
--- a/example/widget/example/CommonScreens.xml
+++ b/example/widget/example/CommonScreens.xml
@@ -59,6 +59,26 @@ under the License.
         </section>
     </screen>
 
+    <screen name="example-react-decorator">
+        <section>
+
+            <widgets>
+                <section>
+                    <condition>
+                        <if-has-permission permission="EXAMPLE" 
action="_VIEW"/>
+                    </condition>
+                    <actions>
+                        <script 
location="component://example/groovyScripts/LoadReactApp.groovy"/>
+                        <set field="layoutSettings.styleSheets[]" 
value="${reactAppStylesheetUrlPath}" global="true"/>
+                    </actions>
+                </section>
+
+                <include-screen name="main-decorator" />
+
+            </widgets>
+        </section>
+    </screen>
+
     <screen name="CommonExampleDecorator">
         <!-- The CommonExampleDecorator screen decorates a small group of 
screens that all have
             something in common. It is decorated by the main-decorator screen. 
To see how the
diff --git a/example/widget/example/ExampleMenus.xml 
b/example/widget/example/ExampleMenus.xml
index ba9a29451..f6924a666 100644
--- a/example/widget/example/ExampleMenus.xml
+++ b/example/widget/example/ExampleMenus.xml
@@ -51,6 +51,9 @@ under the License.
         <menu-item name="ExampleCompoundWidgets" 
title="${uiLabelMap.ExampleCompoundWidgets}">
                 <link target="CompoundWidgets1"/>
         </menu-item>
+        <menu-item name="ExampleReact" 
title="${uiLabelMap.ExampleReactExamples}">
+                <link target="ReactExample"/>
+        </menu-item>
     </menu>
 
     <menu name="EditExample" extends="CommonTabBarMenu" 
extends-resource="component://common/widget/CommonMenus.xml">
diff --git a/example/widget/example/ExampleReactScreens.xml 
b/example/widget/example/ExampleReactScreens.xml
new file mode 100644
index 000000000..1ed91209b
--- /dev/null
+++ b/example/widget/example/ExampleReactScreens.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xmlns="http://ofbiz.apache.org/Widget-Screen";
+         xsi:schemaLocation="http://ofbiz.apache.org/Widget-Screen 
http://ofbiz.apache.org/dtds/widget-screen.xsd";>
+
+    <screen name="ReactExample">
+        <section>
+            <actions>
+                <set field="headerItem" value="ReactExample"/>
+                <set field="titleProperty" value="ExampleReactExamples"/>
+            </actions>
+            <widgets>
+                <decorator-screen name="example-react-decorator" 
location="${parameters.mainDecoratorLocation}">
+                    <decorator-section name="body">
+                        <section>
+                            <condition>
+                                <if-has-permission permission="EXAMPLE" 
action="_VIEW"/>
+                            </condition>
+                            <widgets>
+                                <!-- NOTE: this is the main container for the 
React app. The ID should be unique within the page. -->
+                                <container id="ReactExamplesRootContainer"/>
+                            </widgets>
+                            <fail-widgets>
+                                <label 
style="h3">${uiLabelMap.ExampleViewPermissionError}</label>
+                            </fail-widgets>
+                        </section>
+                    </decorator-section>
+                </decorator-screen>
+            </widgets>
+        </section>
+    </screen>
+</screens>

Reply via email to