diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 59eedbe37..000000000
--- a/.babelrc
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "presets": [
- "airbnb"
- ],
- "plugins": ["@emotion"]
-}
diff --git a/.eslintrc b/.eslintrc
index 4c9480e25..7cc3223f3 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,11 +1,13 @@
{
"extends": [
- "airbnb",
"plugin:jest/recommended",
"plugin:@typescript-eslint/eslint-recommended",
- "plugin:@typescript-eslint/recommended"],
+ "plugin:@typescript-eslint/recommended",
+ "plugin:testing-library/react", // added in for RTL tests
+ "plugin:jest-dom/recommended" // added in for RTL tests
+ ],
"root": true,
- "plugins": ["jest", "react", "react-hooks", "@typescript-eslint"],
+ "plugins": ["jest", "react", "react-hooks", "@typescript-eslint", "testing-library", "jest-dom"],
"rules": {
"arrow-parens": [2, "as-needed"],
"import/no-unresolved": "off",
@@ -13,7 +15,8 @@
"react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
"react-hooks/exhaustive-deps": "warn", // Checks effect dependencies
"react/jsx-filename-extension": [0],
- "linebreak-style": "off"
+ "linebreak-style": "off",
+ "max-len": [{ "ignoreComments": true }]
},
"env": {
"es6": true,
@@ -33,4 +36,4 @@
"ecmaVersion": 2018,
"sourceType": "module"
}
-}
\ No newline at end of file
+}
diff --git a/.gitignore b/.gitignore
index 8a12d473a..aa3509cac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,6 @@ node_modules/
.DS_Store
src/extension/build/bundles
package/reactime-*.tgz
-tictactoe
parents
coverage
src/extension/build.zip
@@ -14,5 +13,7 @@ src/extension/build.pem
bower_components
sandboxes/manual-tests/NextJS/.next
.vscode
-src/app/components/Map.tsx
-package-lock.json
\ No newline at end of file
+package-lock.json
+yarn.lock
+docs/**/*
+docs/*
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index 017884ddd..2fc98bd91 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "tests/manual-tests/recoilTest"]
- path = tests/manual-tests/recoilTest
- url = https://github.com/kevinfey/recoilTest
+[submodule "reactime-website"]
+ path = reactime-website
+ url = https://github.com/reactimetravel/reactime-website
diff --git a/.npmcheckrc b/.npmcheckrc
new file mode 100644
index 000000000..297d19125
--- /dev/null
+++ b/.npmcheckrc
@@ -0,0 +1,10 @@
+{"depcheck":
+ {
+ "ignoreMatches": [
+ "css-loader",
+ "sass-loader",
+ "style-loader",
+ "typedoc-webpack-plugin"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 000000000..9bdd4961d
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,9 @@
+{
+ "printWidth": 100,
+ "semi": true,
+ "singleQuote": true,
+ "jsxSingleQuote": true,
+ "tabWidth": 2,
+ "bracketSpacing": true,
+ "trailingComma": "all"
+}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c31d41d9f..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-language: node_js
-node_js:
- - 12
-dist: trusty
-cache: npm
-git:
- submodules: false
-# branches:
-# only:
-# - implementtravisci
-install:
- - npm install
-script:
- - npm run test
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c7a20ad96..d63679ccb 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,70 +1,107 @@
-# Welcome to the Reactime contributing guide!
+# Contributing to Reactime :sparkles:
-Thank you for investing your time in contributing to our project! :sparkles:.
+Thank you for your interest in making Reactime even better! :heart_eyes: Your help is invaluable, and we appreciate every contribution, big or small. This guide will walk you through the process of opening issues, creating pull requests, and navigating our workflow.
-In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR.
+## New Contributor Guide :hatching_chick:
-## New contributor guide
+Whether you’re brand new to open source or a seasoned pro, we encourage you to:
-To get an overview of the project, read the [README](README.md). Here are some resources to help you get started with open source contributions:
+- **Check out our [README](README.md).**
+ It’ll give you a birds-eye view of what Reactime does and how you can get involved.
+- **Explore these helpful resources:**
+ - [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github)
+ - [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git)
+ - [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow)
+ - [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests)
-- [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github)
-- [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git)
-- [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow)
-- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests)
+## Getting Started :rocket:
+If you want to understand the codebase in more detail, take a look at our [Developer Guidelines](src/DEVELOPER_README.md). :confetti_ball:
-## Getting started
+### Issues :eyes:
-To navigate our codebase with confidence, see the Developer READMEs [Developer Installation](/DeveloperREADME.md) and [Developer Guidelines](/src/README.md) :confetti_ball:.
+#### Creating a New Issue :new:
-### Issues
+1. **Check existing issues.**
+ Before opening a new issue, please [search if it already exists](https://github.com/open-source-labs/reactime/issues).
-#### Create a new issue
+2. **Open your own issue.**
+ If you can’t find an existing issue, feel free to [open a new one](https://github.com/open-source-labs/reactime/issues/new) to report bugs, request features, or suggest improvements.
-If you spot a problem with the docs, [search if an issue already exists](https://github.com/open-source-labs/reactime/issues). If a related issue doesn't exist, you can open a new issue using a relevant [issue form](https://github.com/open-source-labs/reactime/issues/new).
+#### Solving an Issue :wrench:
-#### Solve an issue
+1. **Pick an issue.**
+ Browse through our [open issues](https://github.com/open-source-labs/reactime/issues). We don’t officially assign them, so if something sparks your interest, go for it!
-Scan through our [existing issues](https://github.com/open-source-labs/reactime/issues) to find one that interests you. As a general rule, we don’t assign issues to anyone. If you find an issue to work on, you are welcome to open a PR with a fix.
+2. **Open a pull request.**
+ Once you’re ready to propose a fix or feature, you can open a PR referencing the issue you’re solving.
-### Make Changes
+### Make Changes :rainbow:
-#### Make changes in the UI
+#### Small Edits in the UI :pencil2:
-Click **Make a contribution** at the bottom of any docs page to make small changes such as a typo, sentence fix, or a broken link. This takes you to the `.md` file where you can make your changes and [create a pull request](#pull-request) for a review.
+- Click **Make a contribution** at the bottom of any documentation page to quickly fix typos, broken links, or small wording changes.
+- This will take you directly to the `.md` file, where you can make edits and open a pull request.
-#### Make changes locally
+#### Larger Changes Locally :computer:
-1. [Install Git LFS](https://docs.github.com/en/github/managing-large-files/versioning-large-files/installing-git-large-file-storage).
+1. **Install Git LFS.**
+ Follow the instructions [here](https://docs.github.com/en/github/managing-large-files/versioning-large-files/installing-git-large-file-storage).
-2. Fork the repository.
-- Using GitHub Desktop:
- - [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) will guide you through setting up Desktop.
- - Once Desktop is set up, you can use it to [fork the repo](https://github.com/open-source-labs/reactime.git)!
+2. **Fork the Repository.**
-- Using the command line:
- - [Fork the repo](https://github.com/open-source-labs/reactime.git) so that you can make your changes without affecting the original project until you're ready to merge them.
+ - **GitHub Desktop:**
+ [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) walks you through setup. Then, you can [fork the repo](https://github.com/open-source-labs/reactime.git) right from GitHub Desktop!
+ - **Command Line:**
+ [Fork the repo](https://github.com/open-source-labs/reactime.git) and clone your fork locally so you can work on your own copy.
-3. Create a working branch and start with your changes!
+3. **Create a working branch.**
+ Name it something descriptive (e.g., `feature/new-feature` or `fix/typo-in-docs`).
-### Commit your update
+### Commit Your Changes :white_check_mark:
-Commit the changes once you are happy with them.
+When you’re happy with your updates:
-### Pull Request
+1. **Commit them locally.**
+ Write clear commit messages describing _what_ you changed and _why_.
-When you're finished with the changes, create a pull request, also known as a PR.
-- Fill the "Ready for review" template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request.
-- Don't forget to [link PR to issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one.
-- Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge.
-Once you submit your PR, a Docs team member will review your proposal. We may ask questions or request additional information.
-- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
-- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations).
-- If you run into any merge issues, checkout this [git tutorial](https://github.com/skills/resolve-merge-conflicts) to help you resolve merge conflicts and other issues.
+2. **Push to your branch.**
+ This makes your changes visible on GitHub.
-### Your PR is merged!
+### Open a Pull Request :arrows_counterclockwise:
-Congratulations :tada::tada: The Reactime team thanks you! :sparkles:.
+Once you’ve finished working and pushed your code:
-Once your PR is merged, your contributions will be publicly visible on [Reactime](https://github.com/open-source-labs/reactime)!
+1. **Create the PR.**
+ Click on **Compare & pull request** on your branch to open a new PR.
+
+2. **Fill the “Ready for review” template.**
+ This helps reviewers quickly understand the context and purpose of your changes.
+
+3. **Link Issues.**
+ If your PR fixes or relates to an existing issue, [link it](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) in the PR description.
+
+4. **Allow Maintainer Edits.**
+ Check the box so our team can help update your branch if needed.
+
+5. **Address Feedback.**
+ If reviewers suggest changes, you can:
+
+ - Apply **suggested changes** directly on the GitHub UI.
+ - Make edits in your local branch and push them.
+
+6. **Resolve Conversations.**
+ Mark each PR comment as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations) once you’ve addressed it.
+
+7. **Handle Merge Conflicts.**
+ Check out [this tutorial](https://github.com/skills/resolve-merge-conflicts) if you get stuck.
+
+## Your PR is Merged! :tada:
+
+**Congratulations and thank you!** :dancer: :dancer: Once we merge your PR, your contributions become part of Reactime. We appreciate every contribution, and we hope you’ll stick around for more.
+
+> If you have any further questions or ideas, don’t hesitate to open another issue or join the conversation in the repo!
+
+---
+
+Happy coding and welcome to the Reactime community! :sparkles:
diff --git a/DeveloperREADME.md b/DeveloperREADME.md
deleted file mode 100644
index d6d824ea2..000000000
--- a/DeveloperREADME.md
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
Development Enviroment Setup
-
-
Getting Started
-
-1.
Download React Dev Tools from the Chrome Webstore Here
-
-2. Clone down the Reactime repo onto your machine.
-
-```
-git clone https://github.com/open-source-labs/reactime.git
-```
-
-3. Install dependencies and build.
-
-```
-cd reactime
-npm install --force
-npm run build
-```
-
With release of Node v18.12.1 (LTS) on 11/4/22, the script has been updated to 'npm run dev' || 'npm run build' for backwards compatibility.
-For version Node v16.16.0, please use script 'npm run devlegacy' || 'npm run buildlegacy'
-
-4. Spin up the demo application.
-
-```
-cd demo-app
-npm install
-npm start
-```
-
-5. Add Reactime to your Chrome extensions.
-
-- Navigate to chrome://extensions
-- Select “Load Unpacked”
-- Choose reactime > src > extension > build
-- Navigate to http://localhost:8080/ to inspect the demo application using Reactime!
-
-
-
-
-
-
-
Documentation for Consideration
-
Can Reactime be integrated with Redux compatibility so applications using Redux can track state in Reactime?
-Yes, but it would be very time-consuming and not the most feasible option while Redux devtools exists already. With how Redux devtools is currently set up, a developer is unable to use Redux devtools as a third-party user and integrate its functionality into their own application, as Redux devtools is meant to be used directly on an application using Redux for state-tracking purposes. Since the devtools do not appear to have a public API for integrated use in an application or it simply does not exist, Redux devtools would need to be rebuilt from the ground up and then integrated into Reactime, or built into Reactime directly still from scratch.
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index b5872bcd3..000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-FROM node:10.16.2
-WORKDIR /usr/src/app
-COPY package*.json ./
-RUN npm i
diff --git a/LICENSE b/LICENSE
index d19ddaf80..498003dd9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019 reactime
+Copyright (c) 2025 reactime
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.fr.md b/README.fr.md
index 4104075ea..86ac9d8e2 100644
--- a/README.fr.md
+++ b/README.fr.md
@@ -1,140 +1,289 @@
+
-
Reactime est un outil de performance et de débogage pour les développeurs React. Reactime enregistre un snapshot à chaque fois que l'état d'une application cible est modifié et permet à l'utilisateur de passer à tout état précédemment enregistré.
-
+
Une puissante extension Chrome qui améliore le développement React grâce au débogage avec retour dans le temps et à la surveillance avancée des performances
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+##
✨ Fonctionnalités Clés
+
+### 🔍 Visualisation de l'État
+
+- **Vues Multiples** : Visualisez l’état de votre application via des Graphiques de Composants, des Arborescences JSON, des Graphiques de Performances et des Arbres d’Accessibilité
+- **Historique Chronologique** : Suivez l’évolution de l’état dans le temps grâce à une représentation intuitive de l’historique
+- **Métriques Web** : Surveillez en temps réel les métriques de performance essentielles
+- **Aperçus d’Accessibilité** : Analysez l’arbre d’accessibilité de votre application pour chaque changement d’état
+
+
+
Sur la page principale, vous disposez de deux choix principaux depuis le menu déroulant :
+
+- **Timejump** : Consultez et naviguez dans l’historique des snapshots de l’état de votre application. Vous pouvez revenir à n’importe quel point dans le temps pour observer l’évolution de l’état au fil des modifications. Vous pouvez également utiliser le bouton de lecture pour rejouer chaque changement d’état automatiquement.
+- **Providers / Consumers** : Comprenez mieux les dépendances de contexte de votre application et leurs interactions grâce à une visualisation des relations entre fournisseurs et consommateurs.
+
+
+
+
+
+
+
+### ⏱️ Débogage avec Retour dans le Temps
+
+- **Snapshots d’État** : Capturez et naviguez à travers l’historique d’état de votre application
+- **Commandes de Lecture** : Rejouez automatiquement les changements d’état avec une vitesse ajustable
+- **Points de Saut** : Naviguez instantanément vers n’importe quel état antérieur
+- **Comparaisons Diff** : Comparez l’état entre différents snapshots
+
+
+
+
+
+
+### 📊 Analyse de Performance
+
+- **Métriques de Composants** : Mesurez les temps de rendu et identifiez les goulets d’étranglement
+- **Comparaison de Séries** : Comparez les performances sur différentes séries de changements d’état
+- **Détection de Re-rendu** : Identifiez et corrigez les rendus inutiles
+- **Web Vitals** : Surveillez les Core Web Vitals et d’autres métriques de performance
+
+
+
+### 🔄 Prise en Charge des Frameworks Modernes
+
+
+
+ Compatibilité complète avec Gatsby, Next.js et Remix
+
+
+Prise en charge de TypeScript pour les composants de classe et fonctionnels
+
+
+Prise en charge des Hooks et de l’API Context de React
+
+
+
+
+### 💾 Persistance & Partage d’État
+
+Reactime facilite la sauvegarde et le partage de l’historique d’état de votre application :
+
+- **Exporter l’Historique d’État** : Enregistrez vos snapshots sous forme de fichier JSON pour une analyse ultérieure ou pour les partager
+- **Importer des Sessions Précédentes** : Chargez des snapshots enregistrés précédemment pour comparer les changements d’état entre différentes sessions
+- **Analyse Inter-Session** : Comparez les performances et les changements d’état entre différentes sessions de développement
+
- Manuel • Caractéristiques • Website • En savoir plus
+
+
+
+### 📚 Documentation Interactive
+
+Reactime propose une documentation complète pour aider les développeurs à comprendre son architecture et ses APIs.
+Après avoir cloné ce référentiel, les développeurs peuvent simplement exécuter `npm run docs` à la racine et servir le fichier `/docs/index.html` généré dynamiquement, offrant :
+
+
+
+ Des diagrammes interactifs de composants
+
+
+Des définitions de types et interfaces
+
+
+Une vue d’ensemble de l’architecture du code
+
+
+Des références d’API et des exemples
+
+
+
+
+
🎉 Nouveautés !
+
+La version 26.0 de Reactime propose une refonte complète de l’expérience de débogage React, avec :
+
+- **Nouvelle Visualisation des Données de Contexte**
+
+ - Première visualisation des changements d’état du hook useContext
+ - Cartographie claire des relations fournisseur-consommateur
+ - Surveillance en temps réel de la valeur d’état du contexte
+ - Visualisation détaillée des données du fournisseur
+
+- **Débogage avec Retour dans le Temps Amélioré**
-Actuellement, Reactime est compatible avec les applications React qui utilisent des composants à état (stateful) et Hooks, avec un support en version bêta de Recoil et de pour le Context API.
+ - Interface du curseur de temps repensée, positionnée à côté des snapshots
+ - Contrôles de vitesse de lecture variables
+ - Navigation plus intuitive dans l’état
+ - Visualisation de snapshot améliorée
-
Reactime version 7.0 beta peut vous aider à éviter les ré-rendus inutiles. Identifier les rendus inutiles dans vos applications React est le point de départ idéal pour identifier la plupart des problèmes de performances.
-La version beta 7.0 de Reactime corrige les bugs des anciennes versions et intègre des visualisations améliorées pour les relations entre les composants.
-Reactime 7.0 inclut également une documentation [typedoc](https://typedoc.org/api/) plus approfondie pour les développeurs souhaitant contribuer au code source.
+- **Refonte Complète de l’UI Moderne**
-Après avoir installé Reactime, vous pouvez tester ses fonctionnalités avec votre application React en mode développement.
+ - Design élégant et contemporain avec composants arrondis
+ - Améliorations de la disposition pour une meilleure intuitivité
+ - Nouveau mode sombre
+ - Hiérarchie visuelle améliorée
-Veuillez noter que la fonction de saut de temps fonctionnera UNIQUEMENT lorsque votre application s'exécute en mode développement. En mode production, vous pouvez afficher la carte des composants de votre application, mais aucune fonctionnalité supplémentaire.
+- **Améliorations Techniques Majeures**
+ - Correction de la persistance de connexion lors de périodes d’inactivité et de changements d’onglet
+ - Restauration de la visualisation de l’arbre d’accessibilité
+ - Résolution de problèmes de capture d’état pour les hooks useState basés sur des fonctions
+ - Fiabilité et performance globales de l’extension grandement améliorées
-##
Installation
+Ces mises à jour rendent Reactime plus puissant, plus fiable et plus convivial que jamais, établissant un nouveau standard pour les outils de débogage React.
-Pour commencer, installer l’[extension](https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga) Reactime depuis le Chrome Web Store.
+Pour en savoir plus sur les versions précédentes, cliquez
ici !
+
+
+
+
🚀 Bien Commencer
+
+### Installation
+
+1. Installez l’[extension Reactime](https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga) depuis le Chrome Web Store
+2. Installez l’extension requise [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) si vous ne l’avez pas déjà
+
+### Prérequis
+
+- Votre application React doit fonctionner en **mode développement**
+- L’extension React Developer Tools doit être installée
+- Navigateur Chrome (version 80 ou supérieure recommandée)
-REMARQUE: L'[extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) React Developer Tools est également requise pour que Reactime s'exécute, si vous ne l'avez pas déjà installé sur votre navigateur.
+### Lancer Reactime
-###
Installation Alternative
+Il existe deux manières d’ouvrir le panneau Reactime :
-Utilisez `src/extension/build/build.zip` pour une installation manuelle en [mode Développeur](https://developer.chrome.com/extensions/faq#faq-dev-01). Activez "Autoriser l'accès aux URL de fichiers" dans la page des détails de l'extension si vous effectuez un test local.
+1. **Menu Contextuel**
-##
Manuel
+ - Faites un clic droit n’importe où dans votre application React
+ - Sélectionnez "Reactime" dans le menu contextuel
-Après avoir installé l’extension Chrome Reactime, ouvrez votre application dans le navigateur.
+2. **DevTools**
+ - Ouvrez les DevTools de Chrome (F12 ou ⌘+⌥+I)
+ - Naviguez jusqu’à l’onglet "Reactime"
-Ensuite, ouvrez vos Chrome DevTools et accédez au panneau Reactime.
+Une fois lancé, Reactime commencera automatiquement à surveiller les changements d’état et les métriques de performance de votre application.
+
+
-##
Diagnostic des anomalies
+
🤝 Contribuer à Reactime
-###
Que faire quand Reactime ne trouve pas d’application React?
+Nous accueillons avec joie les contributions de développeurs de tous niveaux ! Voici comment vous pouvez aider à améliorer Reactime:
🙋 Contributing README
-Reactime s'exécute initialement à l'aide du hook global des outils de développement de l'API Chrome. Leur chargement dans Chrome peut prendre du temps. Essayez d'actualiser votre application plusieurs fois jusqu'à ce que Reactime s'exécute.
+1. **Commencer**
-###
Un écran noir s’affiche à la place de l’extension Reactime
+ - Forkez le dépôt
+ - Consultez notre README Développeur détaillé
+ - Mettez en place votre environnement de développement local
-Essayez d'actualiser l'application que vous souhaitez tester et actualisez les DevTools en cliquant sur le bouton droit de la souris «Recharger le cadre».
+2. **Processus de Build**
-###
J’ai trouvé un bug dans Reactime
+ - Suivez les instructions de build dans le README Développeur
+ - Testez soigneusement vos modifications
+ - Soumettez une Pull Request
-Reactime est un projet open source, et toute aide de vore part sera grandement appréciée pour nous aider à améliorer l'expérience utilisateur. Veuillez créer une pull request (ou un problème) pour proposer et collaborer sur les modifications apportées à un référentiel.
+Rejoignez notre communauté grandissante de contributeurs et participez à façonner l’avenir des outils de débogage React ! Pour des lignes directrices de contribution plus détaillées et des informations sur l’architecture du projet, veuillez vous référer à notre
👩💻 README Développeur .
+
+
-##
Caractéristiques
+
🛠️ Dépannage
-### Optimisation du rendu
+### ❓
Pourquoi Reactime n’enregistre-t-il pas les nouveaux changements d’état ?
-L'un des problèmes les plus courants qui affectent les performances dans React est les cycles de rendu inutiles. Ce problème peut être résolu en vérifiant vos rendus dans l'onglet Performances de Chrome DevTools sous le panneau Reactime.
+Reactime a perdu sa connexion avec l’onglet que vous surveillez ; il vous suffit de cliquer sur le bouton "reconnecter"
+pour reprendre votre travail.
-### Enregistrement
+### ❓
Pourquoi Reactime ne trouve-t-il pas mes hooks ?
-Chaque fois que l'état est changé (chaque fois que setState, useState est appelé), cette extension crée un snapshot de l'arbre d'état actuelle et l'enregistre. Chaque instantané sera affiché dans Chrome DevTools sous le panneau Reactime.
+Reactime détecte et surveille les hooks en parcourant le code React non minifié de votre application en mode développement. Si votre processus de build minifie ou "uglifie" votre code — même pour les builds de développement — Reactime risque de ne pas pouvoir localiser et suivre correctement vos hooks. Pour résoudre ce problème :
-### Visualisation
+1. **Assurez-vous d’une vraie build de développement** : Vérifiez la configuration de votre bundler ou outil de build (par ex. Webpack, Babel, Vite, etc.) pour vous assurer que votre application n’est pas minimisée ou "uglifiée" en mode développement.
-Vous pouvez cliquer sur un snapshot pour afficher l'état de votre application. L'état peut être visualisé dans un graphique de composants, une arbre JSON ou un graphique de performances. Les snapshots peuvent être différents d'un snapshot précédent, et peut être visualisé en mode Diff.
+ - Par exemple, avec Webpack, assurez-vous d’exécuter le mode : 'development', ce qui devrait désactiver la minification par défaut.
+ - Dans un projet Create React App, il suffit d’exécuter `npm start` ou `yarn start` pour configurer automatiquement une build de développement non minifiée.
-### Jumping
+2. **Vérifiez les surcharges** : Assurez-vous qu’aucun plugin Babel ou Webpack personnalisé ne minifie votre code, surtout si vous utilisez des frameworks comme Next.js ou Gatsby. Parfois, des plugins ou scripts supplémentaires peuvent s’exécuter en arrière-plan.
-À l'aide de la barre latérale des actions, un utilisateur peut accéder à n'importe quel snapshot enregistré précédemment. Appuyer sur le bouton de saut sur n'importe quel snapshot permettra à un utilisateur d'afficher les données d'état à tout moment dans l'historique de l'application cible.
+3. **Redémarrez & recompilez** : Après avoir modifié toute configuration de build, recompilez ou redémarrez votre serveur de développement pour vous assurer que la nouvelle configuration est prise en compte. Ensuite, rafraîchissez l’onglet de votre navigateur afin que Reactime puisse détecter vos hooks non minifiés.
-### Support pour TypeScript
+Après avoir modifié toute configuration de build, recompilez ou redémarrez votre serveur de développement pour vous assurer que la nouvelle configuration est prise en compte. Ensuite, rafraîchissez l’onglet de votre navigateur afin que Reactime puisse détecter vos hooks non minifiés.
-Reactime propose un support bêta pour les applications TypeScript utilisant des composants de classe avec état et des composants fonctionnels. Des tests et un développement supplémentaires sont nécessaires pour les hooks personnalisés, l'API de contexte et le mode Concurrent.
+### ❓
Pourquoi Reactime m’indique qu’aucune application React n’a été trouvée ?
-### Documentation
+Reactime s’exécute initialement grâce au hook global des dev tools de Chrome.
+Il faut du temps à Chrome pour le charger. Essayez de rafraîchir votre application plusieurs fois jusqu’à ce que vous voyiez Reactime en fonctionnement.
-Après avoir cloné ce référentiel, les développeurs peuvent simplement exécuter `npm run docs` au niveau racine et servir le fichier `/docs/index.html` généré dynamiquement sur un navigateur. Cela fournira une vue GUI lisible, extensible et interactive de la structure et des interfaces de la base de code.
+### ❓
Pourquoi dois-je avoir les React Dev Tools activées ?
-###
Caractéristiques supplémentaires
+Reactime fonctionne de concert avec les React Developer Tools pour accéder à l’arbre Fiber d’une application React ; en interne, Reactime parcourt l’arbre Fiber via le hook global des React Dev Tools, récupérant toutes les informations pertinentes à afficher au développeur.
-- identifier les rendus inutiles
-- fonctionnalité de survol pour afficher les détails des info-bulles sur les visualisations d'état
-- possibilité de panoramique et de zoom sur les visualisations d'état
-- une liste déroulante pour prendre en charge le développement de projets sur plusieurs onglets
-- un curseur pour parcourir rapidement les snapshots
-- un bouton de lecture pour se déplacer automatiquement dans les snapshots
-- un bouton de verrouillage, qui arrête l'enregistrement de chaque snapshot
-- un bouton persister pour conserver les snapshots lors de l'actualisation (pratique lors du changement de code et du débogage)
-- télécharger les snapshots actuels en mémoire
-- titres déclaratifs dans la barre latérale des actions
+### ❓
J’ai trouvé un bug dans Reactime
-##
En savoir plus
+Reactime est un projet open-source, et nous serions ravis d’avoir vos retours pour améliorer l’expérience utilisateur. Veuillez consulter le
👩💻 README Développeur ,
+et créer une Pull Request (ou une issue) pour proposer et collaborer sur des modifications de Reactime.
-- [Time-Travel State with Reactime](https://medium.com/better-programming/time-traveling-state-with-reactime-6-0-53fdc3ae2a20)
-- [React Fiber and Reactime](https://medium.com/@aquinojardim/react-fiber-reactime-4-0-f200f02e7fa8)
-- [Meet Reactime - a time-traveling State Debugger for React](https://medium.com/@yujinkay/meet-reactime-a-time-traveling-state-debugger-for-react-24f0fce96802)
-- [Deep in Weeds with Reactime, Concurrent React_fiberRoot, and Browser History Caching](https://itnext.io/deep-in-the-weeds-with-reactime-concurrent-react-fiberroot-and-browser-history-caching-7ce9d7300abb)
+### ❓
Compatibilité avec les versions Node
-##
Auteurs
+Depuis la sortie de Node v18.12.1 (LTS) le 04/11/22, le script a été mis à jour avec
+`npm run dev` | `npm run build` pour assurer une rétrocompatibilité.
+Pour la version Node v16.16.0, veuillez utiliser les scripts `npm run devlegacy` | `npm run buildlegacy`
+
+
+
✍️ Auteurs
+
+- **Garrett Chow** - [@garrettlchow](https://github.com/garrettlchow)
+- **Ellie Simens** - [@elliesimens](https://github.com/elliesimens)
+- **Ragad Mohammed** - [@ragad-mohammed](https://github.com/ragad-mohammed)
+- **Daniel Ryczek** - [@dryczek14](https://github.com/dryczek01)
+- **Patrice Pinardo** - [@pinardo88](https://github.com/pinardo88)
+- **Haider Ali** - [@hali03](https://github.com/hali03)
+- **Jose Luis Sanchez** - [@JoseSanchez1996](https://github.com/JoseSanchez1996)
+- **Logan Nelsen** - [@ljn16](https://github.com/ljn16)
+- **Mel Koppens** - [@MelKoppens](https://github.com/MelKoppens)
+- **Amy Yang** - [@ay7991](https://github.com/ay7991)
+- **Eva Ury** - [@evaSUry](https://github.com/evaSUry)
+- **Jesse Guerrero** - [@jguerrero35](https://github.com/jguerrero35)
+- **Oliver Cho** - [@Oliver-Cho](https://github.com/Oliver-Cho)
- **Ben Margolius** - [@benmarg](https://github.com/benmarg)
- **Eric Yun** - [@ericsngyun](https://github.com/ericsngyun)
- **James Nghiem** - [@jemzir](https://github.com/jemzir)
- **Wilton Lee** - [@wiltonlee948](https://github.com/wiltonlee948)
+- **Louis Lam** - [@llam722](https://github.com/llam722)
+- **Samuel Tran** - [@leumastr](https://github.com/leumastr)
+- **Brian Yang** - [@yangbrian310](https://github.com/yangbrian310)
+- **Emin Tahirov** - [@eminthrv](https://github.com/eminthrv)
+- **Peng Dong** - [@d28601581](https://github.com/d28601581)
+- **Ozair Ghulam** - [@ozairgh](https://github.com/ozairgh)
+- **Christina Or** - [@christinaor](https://github.com/christinaor)
+- **Khanh Bui** - [@AndyB909](https://github.com/AndyB909)
- **David Kim** - [@codejunkie7](https://github.com/codejunkie7)
- **Robby Tipton** - [@RobbyTipton](https://github.com/RobbyTipton)
- **Kevin HoEun Lee** - [@khobread](https://github.com/khobread)
@@ -144,7 +293,8 @@ Après avoir cloné ce référentiel, les développeurs peuvent simplement exéc
- **Daljit Gill** - [@dgill05](https://github.com/dgill05)
- **Ben Michareune** - [@bmichare](https://github.com/bmichare)
- **Dane Corpion** - [@danecorpion](https://github.com/danecorpion)
-- **Harry Fox** - [@StackOverFlowWhereArtThou](https://github.com/StackOverFlowWhereArtThou)
+- **Harry Fox** -
+ [@StackOverFlowWhereArtThou](https://github.com/StackOverFlowWhereArtThou)
- **Nathan Richardson** - [@BagelEnthusiast](https://github.com/BagelEnthusiast)
- **David Bernstein** - [@dangitbobbeh](https://github.com/dangitbobbeh)
- **Joseph Stern** - [@josephiswhere](https://github.com/josephiswhere)
@@ -175,18 +325,19 @@ Après avoir cloné ce référentiel, les développeurs peuvent simplement exéc
- **Bryan Lee** - [@mylee1995](https://github.com/mylee1995)
- **Josh Kim** - [@joshua0308](https://github.com/joshua0308)
- **Sierra Swaby** - [@starkspark](https://github.com/starkspark)
-- **Ruth Anam** - [@peachiecodes](https://github.com/peachiecodes)
+- **Ruth Anam** - [@nusanam](https://github.com/nusanam)
- **David Chai** - [@davidchaidev](https://github.com/davidchai717)
- **Yujin Kang** - [@yujinkay](https://github.com/yujinkay)
-- **Andy Wong** - [@andywongdev](https://github.com/andywongdev)
-- **Chris Flannery** - [@chriswillsflannery](https://github.com/chriswillsflannery)
+- **Andy Wong** - [@andynullwong](https://github.com/andynullwong)
+- **Chris Flannery** -
+ [@chriswillsflannery](https://github.com/chriswillsflannery)
- **Rajeeb Banstola** - [@rajeebthegreat](https://github.com/rajeebthegreat)
- **Prasanna Malla** - [@prasmalla](https://github.com/prasmalla)
- **Rocky Lin** - [@rocky9413](https://github.com/rocky9413)
- **Abaas Khorrami** - [@dubalol](https://github.com/dubalol)
- **Ergi Shehu** - [@Ergi516](https://github.com/ergi516)
- **Raymond Kwan** - [@rkwn](https://github.com/rkwn)
-- **Joshua Howard** - [@Joshua-Howard](https://github.com/joshua-howard)
+- **Joshua Howard** - [@joshua-howard](https://github.com/joshua-howard)
- **Lina Shin** - [@rxlina](https://github.com/rxlina)
- **Andy Tsou** - [@andytsou19](https://github.com/andytsou19)
- **Feiyi Wu** - [@FreyaWu](https://github.com/FreyaWu)
@@ -194,9 +345,35 @@ Après avoir cloné ce référentiel, les développeurs peuvent simplement exéc
- **Alex Gomez** - [@alexgomez9](https://github.com/alexgomez9)
- **Edar Liu** - [@liuedar](https://github.com/liuedar)
- **Kristina Wallen** - [@kristinawallen](https://github.com/kristinawallen)
-- **Quan Le** - [@blachfog](https://github.com/Blachfog)
+- **Quan Le** - [@Blachfog](https://github.com/Blachfog)
- **Robert Maeda** - [@robmaeda](https://github.com/robmaeda)
+- **Lance Ziegler** - [@lanceziegler](https://github.com/lanceziegler)
+- **Ngoc Zwolinski** - [@ngoczwolinski](https://github.com/ngoczwolinski)
+- **Peter Lam** - [@dev-plam](https://github.com/dev-plam)
+- **Zachary Freeman** - [@zacharydfreeman](https://github.com/zacharydfreeman/)
+- **Jackie Yuan** - [@yuanjackie1](https://github.com/yuanjackie1)
+- **Jasmine Noor** - [@jasnoo](https://github.com/jasnoo)
+- **Minzo Kim** - [@minzo-kim](https://github.com/minzo-kim)
+- **Mark Teets** - [@MarkTeets](https://github.com/MarkTeets)
+- **Nick Huemmer** - [@NickHuemmer](https://github.com/ElDuke717)
+- **James McCollough** - [@j-mccoll](https://github.com/j-mccoll)
+- **Mike Bednarz** - [@mikebednarz](https://github.com/mikebednarz)
+- **Sergei Liubchenko** - [@sergeylvq](https://github.com/sergeylvq)
+- **Yididia Ketema** - [@yididiaketema](https://github.com/yididiaketema)
+- **Morah Geist** - [@morahgeist](https://github.com/morahgeist)
+- **Eivind Del Fierro** - [@EivindDelFierro](https://github.com/EivindDelFierro)
+- **Kyle Bell** - [@KyEBell](https://github.com/KyEBell)
+- **Sean Kelly** - [@brok3turtl3](https://github.com/brok3turtl3)
+- **Christopher Stamper** - [@ctstamper](https://github.com/ctstamper)
+- **Jimmy Phy** - [@jimmally](https://github.com/jimmally)
+- **Andrew Byun** - [@AndrewByun](https://github.com/AndrewByun)
+- **Kelvin Mirhan** - [@kelvinmirhan](https://github.com/kelvinmirhan)
+- **Jesse Rosengrant** - [@jrosengrant](https://github.com/jrosengrant)
+- **Liam Donaher** - [@leebology](https://github.com/leebology)
+- **David Moore** - [@Solodt55](https://github.com/Solodt55)
+- **John Banks** - [@Jbanks123](https://github.com/Jbanks123)
+
-##
License
+
⚖️ Licence
-Ce projet est sous licence MIT - voir le fichier [LICENSE](LICENSE) pour plus de détails
+Ce projet est distribué sous licence MIT - voir le fichier [LICENSE](LICENSE) pour plus de détails.
diff --git a/README.md b/README.md
index 4451bbbcd..e6d02d5a6 100644
--- a/README.md
+++ b/README.md
@@ -1,301 +1,281 @@
-
Reactime is an open source Chrome developer tool for time travel debugging and performance monitoring in React applications. Reactime enables developers to record snapshots of application state, jump between and inspect state snapshots, and monitor performance metrics such as component render time and render frequency.
+
A powerful Chrome extension that enhances React development with time-travel debugging and advanced performance monitoring
+
Read our Medium Article to learn more about Reactime’s behind-the-scenes and development process!
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+##
✨ Key Features
+
+### 🔍 State Visualization
+
+- **Multiple Views**: Visualize your application state through Component Graphs, JSON Trees, Performance Graphs, and Accessibility Trees
+- **History Timeline**: Track state changes over time with an intuitive history visualization
+- **Web Metrics**: Monitor critical performance metrics in real-time
+- **Accessibility Insights**: Analyze your app's accessibility tree for each state change
+
+
+
On the main page, there are two main selections from the dropdown panel:
+
+- **Timejump**: View and navigate through the snapshot history of your application's state. You can jump to any point in time to see how the state evolves across changes. You can also use the play button to replay each state change automatically.
+- **Providers / Consumers**: Understand your application's context dependencies and their interactions better through visualizing its provider and consumer relationships.
+
+
- How To Use • Features • Website • Read More
+
+
-
Reactime 16.0 presents the codebase with substantial, much-needed
-clean-up. From the backend and frontend to testing, the Reactime XVI team has:
-removed vestigial code, added comments to clarify code, implemented 100% testing
-coverage for the codebase, compartmentalized and modularized files, and
-implemented typescript.
-
-The primary purpose of this update is to allow easier understanding of
-Reactime's codebase by individuals or groups wishing to further update Reactime,
-keeping this great developer tool alive.
-
-With release of Node v18.12.1(LTS) on 11/4/22, the script has been updated to
-'npm run dev' || 'npm run build' for backwards compatibility.
For version
-Node v16.16.0, please use script 'npm run devlegacy' || 'npm run buildlegacy'
-
-Previously,
Reactime 14.0 and 15.0 added the exciting features below:
-
-I. React Router Compatibility
Reactime is now compatible with React Router
-applications! Prior to Reactime 14.0, recording state snapshots as the user
-navigated across various routes was possible, but time travel debugging was only
-possible for the current route (i.e. jumping back to a prior state at a
-different route was not possible). In order to streamline debugging of
-applications with multiple routes, Reactime 14.0 added functionality that allows
-the user to time-travel back to different routes, including live updating in the
-browser to reflect the state of their application at that previously visited
-route.
-
-II. Classifying State Snapshots by Route
The list of state snapshots in the
-Reactime dashboard is now classified by route to give the developer visual cues
-of the snapshot-route relationship and make time travel debugging of various
-routes easier.
-
-III. Filtering Performance Metrics By Route
The Reactime dashboard includes
-a stacked bar graph showing render times for each component, with a separate bar
-stack for each snapshot. With Reactime 14.0, this composite bar graph can now be
-filtered by route to allow the developer to review detailed performance data by
-route.
-
-IV. Visualize And Compare Components Within a Snapshot
Users not only have
-access to multiple snapshots, but can now zone into a specified snapshot more
-granularly through a new visualization consisting of its individual components.
-These new graphs are rendered directly in the same Performance tab in Reactime
-and provide details for each component when the user hovers over, providing a
-new visual comparison of components across a single chosen state.
+### ⏱️ Time-Travel Debugging
+
+- **State Snapshots**: Capture and navigate through your application's state history
+- **Playback Controls**: Automatically replay state changes with adjustable speed
+- **Jump Points**: Instantly navigate to any previous state
+- **Diff Comparisons**: Compare states between snapshots
+
-
+
+
+
-After installing Reactime, you can test its functionalities with your React
-application in development mode.
+### 📊 Performance Analysis
-Please note, the time jumping feature will
ONLY work when your
-application is running in
development mode . In production mode, you are
-able to view your application’s component map but no additional features.
+- **Component Metrics**: Track render times and performance bottlenecks
+- **Series Comparison**: Compare performance across different sets of state changes
+- **Re-render Detection**: Identify and fix unnecessary render cycles
+- **Web Vitals**: Monitor Core Web Vitals and other performance metrics
+
+
-##
Installation
+### 🔄 Modern Framework Support
+
+
+
+ Full compatibility with Next.js, Remix, Recoil, and Gatsby
+
+
+TypeScript support for class and functional components
+
+
+Support for React Hooks and Context API
+
+
+
-To get started, install the Reactime
-[extension](https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga)
-from Chrome Web Store.
+### 💾 State Persistence & Sharing
-NOTE: The React Developer Tools
-[extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en)
-is also required for Reactime to run, if you do not already have it installed on
-your browser.
+Reactime makes it easy to save and share your application's state history:
-### Manual Installation
+- **Export State History**: Save your recorded snapshots as a JSON file for later analysis or sharing
+- **Import Previous Sessions**: Upload previously saved snapshots to compare state changes across different sessions
+- **Cross-Session Analysis**: Compare performance and state changes between different development sessions
+
-Go to Chrome Extensions (make sure Chrome Extension is in Developer Mode) for
-manual installation in (https://developer.chrome.com/extensions/faq#faq-dev-01)
-and click on Load Unpacked. Use `src/extension/build/` to load this extension.
-Turn on 'Allow access to file URLs' in extension details page if testing
-locally.
+
+
+
+
-### Looking to contribute to Reactime?
+### 📚 Interactive Documentation
-
Please refer to Developer Install for a detailed guide:
-
Developer Install
+Reactime provides comprehensive documentation to help developers understand its architecture and APIs:
+After cloning this repository, developers can simply run `npm run docs` at the
+root level and serve the dynamically generated `/docs/index.html` provding:
+
+
+
+ Interactive component diagrams
+
+
+Type definitions and interfaces
+
+
+Codebase architecture overview
+
+
+API references and examples
+
+
+
-After you finish the Develpoer Install, checkout
-[the developer README](src/README.md) for more info on the project, and
-instructions on building from source.
+
🎉 What's New!
-##
How to Use
+Reactime 26.0 brings a complete overhaul to the React debugging experience, featuring:
-After installing the Chrome extension, just open up your project in the browser.
+- **New Context Data Display**
-Then open up your Chrome DevTools and navigate to the Reactime panel.
+ - First-ever visualization of useContext hook state changes
+ - Clear mapping of provider-consumer relationships
+ - Real-time context state value monitoring
+ - Detailed provider data visualization
-##
Troubleshooting
+- **Enhanced Time Travel Debugging**
-### ❓
Why is Reactime telling me that no React application is found?
+ - Redesigned slider interface positioned alongside snapshots
+ - Variable playback speed controls
+ - More intuitive state navigation
+ - Improved snapshot visualization
-Reactime initially runs using the dev tools global hook from the Chrome API. It
-takes time for Chrome to load this. Try refreshing your application a couple
-times until you see Reactime running.
+- **Modern UI Overhaul**
-### ❓
There is a black screen instead of the Reactime extension
+ - Sleek, contemporary design with rounded components
+ - Intuitive layout improvements
+ - New dark mode support
+ - Enhanced visual hierarchy
-Try refreshing the application you want to test and refresh the DevTools by
-clicking the right mouse button “Reload frame”.
+- **Major Technical Improvements**
+ - Fixed connection persistence during idle time and tab switches
+ - Restored accessibility tree visualization
+ - Resolved state capture issues for function-based useState hooks
+ - Improved overall extension reliability and performance
-### ❓
I found a bug in Reactime
+These updates make Reactime more powerful, reliable, and user-friendly than ever before, setting a new standard for React debugging tools.
+
+
-Reactime is an open source project, and we’d really appreciate your help with
-improving user experience. Please read [the developer README](src/README.md),
-and create a pull request (or issue) to propose and collaborate on changes to a
-repository.
+
🚀 Getting Started
-### ❓
Node version compatiability
+### Installation
-With release of Node v18.12.1(LTS) on 11/4/22, the script has been updated to
-'npm run dev' | 'npm run build' for backwards compatibility.
For version
-Node v16.16.0, please use script 'npm run devlegacy' | 'npm run buildlegacy'
+1. Install the [Reactime extension](https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga) from the Chrome Web Store
+2. Install the required [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) extension if you haven't already
-##
Features
+### Prerequisites
-### 🔹 Viewing
+- Your React application must be running in **development mode**
+- React Developer Tools extension must be installed
+- Chrome browser (version 80 or higher recommended)
-You can view your application's file structure and click on a snapshot to view
-your app's state. State can be visualized in a Component Graph, JSON Tree, or
-Performance Graph. Snapshots can be diffed with the previous snapshot, which can
-be viewed in Diff mode.
-
-
+### Launch Reactime
-
-
-
-
+There are two ways to open the Reactime panel:
-### 🔹 Snapshot Series and Action Comparison
+1. **DevTools**
-You can save a series of state snapshots and use it to analyze changes in
-component render performance between current and previous series of snapshots.
-You can also name specific snapshots and compare all snapshots with the same
-name.
-
-
+ - Open Chrome DevTools (F12 or ⌘+⌥+I)
+ - Navigate to the "Reactime" tab
+ - This will open Reactime as a panel within Chrome DevTools, integrated alongside your other development tools
-
-
-
-
+2. **Context Menu**
-### 🔹 Components Comparison
+ - Right-click anywhere on your React application
+ - Select "Reactime" from the context menu
+ - This will open Reactime in a separate popup window which you can resize and position independently
-When toggled to a specific snapshot, a visualization of the individual
-components of the snapshow will be displayed. This can be done under the same
-Performance tab where the snapshots are rendered. You will also find details of
-each component upon hovering.
+Once launched, Reactime will automatically begin monitoring your application's state changes and performance metrics.
-
-
-
-
+
🤝 Contributing to Reactime
-### 🔹 Recording
+We welcome contributions from developers of all skill levels! For detailed guidelines on how to contribute:
-Whenever state is changed (whenever setState, useState is called), this
-extension will create a snapshot of the current state tree and record it. Each
-snapshot will be displayed in Chrome DevTools under the Reactime panel.
-
-
+1. **Get Started**
-
-
-
-
+ - Fork the repository
+ - Review our comprehensive Developer README
+ - Set up your local development environment
-### 🔹 Re-render Optimization
+2. **Build Process**
-One of the most common issues that affects performance in React is unnecessary
-render cycles. This problem can be fixed by checking your renders in the
-Performance tab in Chrome DevTools under the Reactime panel.
+ - Follow our build instructions in the Developer README
+ - Test your changes thoroughly
+ - Submit a pull request
-### 🔹 Jumping
+Join our growing community of contributors and help shape the future of React debugging tools! For detailed contribution guidelines and project architecture information, please refer to our
👩💻 Developer README and
🙋 Contributing README
+
+
-Using the actions sidebar, a user can jump to any previous recorded snapshots.
-Hitting the jump button on any snapshot will allow a user to view state data at
-any point in the history of the target application.
+
🛠️ Troubleshooting
-### 🔹 Gatsby
+### ❓
Why is Reactime not recording new state changes?
-Reactime offers full support for Gatsby applications. You would be able to
-identify unnecessary renders, duration of each rendering, travel-debugging
-features and visual representation of the tree components.
+Reactime lost its connection to the tab you're monitoring, simply click the "reconnect" button to resume your work.
-### 🔹 Next.js
+### ❓
Why isn’t Reactime finding my hooks?
-Reactime offers debugging and performance tools for Next.js apps: time-traveling
-debugging, preventing unnecessary components re-renders and making your
-application faster.
+Reactime detects and monitors hooks by traversing your application’s unminified React code in development mode. If your build process is minifying or uglifying your code—even for development builds—Reactime may not be able to properly locate and track your hooks. To fix this:
-### 🔹 TypeScript Support
+1. **Ensure a true development build**: Double-check your bundler or build tool configuration (e.g., Webpack, Babel, Vite, etc.) to make sure that your application is not minimized or uglified in development mode.
-Reactime offers beta support for TypeScript applications using stateful class
-components and functional components. Further testing and development is
-required for custom hooks, Context API, and Concurrent Mode.
+ - For example, with Webpack, make sure you’re running in mode: 'development', which should disable default minification.
+ - In a Create React App project, simply running npm start or yarn start will automatically configure a non-minified development build.
-### 🔹 Documentation
+2. **Check for overrides**: Ensure there are no custom Babel or Webpack plugins that minify your code, especially if you’re using frameworks like Next.js or Gatsby. Sometimes additional plugins or scripts might be running under the hood.
-After cloning this repository, developers can simply run `npm run docs` at the
-root level and serve the dynamically generated `/docs/index.html` file on a
-browser. Doing so will provide a readable, extensible, and interactive GUI view
-of the structure and interfaces of the codebase.
-
+3. **Restart & rebuild**: After changing any build configuration, rebuild or restart your development server to ensure the new configuration is applied. Then refresh your browser tab so Reactime can detect your unminified hooks.
-###
Additional Features
-
-- Identifying unnecessary re-renders
-- Single-click to view tooltip details on state visualizations
-- Double-click to collapse child components
-- A reverse filter with autofill to focus on a portion of the component map
-- Ability to pan and zoom on state visualizations
-- A dropdown to support development of projects on multiple tabs
-- A slider to move through snapshots quickly
-- A play button to move through snapshots automatically
-- A lock button, which stops recording each snapshot
-- A persist button to keep snapshots upon refresh (handy when changing code and
- debugging)
-- Download/upload the current snapshots in memory
-- Declarative titles in the actions sidebar
-- Interative Tutorial Walkthrough
-- Toggle feature allowing temporary pause of state monitoring
-- Updated frontend diagram:
+After changing any build configuration, rebuild or restart your development server to ensure the new configuration is applied. Then refresh your browser tab so Reactime can detect your unminified hooks.
-
-
+### ❓ Why is Reactime telling me that no React application is found?
-### Bug Fixes
+Reactime initially runs using the dev tools global hook from the Chrome API. It
+takes time for Chrome to load this. Try refreshing your application a couple of
+times until you see Reactime running.
-- Search bar now searches for specific nodes successfully
-- Tab titles of chrome browser tabs not running an application in development
- mode are no longer affected by Reactime
-- Multiple black screens fixed
-- Improved UI and performance
-- No longer inject scripts to non-target applications
+### ❓ Why do I need to have React Dev Tools enabled?
-## Read More
+Reactime works in tandem with the React Developer Tools to access a React application's Fiber tree; under the hood, Reactime traverses the Fiber tree through the React Developer Tool's global hook, pulling all relevant information needed to display to the developer
-- [Reactime XVI: Clean-up Time](https://medium.com/@emintahirov1996/reactime-xvi-cleanup-time-a14ba3dcc8a6)
-- [Inter-Route Time Travel with Reactime](https://medium.com/@robbytiptontol/inter-route-time-travel-with-reactime-d84cd55ec73b)
-- [Time-Travel State with Reactime](https://medium.com/better-programming/time-traveling-state-with-reactime-6-0-53fdc3ae2a20)
-- [React Fiber and Reactime](https://medium.com/@aquinojardim/react-fiber-reactime-4-0-f200f02e7fa8)
-- [Meet Reactime - a time-traveling State Debugger for React](https://medium.com/@yujinkay/meet-reactime-a-time-traveling-state-debugger-for-react-24f0fce96802)
-- [Deep in Weeds with Reactime, Concurrent React_fiberRoot, and Browser History Caching](https://itnext.io/deep-in-the-weeds-with-reactime-concurrent-react-fiberroot-and-browser-history-caching-7ce9d7300abb)
-- [Time-Traveling Through React State with Reactime 9.0](https://rxlina.medium.com/time-traveling-through-react-state-with-reactime-9-0-371dbdc99319)
-- [What time is it? Reactime!](https://medium.com/@liuedar/what-time-is-it-reactime-fd7267b9eb89)
+### ❓ I found a bug in Reactime
+
+Reactime is an open-source project, and we'd love to hear from you about
+improving the user experience. Please read the 👩💻 Developer README ,
+and create a pull request (or issue) to propose and collaborate on changes to Reactime.
-## Authors
+### ❓ Node version compatibility
+
+With the release of Node v18.12.1(LTS) on 11/4/22, the script has been updated to
+'npm run dev' | 'npm run build' for backwards compatibility. For version
+Node v16.16.0, please use script 'npm run devlegacy' | 'npm run buildlegacy'
+
+
+
✍️ Authors
+
+- **Garrett Chow** - [@garrettlchow](https://github.com/garrettlchow)
+- **Ellie Simens** - [@elliesimens](https://github.com/elliesimens)
+- **Ragad Mohammed** - [@ragad-mohammed](https://github.com/ragad-mohammed)
+- **Daniel Ryczek** - [@dryczek14](https://github.com/dryczek01)
+- **Patrice Pinardo** - [@pinardo88](https://github.com/pinardo88)
+- **Haider Ali** - [@hali03](https://github.com/hali03)
+- **Jose Luis Sanchez** - [@JoseSanchez1996](https://github.com/JoseSanchez1996)
+- **Logan Nelsen** - [@ljn16](https://github.com/ljn16)
+- **Mel Koppens** - [@MelKoppens](https://github.com/MelKoppens)
+- **Amy Yang** - [@ay7991](https://github.com/ay7991)
+- **Eva Ury** - [@evaSUry](https://github.com/evaSUry)
+- **Jesse Guerrero** - [@jguerrero35](https://github.com/jguerrero35)
+- **Oliver Cho** - [@Oliver-Cho](https://github.com/Oliver-Cho)
- **Ben Margolius** - [@benmarg](https://github.com/benmarg)
- **Eric Yun** - [@ericsngyun](https://github.com/ericsngyun)
- **James Nghiem** - [@jemzir](https://github.com/jemzir)
@@ -371,8 +351,33 @@ of the structure and interfaces of the codebase.
- **Kristina Wallen** - [@kristinawallen](https://github.com/kristinawallen)
- **Quan Le** - [@blachfog](https://github.com/Blachfog)
- **Robert Maeda** - [@robmaeda](https://github.com/robmaeda)
+- **Lance Ziegler** - [@lanceziegler](https://github.com/lanceziegler)
+- **Ngoc Zwolinski** - [@ngoczwolinski](https://github.com/ngoczwolinski)
+- **Peter Lam** - [@dev-plam](https://github.com/dev-plam)
+- **Zachary Freeman** - [@zacharydfreeman](https://github.com/zacharydfreeman/)
+- **Jackie Yuan** - [@yuanjackie1](https://github.com/yuanjackie1)
+- **Jasmine Noor** - [@jasnoo](https://github.com/jasnoo)
+- **Minzo Kim** - [@minzo-kim](https://github.com/minzo-kim)
+- **Mark Teets** - [@MarkTeets](https://github.com/MarkTeets)
+- **Nick Huemmer** - [@NickHuemmer](https://github.com/ElDuke717)
+- **James McCollough** - [@j-mccoll](https://github.com/j-mccoll)
+- **Mike Bednarz** - [@mikebednarz](https://github.com/mikebednarz)
+- **Sergei Liubchenko** - [@sergeylvq](https://github.com/sergeylvq)
+- **Yididia Ketema** - [@yididiaketema](https://github.com/yididiaketema)
+- **Morah Geist** - [@morahgeist](https://github.com/morahgeist)
+- **Eivind Del Fierro** - [@EivindDelFierro](https://github.com/EivindDelFierro)
+- **Kyle Bell** - [@KyEBell](https://github.com/KyEBell)
+- **Sean Kelly** - [@brok3turtl3](https://github.com/brok3turtl3)
+- **Christopher Stamper** - [@ctstamper](https://github.com/ctstamper)
+- **Jimmy Phy** - [@jimmally](https://github.com/jimmally)
+- **Andrew Byun** - [@AndrewByun](https://github.com/AndrewByun)
+- **Kelvin Mirhan** - [@kelvinmirhan](https://github.com/kelvinmirhan)
+- **Jesse Rosengrant** - [@jrosengrant](https://github.com/jrosengrant)
+- **Liam Donaher** - [@leebology](https://github.com/leebology)
+- **David Moore** - [@Solodt55](https://github.com/Solodt55)
+- **John Banks** - [@Jbanks123](https://github.com/Jbanks123)
+
-##
License
+
⚖️ License
-This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
-for details.
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
diff --git a/README.rus.md b/README.rus.md
index 2d4303a2d..380f9f819 100644
--- a/README.rus.md
+++ b/README.rus.md
@@ -1,115 +1,278 @@
-
-
-
-[](https://github.com/oslabs-beta/reactime) [](https://travis-ci.com/oslabs-beta/reactime) [](http://badge.fury.io/js/reactime)  
+
Мощное расширение Chrome, которое улучшает процесс разработки React за счёт отладки с путешествиями во времени и углублённого мониторинга производительности
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+##
✨ Ключевые особенности
+
+### 🔍 Визуализация состояния
+
+- **Разнообразные представления**: Отображение состояния приложения в виде графов компонентов, JSON-деревьев, графиков производительности и деревьев доступности
+- **История изменений**: Отслеживайте изменения состояния во времени с удобной визуализацией истории
+- **Метрики веб-приложения**: Отслеживайте важные метрики производительности в реальном времени
+- **Аналитика доступности**: Анализируйте дерево доступности вашего приложения на каждом этапе изменения состояния
+
+
+
На главном экране доступны два основных выбора из выпадающего списка:
+
+- **Timejump**: Просматривайте и перемещайтесь по истории снимков состояния (snapshot) вашего приложения. Можно переместиться в любую точку во времени, чтобы увидеть, как состояние эволюционировало при изменениях. Также доступна кнопка воспроизведения, чтобы автоматически проиграть каждое изменение состояния.
+- **Providers / Consumers**: Глубже понимайте зависимости контекста приложения и его взаимодействия, визуализируя отношения провайдеров и потребителей.
+
+
+
+
+
+
+
+### ⏱️ Отладка с путешествиями во времени
+
+- **Снимки состояния**: Фиксируйте и перемещайтесь по истории состояния приложения
+- **Элементы управления воспроизведением**: Автоматически воспроизводите изменения состояния с регулировкой скорости
+- **Точки мгновенного перехода**: Мгновенно возвращайтесь к любому предыдущему состоянию
+- **Сравнение состояний**: Сравнивайте разницу между снимками состояния
+
+
+
+
+
+
+
+### 📊 Анализ производительности
+
+- **Метрики компонентов**: Отслеживайте время рендера и узкие места в производительности
+- **Сравнение серий**: Сопоставляйте производительность при разных наборах изменений состояния
+- **Определение перерисовок**: Находите и исправляйте избыточные циклы рендера
+- **Web Vitals**: Следите за Core Web Vitals и другими метриками
+
+
+
+### 🔄 Поддержка современных фреймворков
+
+
+
+ Полная совместимость с Gatsby, Next.js и Remix
+
+
+Поддержка TypeScript для классовых и функциональных компонентов
+
+
+Поддержка React Hooks и Context API
+
+
+
+
+### 💾 Сохранение и обмен состоянием
+
+Reactime упрощает сохранение и обмен историей состояния вашего приложения:
+
+- **Экспорт истории**: Сохраняйте записанные снимки в JSON-файл для дальнейшего анализа или передачи
+- **Импорт предыдущих сессий**: Загружайте ранее сохранённые снимки, чтобы сравнивать изменения состояния между разными сессиями
+- **Межсессионный анализ**: Сопоставляйте производительность и изменения состояния между разными этапами разработки
+
+
+
+
+
+
+### 📚 Интерактивная документация
+
+Reactime предлагает обширную документацию, помогающую разработчикам разобраться в архитектуре и API инструмента. После клонирования репозитория достаточно запустить `npm run docs` в корневой директории, а затем открыть сгенерированный файл `/docs/index.html`, в котором представлены:
+
+
+
+ Интерактивные диаграммы компонентов
+
+
+Типы и интерфейсы
+
+
+Обзор архитектуры кодовой базы
+
+
+API-справочник и примеры
+
+
+
+
+
🎉 Что нового!
-
Reactime - расширение для дебаггинга/отладки React приложений. Оно создает снэпшоты при каждом изменении состояния (state) и позволяет пользованию прыгать на любое предыдущее состояние (state).
-В настоящее время Reactime поддерживает React приложения с классовыми, функциональными компонентами, хуками и Context API.
+Версия Reactime 26.0 предлагает полное обновление инструмента отладки React, включая:
-В Reactime версии 7.0 отлажены баги предыдущих версий, улучшена визуализация данных отношений между компонентами. Также новая версия включает в себя расширенную документацию для разработчиков, которые хотят работать над приложением.
+- **Новый показ данных контекста**
-После загрузки Reactime вы можете протестировать его полную функциональность на любом вашем React приложении в режиме разработки (dev mode). В продакшен режиме вы можете только работать с картой компонентов.
+ - Первая в своём роде визуализация состояния, основанного на хуке useContext
+ - Чёткое отображение отношений «провайдер – потребитель»
+ - Мониторинг значений контекста в реальном времени
+ - Подробная визуализация данных провайдеров
-##
Установка
+- **Улучшенная отладка с путешествиями во времени**
-Для начала использования приложения, скачайте Reactime [extension](https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga) из Chrome Web Store.
+ - Переработанный интерфейс слайдера, размещённого вместе со снимками
+ - Элементы управления скоростью воспроизведения
+ - Более интуитивная навигация по состояниям
+ - Улучшенная визуализация снимков
-Внимание: Вам понадобится React Developer Tools [extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) Вам не нужно запускать React DevTools, но расширение должно быть установлено в вашем браузере.
+- **Современный переработанный интерфейс**
-###
Альтернативная установка
+ - Стильный, современный дизайн со скруглёнными элементами
+ - Интуитивная структура расположения элементов
+ - Новый тёмный режим
+ - Улучшенная визуальная иерархия
-Используйте `src/extension/build/build.zip` для мануальной установки в [Developer mode](https://developer.chrome.com/extensions/faq#faq-dev-01). Включите 'Allow access to file URLs' в разделе с расширениями.
+- **Крупные технические улучшения**
+ - Исправлена проблема с сохранением соединения при бездействии или переключении вкладок
+ - Восстановлена визуализация дерева доступности (Accessibility Tree)
+ - Исправлены проблемы с захватом состояния для хуков useState в функциональных компонентах
+ - Общий рост стабильности и производительности расширения
-##
Как использовать
+Благодаря этим обновлениям Reactime стал ещё более мощным, надёжным и удобным в использовании, устанавливая новый стандарт среди инструментов отладки React.
-После установки Chrome extension, просто откройте ваш проект в браузере.
+Чтобы узнать больше о предыдущих релизах, перейдите по
ссылке .
+
+
+
+
🚀 Начало работы
+
+### Установка
-Затем откройте Chrome DevTools и найдите панель Reactime.
+1. Установите [Reactime](https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga) из Интернет-магазина Chrome
+2. Установите необходимое расширение [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en), если у вас его ещё нет
-##
Устраняем проблемы
+### Предварительные требования
-###
Почему Reactime говорит, что приложение React не найдено?
+- Ваше React-приложение должно работать в **режиме разработки (development)**
+- Расширение React Developer Tools должно быть установлено
+- Браузер Chrome (рекомендуется версия 80 или выше)
-Reactime работает при использовании глобального хука DevTools, его загрузка может занимать некоторое время у Chrome браузера. Попробуйте обновить ваше приложение.
+### Запуск Reactime
-###
Вместо Reactime - черный экран
+Существует два способа открыть панель Reactime:
-Попробуйте обновить приложение, которые вы хотите отладить или обновите панель Reactime. Сделать это можно кликом правой кнопки “Reload the frame”.
+1. **Контекстное меню**
-###
Я нашел ошибки при работе Reactime
+ - Кликните правой кнопкой мыши в любом месте вашего React-приложения
+ - Выберите «Reactime» в контекстном меню
-Reactime это open source project, поэтому мы будем рады, если вы поможете нам сделать его лучше. Если вы знаете как устранить баг - запросите pull request. Также вы можете сообщить об ошибках в разделе “Issues”.
+2. **Инструменты разработчика**
+ - Откройте Chrome DevTools (F12 или ⌘+⌥+I)
+ - Перейдите на вкладку «Reactime»
-##
Функциональность
+После запуска Reactime автоматически начнёт отслеживать изменения состояния и метрики производительности вашего приложения.
+
+
-### Оптимизация рендеринга
+
🤝 Участие в развитии Reactime
-Одна из самых распространенных проблем, которая влияет на производительность приложения React - ненужный циклы ре-рендеринга. Эту проблему вы можете решить при помощи отслеживания рендеринга во вкладке Performance в Reactime.
+Мы приглашаем всех желающих внести свой вклад в улучшение Reactime! Вот как вы можете помочь:
🙋 Contributing README
-### Запись
+1. **Начальный шаг**
-Когда изменяется состояние (при вызове useState или setState), Reactime создает снэпшот состояния дерева в настоящий момент и записывает его. Каждый снэпшот отображается в Chrome DevTools в разделе Reactime.
+ - Сделайте форк репозитория
+ - Изучите наше подробное Руководство для разработчиков (Developer README)
+ - Настройте локальную среду разработки
-### Просмотр
+2. **Процесс сборки**
+ - Следуйте инструкциям по сборке в Руководстве для разработчиков
+ - Тщательно протестируйте свои изменения
+ - Создайте пул-реквест
-При клике на снапшот вы можете увидеть состояние вашего приложения. Состояния отображаются в виде графика или JSON дерева, вы можете переключить вкладку на удобную вам визуализацию.
+Присоединяйтесь к нашему растущему сообществу контрибьюторов и помогите формировать будущее инструментов отладки React! Подробные инструкции по участию и архитектуре проекта вы найдёте в
👩💻 Руководстве для разработчиков .
+
+
-### Прыжки
+
🛠️ Устранение неполадок
-Используя панель действий, вы можете совершать прыжки на предыдущие сохраненные снэпшоты. Используя данный функционал вы можете отследить работу приложения в нужный момент времени или при вводе определенных данных.
+### ❓
Почему Reactime не записывает новые изменения состояния?
-### TypeScript поддержка
+Reactime потерял соединение с вкладкой, за которой ведётся наблюдение. Просто нажмите кнопку «reconnect», чтобы возобновить работу.
-Reactime beta поддерживает приложения, написанные на TypeScript, которые используют классы и функциональные компоненты. Работа с хуками, Context API и Concurrent Mode находится в стадии тестирования.
+### ❓
Почему Reactime не может найти мои хуки?
-### Документация
+Reactime обнаруживает и отслеживает хуки, просматривая «неминифицированный» код React в режиме разработки. Если ваш процесс сборки минифицирует или «уродует» (uglify) код — даже в режиме разработки — Reactime может не найти и не отследить ваши хуки. Чтобы исправить это:
-После клонирования репозитория, вы можете использовать команду `npm run docs` в корневой папке, которая генерирует файл в браузере `/docs/index.html`. Это упростит знакомство с приложением и поможет вам ознакомиться со структурой и интерфейсом существующего кода.
+1. **Убедитесь, что сборка действительно предназначена для разработки**: Проверьте настройки вашего бандлера или инструмента сборки (например, Webpack, Babel, Vite и т. д.), чтобы приложение не было минимизировано и «уродовано» в режиме разработки.
+ - Например, в Webpack установите `mode: 'development'`, чтобы по умолчанию отключить минификацию.
+ - В Create React App, достаточно запустить `npm start` или `yarn start`, чтобы автоматически настроить неминифицированную сборку.
+2. **Проверьте, нет ли переопределений**: Убедитесь, что нет дополнительных Babel- или Webpack-плагинов, которые минифицируют ваш код, особенно если вы используете фреймворки вроде Next.js или Gatsby. Иногда дополнительные плагины или скрипты могут незаметно запускать минификацию.
+3. **Перезапустите и пересоберите**: После изменения настроек сборки перезапустите или пересоберите ваше приложение, чтобы новые настройки были применены. Затем обновите вкладку браузера, чтобы Reactime мог обнаружить ваши неминифицированные хуки.
-###
Дополнительный функционал
+### ❓
Почему Reactime говорит, что React-приложение не найдено?
-- identifying unnecessary re-renders
-- hover functionality to view tooltip details on state visualizations
-- ability to pan and zoom on state visualizations
-- a dropdown to support development of projects on multiple tabs
-- a slider to move through snapshots quickly
-- a play button to move through snapshots automatically
-- a lock button, which stops recording each snapshot
-- a persist button to keep snapshots upon refresh (handy when changing code and debugging)
-- download/upload the current snapshots in memory
-- declarative titles in the actions sidebar
+Reactime изначально запускается, используя глобальный хук dev tools из API Chrome. Чтобы Chrome успел это загрузить, может потребоваться время. Попробуйте обновить (refresh) ваше приложение несколько раз, пока не увидите, что Reactime заработал.
-##
Узнать больше о Reactime и React Fiber
+### ❓
Почему мне нужно включать React Dev Tools?
-- [Time-Travel State with Reactime](https://medium.com/better-programming/time-traveling-state-with-reactime-6-0-53fdc3ae2a20)
-- [React Fiber and Reactime](https://medium.com/@aquinojardim/react-fiber-reactime-4-0-f200f02e7fa8)
-- [Meet Reactime - a time-traveling State Debugger for React](https://medium.com/@yujinkay/meet-reactime-a-time-traveling-state-debugger-for-react-24f0fce96802)
-- [Deep in Weeds with Reactime, Concurrent React_fiberRoot, and Browser History Caching](https://itnext.io/deep-in-the-weeds-with-reactime-concurrent-react-fiberroot-and-browser-history-caching-7ce9d7300abb)
+Reactime работает в связке с React Developer Tools, чтобы получить доступ к дереву Fiber в React-приложении. Внутри Reactime просматривает дерево Fiber через глобальный хук из React Developer Tools, получая всю необходимую информацию для отображения разработчику.
-##
Авторы
+### ❓
Я нашёл(ла) баг в Reactime
+
+Reactime — это проект с открытым исходным кодом. Мы будем рады услышать ваши идеи по улучшению пользовательского опыта. Ознакомьтесь с
👩💻 Руководством для разработчиков и создайте пул-реквест (или Issue), чтобы предложить и совместно доработать изменения в Reactime.
+
+### ❓
Совместимость с версиями Node
+
+С выходом Node v18.12.1 (LTS) от 04.11.22 в скриптах появились команды
+`npm run dev` | `npm run build` для обратной совместимости.
Для версии
+Node v16.16.0 используйте скрипты `npm run devlegacy` | `npm run buildlegacy`
+
+
+
+
✍️ Авторы
+
+- **Garrett Chow** - [@garrettlchow](https://github.com/garrettlchow)
+- **Ellie Simens** - [@elliesimens](https://github.com/elliesimens)
+- **Ragad Mohammed** - [@ragad-mohammed](https://github.com/ragad-mohammed)
+- **Daniel Ryczek** - [@dryczek14](https://github.com/dryczek01)
+- **Patrice Pinardo** - [@pinardo88](https://github.com/pinardo88)
+- **Haider Ali** - [@hali03](https://github.com/hali03)
+- **Jose Luis Sanchez** - [@JoseSanchez1996](https://github.com/JoseSanchez1996)
+- **Logan Nelsen** - [@ljn16](https://github.com/ljn16)
+- **Mel Koppens** - [@MelKoppens](https://github.com/MelKoppens)
+- **Amy Yang** - [@ay7991](https://github.com/ay7991)
+- **Eva Ury** - [@evaSUry](https://github.com/evaSUry)
+- **Jesse Guerrero** - [@jguerrero35](https://github.com/jguerrero35)
+- **Oliver Cho** - [@Oliver-Cho](https://github.com/Oliver-Cho)
- **Ben Margolius** - [@benmarg](https://github.com/benmarg)
- **Eric Yun** - [@ericsngyun](https://github.com/ericsngyun)
- **James Nghiem** - [@jemzir](https://github.com/jemzir)
- **Wilton Lee** - [@wiltonlee948](https://github.com/wiltonlee948)
+- **Louis Lam** - [@llam722](https://github.com/llam722)
+- **Samuel Tran** - [@leumastr](https://github.com/leumastr)
+- **Brian Yang** - [@yangbrian310](https://github.com/yangbrian310)
+- **Emin Tahirov** - [@eminthrv](https://github.com/eminthrv)
+- **Peng Dong** - [@d28601581](https://github.com/d28601581)
+- **Ozair Ghulam** - [@ozairgh](https://github.com/ozairgh)
+- **Christina Or** - [@christinaor](https://github.com/christinaor)
+- **Khanh Bui** - [@AndyB909](https://github.com/AndyB909)
- **David Kim** - [@codejunkie7](https://github.com/codejunkie7)
- **Robby Tipton** - [@RobbyTipton](https://github.com/RobbyTipton)
- **Kevin HoEun Lee** - [@khobread](https://github.com/khobread)
@@ -150,10 +313,10 @@ Reactime beta поддерживает приложения, написанны
- **Bryan Lee** - [@mylee1995](https://github.com/mylee1995)
- **Josh Kim** - [@joshua0308](https://github.com/joshua0308)
- **Sierra Swaby** - [@starkspark](https://github.com/starkspark)
-- **Ruth Anam** - [@peachiecodes](https://github.com/peachiecodes)
+- **Ruth Anam** - [@nusanam](https://github.com/nusanam)
- **David Chai** - [@davidchaidev](https://github.com/davidchai717)
- **Yujin Kang** - [@yujinkay](https://github.com/yujinkay)
-- **Andy Wong** - [@andywongdev](https://github.com/andywongdev)
+- **Andy Wong** - [@andynullwong](https://github.com/andynullwong)
- **Chris Flannery** - [@chriswillsflannery](https://github.com/chriswillsflannery)
- **Rajeeb Banstola** - [@rajeebthegreat](https://github.com/rajeebthegreat)
- **Prasanna Malla** - [@prasmalla](https://github.com/prasmalla)
@@ -169,9 +332,35 @@ Reactime beta поддерживает приложения, написанны
- **Alex Gomez** - [@alexgomez9](https://github.com/alexgomez9)
- **Edar Liu** - [@liuedar](https://github.com/liuedar)
- **Kristina Wallen** - [@kristinawallen](https://github.com/kristinawallen)
-- **Quan Le** - [@blachfog](https://github.com/Blachfog)
+- **Quan Le** - [@Blachfog](https://github.com/Blachfog)
- **Robert Maeda** - [@robmaeda](https://github.com/robmaeda)
+- **Lance Ziegler** - [@lanceziegler](https://github.com/lanceziegler)
+- **Ngoc Zwolinski** - [@ngoczwolinski](https://github.com/ngoczwolinski)
+- **Peter Lam** - [@dev-plam](https://github.com/dev-plam)
+- **Zachary Freeman** - [@zacharydfreeman](https://github.com/zacharydfreeman/)
+- **Jackie Yuan** - [@yuanjackie1](https://github.com/yuanjackie1)
+- **Jasmine Noor** - [@jasnoo](https://github.com/jasnoo)
+- **Minzo Kim** - [@minzo-kim](https://github.com/minzo-kim)
+- **Mark Teets** - [@MarkTeets](https://github.com/MarkTeets)
+- **Nick Huemmer** - [@NickHuemmer](https://github.com/ElDuke717)
+- **James McCollough** - [@j-mccoll](https://github.com/j-mccoll)
+- **Mike Bednarz** - [@mikebednarz](https://github.com/mikebednarz)
+- **Sergei Liubchenko** - [@sergeylvq](https://github.com/sergeylvq)
+- **Yididia Ketema** - [@yididiaketema](https://github.com/yididiaketema)
+- **Morah Geist** - [@morahgeist](https://github.com/morahgeist)
+- **Eivind Del Fierro** - [@EivindDelFierro](https://github.com/EivindDelFierro)
+- **Kyle Bell** - [@KyEBell](https://github.com/KyEBell)
+- **Sean Kelly** - [@brok3turtl3](https://github.com/brok3turtl3)
+- **Christopher Stamper** - [@ctstamper](https://github.com/ctstamper)
+- **Jimmy Phy** - [@jimmally](https://github.com/jimmally)
+- **Andrew Byun** - [@AndrewByun](https://github.com/AndrewByun)
+- **Kelvin Mirhan** - [@kelvinmirhan](https://github.com/kelvinmirhan)
+- **Jesse Rosengrant** - [@jrosengrant](https://github.com/jrosengrant)
+- **Liam Donaher** - [@leebology](https://github.com/leebology)
+- **David Moore** - [@Solodt55](https://github.com/Solodt55)
+- **John Banks** - [@Jbanks123](https://github.com/Jbanks123)
+
-##
License
+
⚖️ Лицензия
-This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
+Этот проект распространяется по лицензии MIT — подробности см. в файле [LICENSE](LICENSE).
diff --git a/archive/readme-logo-svg.svg b/archive/readme-logo-svg.svg
deleted file mode 100644
index 3356a87b3..000000000
--- a/archive/readme-logo-svg.svg
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/archive/readme_logo.png b/archive/readme_logo.png
deleted file mode 100644
index 618512e11..000000000
Binary files a/archive/readme_logo.png and /dev/null differ
diff --git a/archive/src-app.jpg b/archive/src-app.jpg
deleted file mode 100644
index a9e03415e..000000000
Binary files a/archive/src-app.jpg and /dev/null differ
diff --git a/archive/v4-demo.gif b/archive/v4-demo.gif
deleted file mode 100644
index e4e959fb8..000000000
Binary files a/archive/v4-demo.gif and /dev/null differ
diff --git a/archive/v4-readme.md b/archive/v4-readme.md
deleted file mode 100644
index 29e2d69b4..000000000
--- a/archive/v4-readme.md
+++ /dev/null
@@ -1,128 +0,0 @@
-
-
-
-
-
State Debugger for React
-
-[](https://github.com/oslabs-beta/reactime) [](https://travis-ci.com/oslabs-beta/reactime) [](http://badge.fury.io/js/reactime) [](https://david-dm.org/oslabs-beta/reactime#info=dependencies) [](https://david-dm.org/oslabs-beta/reactime?type=dev) [](https://snyk.io/test/github/oslabs-beta/reactime)
-
-
-
-
-
-
-Reactime is a debugging tool for React developers. It records state whenever it is changed and allows the user to jump to any previously recorded state.
-
-This tool is for React apps using stateful components and prop drilling, and has beta support for Context API, conditional state routing, Hooks (useState, useEffect) and functional components.
-
-The latest release extends the core functionality by including support for TypeScript applications, improving the user experience through more declarative titles in the actions panel, and extending support for components with conditional state fields. The testing suite has also been expanded with the inclusion of a Sandbox utility to aid future expansion as well as additional E2E and integration tests with Puppeteer and React Testing Library.
-
-After installing the Reactime, you can test its functionalities in the following demo repositories:
-
-- [Calculator](https://joshua0308.github.io/calculator/)
-- [Bitcoin Price Index](http://reactime-demo2.us-east-1.elasticbeanstalk.com)
-
-Reactime was nominated for the Productivity Booster award at [React Open Source Awards 2020](https://osawards.com/react/)!
-
-## Installation
-
-Two parts are required for this tool to function: a [**Chrome extension**](https://chrome.google.com/webstore/detail/react-time-travel/cgibknllccemdnfhfpmjhffpjfeidjga) and an [**NPM package**](https://www.npmjs.com/package/reactime).
-
-1. Install the Reactime [extension](https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga) from Chrome Web Store. Alternatively, use `src/extension/build/build.zip` for manual installation in [Developer mode](https://developer.chrome.com/extensions/faq#faq-dev-01). Turn on 'Allow access to file URLs' in extension details page if testing locally.
-
-2. Install the [NPM package](https://www.npmjs.com/package/reactime) in your application's root directory.
-
-```
-npm i reactime
-```
-
-3. Call the library method on your root container after rendering your App.
-
-```
-import reactime from 'reactime';
-
-const rootContainer = document.getElementById('root');
-ReactDOM.render(
, rootContainer);
-
-reactime(rootContainer);
-```
-
-4. For experimental concurrent mode support.
-
-```
-import reactime from 'reactime';
-
-const rootContainer = ReactDOM.createRoot(document.getElementById('root'));
-rootContainer.render(
);
-reactime(rootContainer);
-```
-
-5. Done! That's all you have to do to link your React project to our library.
-
-## How to Use
-
-After installing both the Chrome extension and the NPM package, just open up your project in the browser.
-
-Then open up your Chrome DevTools and navigate to the Reactime tab.
-
-## Features
-
-### Recording
-
-Whenever state is changed (whenever setState or useState is called), this extension will create a snapshot of the current state tree and record it. Each snapshot will be displayed in Chrome DevTools under the Reactime panel.
-
-### Viewing
-
-You can click on a snapshot to view your app's state. State can be visualized in a JSON or a tree. Also, snapshots can be diffed with the previous snapshot, which can be viewed under the Diff tab.
-
-### Jumping
-
-Jumping is the most important feature of all. It allows you to jump to any previous recorded snapshots. Hitting the jump button on any snapshot will change the DOM by setting their state.
-
-### TypeScript Support
-
-Reactime offers beta support for TypeScript applications using stateful class components and functional components with useState hooks. Further testing and development is required for custom hooks, Context API, and Concurrent Mode.
-
-### Additional Features
-
-- multiple tree graph branches depicting state changes
-- tree graph hover functionality to view state changes
-- ability to pan and zoom tree graph
-- multiple tabs support
-- a slider to move through snapshots quickly
-- a play button to move through snapshots automatically
-- a pause button, which stops recording each snapshot
-- a lock button to freeze the DOM in place. setState will lose all functionality while the extension is locked
-- a persist button to keep snapshots upon refresh (handy when changing code and debugging)
-- export/import the current snapshots in memory
-- declarative titles in the actions panel
-- extended support for components with conditional state fields
-- a Sandbox utility to aid future expansion
-
-## Authors
-- **Carlos Perez** - [@crperezt](https://github.com/crperezt)
-- **Edwin Menendez** - [@edwinjmenendez](https://github.com/edwinjmenendez)
-- **Gabriela Jardim Aquino** - [@aquinojardim](https://github.com/aquinojardim)
-- **Gregory Panciera** - [@gpanciera](https://github.com/gpanciera)
-- **Nathanael Wa Mwenze** - [@nmwenz90](https://github.com/nmwenz90)
-- **Ryan Dang** - [@rydang](https://github.com/rydang)
-- **Bryan Lee** - [@mylee1995](https://github.com/mylee1995)
-- **Josh Kim** - [@joshua0308](https://github.com/joshua0308)
-- **Sierra Swaby** - [@starkspark](https://github.com/starkspark)
-- **Ruth Anam** - [@peachiecodes](https://github.com/peachiecodes)
-- **David Chai** - [@davidchaidev](https://github.com/davidchai717)
-- **Yujin Kang** - [@yujinkay](https://github.com/yujinkay)
-- **Andy Wong** - [@andywongdev](https://github.com/andywongdev)
-- **Chris Flannery** - [@chriswillsflannery](https://github.com/chriswillsflannery)
-- **Rajeeb Banstola** - [@rajeebthegreat](https://github.com/rajeebthegreat)
-- **Prasanna Malla** - [@prasmalla](https://github.com/prasmalla)
-- **Rocky Lin** - [@rocky9413](https://github.com/rocky9413)
-- **Abaas Khorrami** - [@dubalol](https://github.com/dubalol)
-- **Ergi Shehu** - [@Ergi516](https://github.com/ergi516)
-- **Raymond Kwan** - [@rkwn](https://github.com/rkwn)
-- **Joshua Howard** - [@Joshua-Howard](https://github.com/joshua-howard)
-
-## License
-
-This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
-
diff --git a/assets/AppStructureDiagram.png b/assets/AppStructureDiagram.png
deleted file mode 100644
index ff55c8d97..000000000
Binary files a/assets/AppStructureDiagram.png and /dev/null differ
diff --git a/assets/Back_End_Dependency_Chart_v22.jpg b/assets/Back_End_Dependency_Chart_v22.jpg
new file mode 100644
index 000000000..c7dfb3511
Binary files /dev/null and b/assets/Back_End_Dependency_Chart_v22.jpg differ
diff --git a/assets/DataFlowDiagram.PNG b/assets/DataFlowDiagram.PNG
deleted file mode 100644
index 8a50bbcfd..000000000
Binary files a/assets/DataFlowDiagram.PNG and /dev/null differ
diff --git a/assets/DataFlowDiagramV23.png b/assets/DataFlowDiagramV23.png
new file mode 100644
index 000000000..f835c0673
Binary files /dev/null and b/assets/DataFlowDiagramV23.png differ
diff --git a/assets/Front_End_Dependency_Chart_v22.jpg b/assets/Front_End_Dependency_Chart_v22.jpg
new file mode 100644
index 000000000..6f8d26937
Binary files /dev/null and b/assets/Front_End_Dependency_Chart_v22.jpg differ
diff --git a/assets/action-comparison.gif b/assets/action-comparison.gif
deleted file mode 100644
index 4a50300ce..000000000
Binary files a/assets/action-comparison.gif and /dev/null differ
diff --git a/assets/backend-recordSnapshot.png b/assets/backend-recordSnapshot.png
new file mode 100644
index 000000000..b3e9f1559
Binary files /dev/null and b/assets/backend-recordSnapshot.png differ
diff --git a/assets/backend-timeTravel.png b/assets/backend-timeTravel.png
new file mode 100644
index 000000000..eee1a4a23
Binary files /dev/null and b/assets/backend-timeTravel.png differ
diff --git a/assets/backend.png b/assets/backend.png
deleted file mode 100644
index 6ef582455..000000000
Binary files a/assets/backend.png and /dev/null differ
diff --git a/assets/components-viewing.gif b/assets/components-viewing.gif
deleted file mode 100644
index 0560b58f7..000000000
Binary files a/assets/components-viewing.gif and /dev/null differ
diff --git a/assets/frontend-diagram.png b/assets/frontend-diagram.png
index 9a46d39cb..84a6b03cb 100644
Binary files a/assets/frontend-diagram.png and b/assets/frontend-diagram.png differ
diff --git a/assets/frontend.png b/assets/frontend.png
deleted file mode 100644
index 9f5a30a3a..000000000
Binary files a/assets/frontend.png and /dev/null differ
diff --git a/assets/gifs/GeneralDemoGif_V26.gif b/assets/gifs/GeneralDemoGif_V26.gif
new file mode 100644
index 000000000..cae64e5de
Binary files /dev/null and b/assets/gifs/GeneralDemoGif_V26.gif differ
diff --git a/assets/gifs/ImportExportGif_V26.gif b/assets/gifs/ImportExportGif_V26.gif
new file mode 100644
index 000000000..4947ff1dd
Binary files /dev/null and b/assets/gifs/ImportExportGif_V26.gif differ
diff --git a/assets/gifs/ProviderConsumer_V26.gif b/assets/gifs/ProviderConsumer_V26.gif
new file mode 100644
index 000000000..ff436de8f
Binary files /dev/null and b/assets/gifs/ProviderConsumer_V26.gif differ
diff --git a/assets/gifs/TimeTravelGif_V26.gif b/assets/gifs/TimeTravelGif_V26.gif
new file mode 100644
index 000000000..e1d20bb71
Binary files /dev/null and b/assets/gifs/TimeTravelGif_V26.gif differ
diff --git a/assets/gifs/app_main_v26.png b/assets/gifs/app_main_v26.png
new file mode 100644
index 000000000..c0d9076fd
Binary files /dev/null and b/assets/gifs/app_main_v26.png differ
diff --git a/assets/console.gif b/assets/gifs/console.gif
similarity index 100%
rename from assets/console.gif
rename to assets/gifs/console.gif
diff --git a/assets/extension-console.gif b/assets/gifs/extension-console.gif
similarity index 100%
rename from assets/extension-console.gif
rename to assets/gifs/extension-console.gif
diff --git a/assets/reactime-console.gif b/assets/gifs/reactime-console.gif
similarity index 100%
rename from assets/reactime-console.gif
rename to assets/gifs/reactime-console.gif
diff --git a/assets/reactime-dev-setup.gif b/assets/gifs/reactime-dev-setup.gif
similarity index 100%
rename from assets/reactime-dev-setup.gif
rename to assets/gifs/reactime-dev-setup.gif
diff --git a/assets/history-tree.gif b/assets/history-tree.gif
deleted file mode 100644
index f53a30fce..000000000
Binary files a/assets/history-tree.gif and /dev/null differ
diff --git a/assets/logos/blackWhiteSquareIcon128.png b/assets/logos/blackWhiteSquareIcon128.png
new file mode 100644
index 000000000..9ff5c33e0
Binary files /dev/null and b/assets/logos/blackWhiteSquareIcon128.png differ
diff --git a/assets/logos/blackWhiteSquareIcon48.png b/assets/logos/blackWhiteSquareIcon48.png
new file mode 100644
index 000000000..d054e2b6c
Binary files /dev/null and b/assets/logos/blackWhiteSquareIcon48.png differ
diff --git a/assets/logos/marqueePromoTitle.png b/assets/logos/marqueePromoTitle.png
new file mode 100644
index 000000000..7c13a6d7e
Binary files /dev/null and b/assets/logos/marqueePromoTitle.png differ
diff --git a/assets/logos/smallPromoTitle.png b/assets/logos/smallPromoTitle.png
new file mode 100644
index 000000000..0074165eb
Binary files /dev/null and b/assets/logos/smallPromoTitle.png differ
diff --git a/assets/logos/whiteBlackSquareIcon128.png b/assets/logos/whiteBlackSquareIcon128.png
new file mode 100644
index 000000000..3f95221cb
Binary files /dev/null and b/assets/logos/whiteBlackSquareIcon128.png differ
diff --git a/assets/logos/whiteBlackSquareIcon48.png b/assets/logos/whiteBlackSquareIcon48.png
new file mode 100644
index 000000000..6788a2d02
Binary files /dev/null and b/assets/logos/whiteBlackSquareIcon48.png differ
diff --git a/assets/map-viewing.gif b/assets/map-viewing.gif
deleted file mode 100644
index e1028a540..000000000
Binary files a/assets/map-viewing.gif and /dev/null differ
diff --git a/assets/new-reactime.gif b/assets/new-reactime.gif
deleted file mode 100644
index 7eae93979..000000000
Binary files a/assets/new-reactime.gif and /dev/null differ
diff --git a/assets/nextjs.gif b/assets/nextjs.gif
deleted file mode 100644
index 5777a2751..000000000
Binary files a/assets/nextjs.gif and /dev/null differ
diff --git a/assets/obsolete/gifs/GeneralDemoGif_V23.gif b/assets/obsolete/gifs/GeneralDemoGif_V23.gif
new file mode 100644
index 000000000..4dc6f8924
Binary files /dev/null and b/assets/obsolete/gifs/GeneralDemoGif_V23.gif differ
diff --git a/assets/obsolete/gifs/ImportExportGif_V23.gif b/assets/obsolete/gifs/ImportExportGif_V23.gif
new file mode 100644
index 000000000..0b8d9f3da
Binary files /dev/null and b/assets/obsolete/gifs/ImportExportGif_V23.gif differ
diff --git a/assets/obsolete/gifs/PerformanceGif_V23.gif b/assets/obsolete/gifs/PerformanceGif_V23.gif
new file mode 100644
index 000000000..99b9bc1c4
Binary files /dev/null and b/assets/obsolete/gifs/PerformanceGif_V23.gif differ
diff --git a/assets/obsolete/gifs/TimeTravelGif_V23.gif b/assets/obsolete/gifs/TimeTravelGif_V23.gif
new file mode 100644
index 000000000..4e14f229b
Binary files /dev/null and b/assets/obsolete/gifs/TimeTravelGif_V23.gif differ
diff --git a/assets/obsolete/hooks-demo.gif b/assets/obsolete/hooks-demo.gif
deleted file mode 100644
index 1b662f51d..000000000
Binary files a/assets/obsolete/hooks-demo.gif and /dev/null differ
diff --git a/assets/obsolete/logos/blackWhiteSquareIcon.png b/assets/obsolete/logos/blackWhiteSquareIcon.png
new file mode 100644
index 000000000..4a15ecb29
Binary files /dev/null and b/assets/obsolete/logos/blackWhiteSquareIcon.png differ
diff --git a/assets/obsolete/logos/blackWhiteSquareIcon128_old.png b/assets/obsolete/logos/blackWhiteSquareIcon128_old.png
new file mode 100644
index 000000000..2e89a45da
Binary files /dev/null and b/assets/obsolete/logos/blackWhiteSquareIcon128_old.png differ
diff --git a/assets/obsolete/logos/blackWhiteSquareIcon48_old.png b/assets/obsolete/logos/blackWhiteSquareIcon48_old.png
new file mode 100644
index 000000000..298516b15
Binary files /dev/null and b/assets/obsolete/logos/blackWhiteSquareIcon48_old.png differ
diff --git a/assets/obsolete/logos/blackWhiteSquareLogo.png b/assets/obsolete/logos/blackWhiteSquareLogo.png
new file mode 100644
index 000000000..7203dabbf
Binary files /dev/null and b/assets/obsolete/logos/blackWhiteSquareLogo.png differ
diff --git a/assets/obsolete/logos/blackWhiteSquareLogoMedium.png b/assets/obsolete/logos/blackWhiteSquareLogoMedium.png
new file mode 100644
index 000000000..c283491ea
Binary files /dev/null and b/assets/obsolete/logos/blackWhiteSquareLogoMedium.png differ
diff --git a/assets/obsolete/logos/blackWhiteSquareSite.png b/assets/obsolete/logos/blackWhiteSquareSite.png
new file mode 100644
index 000000000..fc5cbb02a
Binary files /dev/null and b/assets/obsolete/logos/blackWhiteSquareSite.png differ
diff --git a/assets/obsolete/logos/marqueePromoTitle.png b/assets/obsolete/logos/marqueePromoTitle.png
new file mode 100644
index 000000000..e47d77771
Binary files /dev/null and b/assets/obsolete/logos/marqueePromoTitle.png differ
diff --git a/assets/obsolete/logos/marqueePromoTitle_old.png b/assets/obsolete/logos/marqueePromoTitle_old.png
new file mode 100644
index 000000000..e47d77771
Binary files /dev/null and b/assets/obsolete/logos/marqueePromoTitle_old.png differ
diff --git a/assets/obsolete/logos/smallPromoTitle.png b/assets/obsolete/logos/smallPromoTitle.png
new file mode 100644
index 000000000..254f85d69
Binary files /dev/null and b/assets/obsolete/logos/smallPromoTitle.png differ
diff --git a/assets/obsolete/logos/smallPromoTitle_old.png b/assets/obsolete/logos/smallPromoTitle_old.png
new file mode 100644
index 000000000..254f85d69
Binary files /dev/null and b/assets/obsolete/logos/smallPromoTitle_old.png differ
diff --git a/assets/obsolete/logos/whiteBlackSquareIcon.png b/assets/obsolete/logos/whiteBlackSquareIcon.png
new file mode 100644
index 000000000..70592ee34
Binary files /dev/null and b/assets/obsolete/logos/whiteBlackSquareIcon.png differ
diff --git a/assets/obsolete/logos/whiteBlackSquareIcon128.png b/assets/obsolete/logos/whiteBlackSquareIcon128.png
new file mode 100644
index 000000000..9749d8d41
Binary files /dev/null and b/assets/obsolete/logos/whiteBlackSquareIcon128.png differ
diff --git a/assets/obsolete/logos/whiteBlackSquareIcon48.png b/assets/obsolete/logos/whiteBlackSquareIcon48.png
new file mode 100644
index 000000000..b5b1ef559
Binary files /dev/null and b/assets/obsolete/logos/whiteBlackSquareIcon48.png differ
diff --git a/assets/obsolete/logos/whiteBlackSquareLogo.png b/assets/obsolete/logos/whiteBlackSquareLogo.png
new file mode 100644
index 000000000..c8756bb01
Binary files /dev/null and b/assets/obsolete/logos/whiteBlackSquareLogo.png differ
diff --git a/assets/obsolete/logos/whiteBlackSquareSite.png b/assets/obsolete/logos/whiteBlackSquareSite.png
new file mode 100644
index 000000000..15b4af999
Binary files /dev/null and b/assets/obsolete/logos/whiteBlackSquareSite.png differ
diff --git a/assets/obsolete/readme-logo-300.png b/assets/obsolete/readme-logo-300.png
deleted file mode 100644
index 51e1baf48..000000000
Binary files a/assets/obsolete/readme-logo-300.png and /dev/null differ
diff --git a/assets/obsolete/readme-logo-small.png b/assets/obsolete/readme-logo-small.png
deleted file mode 100644
index 6695a5c86..000000000
Binary files a/assets/obsolete/readme-logo-small.png and /dev/null differ
diff --git a/assets/oldDataflowDiagram.jpg b/assets/oldDataflowDiagram.jpg
deleted file mode 100644
index 41d5e4230..000000000
Binary files a/assets/oldDataflowDiagram.jpg and /dev/null differ
diff --git a/assets/react-calculator-demo.gif b/assets/react-calculator-demo.gif
deleted file mode 100644
index d1a8e8807..000000000
Binary files a/assets/react-calculator-demo.gif and /dev/null differ
diff --git a/assets/reactime with website svg.svg b/assets/reactime with website svg.svg
deleted file mode 100644
index 3356a87b3..000000000
--- a/assets/reactime with website svg.svg
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/reactime-2022-workflow.png b/assets/reactime-2022-workflow.png
deleted file mode 100644
index 90d2fdc66..000000000
Binary files a/assets/reactime-2022-workflow.png and /dev/null differ
diff --git a/assets/reactime7.gif b/assets/reactime7.gif
deleted file mode 100644
index 183347fb4..000000000
Binary files a/assets/reactime7.gif and /dev/null differ
diff --git a/assets/readme-logo-300-no-version.png b/assets/readme-logo-300-no-version.png
deleted file mode 100644
index e1f788fbf..000000000
Binary files a/assets/readme-logo-300-no-version.png and /dev/null differ
diff --git a/assets/readme-logo-small-no-version.png b/assets/readme-logo-small-no-version.png
deleted file mode 100644
index 3609df502..000000000
Binary files a/assets/readme-logo-small-no-version.png and /dev/null differ
diff --git a/assets/snapshot-comparison.gif b/assets/snapshot-comparison.gif
deleted file mode 100644
index d6a3860b4..000000000
Binary files a/assets/snapshot-comparison.gif and /dev/null differ
diff --git a/demo-app-next/.gitignore b/demo-app-next/.gitignore
new file mode 100644
index 000000000..20fccdd4b
--- /dev/null
+++ b/demo-app-next/.gitignore
@@ -0,0 +1,30 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
diff --git a/demo-app-next/README.md b/demo-app-next/README.md
new file mode 100644
index 000000000..02695bc1d
--- /dev/null
+++ b/demo-app-next/README.md
@@ -0,0 +1 @@
+This is a starter template for [Learn Next.js](https://nextjs.org/learn).
\ No newline at end of file
diff --git a/demo-app-next/next-env.d.ts b/demo-app-next/next-env.d.ts
new file mode 100644
index 000000000..a4a7b3f5c
--- /dev/null
+++ b/demo-app-next/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
diff --git a/demo-app-next/package.json b/demo-app-next/package.json
new file mode 100644
index 000000000..0f7a13bba
--- /dev/null
+++ b/demo-app-next/package.json
@@ -0,0 +1,18 @@
+{
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "next": "latest",
+ "react": "18.2.0",
+ "react-dom": "18.2.0"
+ },
+ "devDependencies": {
+ "@types/node": "18.15.0",
+ "@types/react": "18.0.28",
+ "typescript": "4.9.5"
+ }
+}
diff --git a/demo-app-next/public/favicon.ico b/demo-app-next/public/favicon.ico
new file mode 100644
index 000000000..4965832f2
Binary files /dev/null and b/demo-app-next/public/favicon.ico differ
diff --git a/demo-app-next/public/vercel.svg b/demo-app-next/public/vercel.svg
new file mode 100644
index 000000000..fbf0e25a6
--- /dev/null
+++ b/demo-app-next/public/vercel.svg
@@ -0,0 +1,4 @@
+
+
+
\ No newline at end of file
diff --git a/demo-app-next/src/components/Board.tsx b/demo-app-next/src/components/Board.tsx
new file mode 100644
index 000000000..950f292df
--- /dev/null
+++ b/demo-app-next/src/components/Board.tsx
@@ -0,0 +1,136 @@
+import React, { Component } from 'react';
+import Row from './Row';
+import { BoardContent, Scoreboard, Player } from '../types/types';
+
+type BoardState = {
+ board: BoardContent;
+ currentPlayer: Player;
+ gameOver: boolean;
+ message: string;
+ scoreboard: Scoreboard;
+};
+
+class Board extends Component<{}, BoardState> {
+ constructor(props: unknown) {
+ super(props);
+ this.state = {
+ board: this.newBoard(),
+ currentPlayer: 'X',
+ gameOver: false,
+ message: '',
+ scoreboard: { X: 0, O: 0 },
+ };
+
+ this.resetBoard = this.resetBoard.bind(this);
+ this.handleBoxClick = this.handleBoxClick.bind(this);
+ }
+
+ componentDidUpdate(): void {
+ this.checkForWinner();
+ }
+
+ /**
+ * @method newBoard
+ * @description - returns a blank BoardContent array,
+ * for the start of a new game
+ */
+ newBoard(): BoardContent {
+ return [
+ ['-', '-', '-'],
+ ['-', '-', '-'],
+ ['-', '-', '-'],
+ ];
+ }
+
+ /**
+ * @method resetBoard
+ * @description - sets to board object to be all '-',
+ * and sets gameOver and message to default state
+ */
+ resetBoard(): void {
+ this.setState({
+ gameOver: false,
+ board: this.newBoard(),
+ message: '',
+ });
+ }
+
+ /**
+ * @method checkForWinner
+ * @description - checks to see if either player has filled a row
+ * if so, ends the game and updates the message to declare winner
+ */
+ checkForWinner(): void {
+ const { board, gameOver, currentPlayer } = this.state;
+
+ const spacesLeft = (): boolean => {
+ for (let i of board) {
+ if (i.includes('-')) return true;
+ }
+ return false;
+ };
+
+ if (!gameOver) {
+ // win conditions: matching rows, columns, or diagonals, that are not empty('-')
+ if (
+ (board[0][0] === board[0][1] && board[0][1] === board[0][2] && board[0][2] !== '-') ||
+ (board[1][0] === board[1][1] && board[1][1] === board[1][2] && board[1][2] !== '-') ||
+ (board[2][0] === board[2][1] && board[2][1] === board[2][2] && board[2][2] !== '-') ||
+ (board[0][0] === board[1][0] && board[1][0] === board[2][0] && board[2][0] !== '-') ||
+ (board[0][1] === board[1][1] && board[1][1] === board[2][1] && board[2][1] !== '-') ||
+ (board[0][2] === board[1][2] && board[1][2] === board[2][2] && board[2][2] !== '-') ||
+ (board[0][0] === board[1][1] && board[1][1] === board[2][2] && board[2][2] !== '-') ||
+ (board[2][0] === board[1][1] && board[1][1] === board[0][2] && board[0][2] !== '-')
+ ) {
+ // winner is the person who's turn was previous
+ const winner: Player = currentPlayer === 'X' ? 'O' : 'X';
+
+ this.setState({
+ gameOver: true,
+ message: `Player ${winner} wins!`,
+ });
+
+ // draw condition: no '-' remaining in board without above win condition triggering
+ } else if (!spacesLeft()) {
+ this.setState({
+ gameOver: true,
+ message: 'Draw!',
+ });
+ }
+ }
+ }
+
+ handleBoxClick(row: number, column: number): void {
+ const boardCopy: BoardContent = [
+ [...this.state.board[0]],
+ [...this.state.board[1]],
+ [...this.state.board[2]],
+ ];
+ boardCopy[row][column] = this.state.currentPlayer;
+ const newPlayer: Player = this.state.currentPlayer === 'X' ? 'O' : 'X';
+ this.setState({ board: boardCopy, currentPlayer: newPlayer });
+ }
+
+ render(): JSX.Element {
+ const rows: Array
= [];
+ for (let i = 0; i < 3; i++) {
+ rows.push(
+
,
+ );
+ }
+ // const { X, O }: Scoreboard = this.state.scoreboard;
+
+ return (
+
+
Tic Tac Toe
+ {this.state.gameOver && {this.state.message} }
+ {rows}
+
+ Reset
+
+
+ );
+ }
+}
+
+export default Board;
diff --git a/demo-app-next/src/components/Box.tsx b/demo-app-next/src/components/Box.tsx
new file mode 100644
index 000000000..f44c00d62
--- /dev/null
+++ b/demo-app-next/src/components/Box.tsx
@@ -0,0 +1,18 @@
+import { BoardText } from '../types/types';
+
+type BoxProps = {
+ value: BoardText;
+ row: number;
+ column: number;
+ handleBoxClick: (row: number, column: number) => void;
+};
+
+const Box = (props: BoxProps): JSX.Element => {
+ return (
+ props.handleBoxClick(props.row, props.column)}>
+ {props.value}
+
+ );
+};
+
+export default Box;
diff --git a/demo-app-next/src/components/Buttons.tsx b/demo-app-next/src/components/Buttons.tsx
new file mode 100644
index 000000000..184e30acf
--- /dev/null
+++ b/demo-app-next/src/components/Buttons.tsx
@@ -0,0 +1,19 @@
+import Increment from './Increment';
+
+export default function Buttons(): JSX.Element {
+ const buttons = [];
+ for (let i = 0; i < 4; i++) {
+ buttons.push( );
+ }
+
+ return (
+
+
Stateful Buttons
+
+ These buttons are functional components that each manage their own state with the useState
+ hook.
+
+ {buttons}
+
+ );
+}
diff --git a/demo-app-next/src/components/Increment.tsx b/demo-app-next/src/components/Increment.tsx
new file mode 100644
index 000000000..791f08f23
--- /dev/null
+++ b/demo-app-next/src/components/Increment.tsx
@@ -0,0 +1,11 @@
+import React, { useState } from 'react';
+
+export default function Increment(): JSX.Element {
+ const [count, setCount] = useState(0);
+
+ return (
+ setCount(count + 1)}>
+ You clicked me {count} times.
+
+ );
+}
diff --git a/demo-app-next/src/components/Row.tsx b/demo-app-next/src/components/Row.tsx
new file mode 100644
index 000000000..961a83c73
--- /dev/null
+++ b/demo-app-next/src/components/Row.tsx
@@ -0,0 +1,27 @@
+import Box from './Box';
+import { BoardText } from '../types/types';
+
+type RowProps = {
+ handleBoxClick: (row: number, column: number) => void;
+ values: Array;
+ row: number;
+};
+
+const Row = (props: RowProps) => {
+ const boxes: Array = [];
+ for (let i = 0; i < 3; i++) {
+ boxes.push(
+ ,
+ );
+ }
+
+ return {boxes}
;
+};
+
+export default Row;
diff --git a/demo-app-next/src/components/navbar.tsx b/demo-app-next/src/components/navbar.tsx
new file mode 100644
index 000000000..b841698ea
--- /dev/null
+++ b/demo-app-next/src/components/navbar.tsx
@@ -0,0 +1,17 @@
+import Link from 'next/link';
+
+export default function Navbar(): JSX.Element {
+ return (
+
+
+ About
+
+
+ Tic-Tac-Toe
+
+
+ Counter
+
+
+ );
+}
diff --git a/demo-app-next/src/pages/_app.tsx b/demo-app-next/src/pages/_app.tsx
new file mode 100644
index 000000000..279f38d6b
--- /dev/null
+++ b/demo-app-next/src/pages/_app.tsx
@@ -0,0 +1,6 @@
+import '../../styles/style.css';
+import React from 'react';
+
+export default function MyApp({ Component, pageProps }): JSX.Element {
+ return ;
+}
diff --git a/demo-app-next/src/pages/buttons/index.tsx b/demo-app-next/src/pages/buttons/index.tsx
new file mode 100644
index 000000000..4e0b24237
--- /dev/null
+++ b/demo-app-next/src/pages/buttons/index.tsx
@@ -0,0 +1,11 @@
+import Buttons from '../../components/Buttons';
+import Navbar from '../../components/navbar';
+
+export default function ButtonsPage(): JSX.Element {
+ return (
+
+
+
+
+ );
+}
diff --git a/demo-app-next/src/pages/index.tsx b/demo-app-next/src/pages/index.tsx
new file mode 100644
index 000000000..5bcd002d3
--- /dev/null
+++ b/demo-app-next/src/pages/index.tsx
@@ -0,0 +1,29 @@
+import Navbar from '../components/navbar';
+import React from 'react';
+
+export default function Home(): JSX.Element {
+ return (
+
+
+
+
Lorem Ipsum
+
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
+ ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
+ ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
+ reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
+ sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
+ est laborum."
+
+
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
+ ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
+ ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
+ reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
+ sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
+ est laborum."
+
+
+
+ );
+}
diff --git a/demo-app-next/src/pages/tictactoe/index.tsx b/demo-app-next/src/pages/tictactoe/index.tsx
new file mode 100644
index 000000000..d2376d215
--- /dev/null
+++ b/demo-app-next/src/pages/tictactoe/index.tsx
@@ -0,0 +1,11 @@
+import Board from '../../components/Board';
+import Navbar from '../../components/navbar';
+
+export default function BoardPage(): JSX.Element {
+ return (
+
+
+
+
+ );
+}
diff --git a/demo-app-next/src/types/types.ts b/demo-app-next/src/types/types.ts
new file mode 100644
index 000000000..cc8252e42
--- /dev/null
+++ b/demo-app-next/src/types/types.ts
@@ -0,0 +1,10 @@
+export type Scoreboard = {
+ X: number;
+ O: number;
+};
+
+export type Player = 'X' | 'O';
+
+export type BoardText = 'X' | 'O' | '-';
+
+export type BoardContent = Array>;
diff --git a/demo-app-next/styles/Home.module.css b/demo-app-next/styles/Home.module.css
new file mode 100644
index 000000000..b82575626
--- /dev/null
+++ b/demo-app-next/styles/Home.module.css
@@ -0,0 +1,91 @@
+.container {
+ min-height: 100vh;
+ padding: 0 0.5rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.title a {
+ color: #0070f3;
+ text-decoration: none;
+}
+
+.title a:hover,
+.title a:focus,
+.title a:active {
+ text-decoration: underline;
+}
+
+.title {
+ margin: 0 0 1rem;
+ line-height: 1.15;
+ font-size: 3.6rem;
+}
+
+.title {
+ text-align: center;
+}
+
+.title,
+.description {
+ text-align: center;
+}
+
+
+.description {
+ line-height: 1.5;
+ font-size: 1.5rem;
+}
+
+.grid {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-wrap: wrap;
+
+ max-width: 800px;
+ margin-top: 3rem;
+}
+
+.card {
+ margin: 1rem;
+ flex-basis: 45%;
+ padding: 1.5rem;
+ text-align: left;
+ color: inherit;
+ text-decoration: none;
+ border: 1px solid #eaeaea;
+ border-radius: 10px;
+ transition: color 0.15s ease, border-color 0.15s ease;
+}
+
+.card:hover,
+.card:focus,
+.card:active {
+ color: #0070f3;
+ border-color: #0070f3;
+}
+
+.card h3 {
+ margin: 0 0 1rem 0;
+ font-size: 1.5rem;
+}
+
+.card p {
+ margin: 0;
+ font-size: 1.25rem;
+ line-height: 1.5;
+}
+
+.logo {
+ height: 1em;
+}
+
+@media (max-width: 600px) {
+ .grid {
+ width: 100%;
+ flex-direction: column;
+ }
+}
diff --git a/demo-app-next/styles/globals.css b/demo-app-next/styles/globals.css
new file mode 100644
index 000000000..6c7e3c462
--- /dev/null
+++ b/demo-app-next/styles/globals.css
@@ -0,0 +1,149 @@
+body {
+ margin: 0;
+ font-family: Arial, Helvetica, sans-serif;
+ background-color: #fff4f4;
+}
+
+h1,
+h4 {
+ text-align: center;
+}
+
+/* Navbar */
+
+.nav {
+ background-color: #ff6569;
+
+ display: flex;
+ justify-content: space-evenly;
+
+ padding: 30px;
+ height: 30px;
+}
+
+.link {
+ flex-grow: 1;
+
+ font-size: 1.5em;
+ text-decoration: none;
+ text-align: center;
+
+ color: #fff4f4;
+}
+
+.link:hover {
+ font-size: 2em;
+}
+
+/* About */
+
+.about {
+ background-color: #ffffff;
+ color: #330002;
+
+ padding-top: 1em;
+ padding-bottom: 2em;
+ padding-right: 4em;
+ padding-left: 4em;
+ margin-top: 2em;
+
+ max-width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+/* Tic-Tac-Toe */
+
+.board {
+ background-color: #ffffff;
+ color: #330002;
+
+ margin-top: 2em;
+
+ padding-top: 1em;
+ padding-bottom: 1em;
+ padding-left: 4em;
+ padding-right: 4em;
+
+ width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+.box {
+ background-color: #62d6fb;
+ border-style: solid;
+ border-color: #ffffff;
+ border-radius: 5px;
+
+ height: 100px;
+ width: 100px;
+
+ font-size: 4em;
+}
+
+#reset {
+ color: #ff6569;
+ font-size: 1.5em;
+
+ background-color: #ffffff;
+ border-style: solid;
+ border-color: #ff6569;
+ border-radius: 5px;
+
+ margin-top: 20px;
+ margin-bottom: 20px;
+
+ width: 100%;
+
+ padding: 0.5em;
+}
+
+#reset:hover {
+ color: #ffffff;
+ background-color: #ff6569;
+}
+
+/* Counter */
+
+.buttons {
+ background-color: #ffffff;
+ color: #330002;
+
+ padding-top: 1em;
+ padding-bottom: 2em;
+ padding-right: 4em;
+ padding-left: 4em;
+ margin-top: 2em;
+
+ max-width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+.increment {
+ color: #ffffff;
+ font-size: 1.5em;
+
+ background-color: #ff6569;
+ border-style: solid;
+ border-color: #ffffff;
+ border-radius: 5px;
+
+ margin-top: 20px;
+ margin-bottom: 20px;
+
+ width: 100%;
+
+ padding: 0.5em;
+}
+
+.increment:hover {
+ background-color: #62d6fb;
+}
diff --git a/demo-app-next/styles/style.css b/demo-app-next/styles/style.css
new file mode 100644
index 000000000..6c7e3c462
--- /dev/null
+++ b/demo-app-next/styles/style.css
@@ -0,0 +1,149 @@
+body {
+ margin: 0;
+ font-family: Arial, Helvetica, sans-serif;
+ background-color: #fff4f4;
+}
+
+h1,
+h4 {
+ text-align: center;
+}
+
+/* Navbar */
+
+.nav {
+ background-color: #ff6569;
+
+ display: flex;
+ justify-content: space-evenly;
+
+ padding: 30px;
+ height: 30px;
+}
+
+.link {
+ flex-grow: 1;
+
+ font-size: 1.5em;
+ text-decoration: none;
+ text-align: center;
+
+ color: #fff4f4;
+}
+
+.link:hover {
+ font-size: 2em;
+}
+
+/* About */
+
+.about {
+ background-color: #ffffff;
+ color: #330002;
+
+ padding-top: 1em;
+ padding-bottom: 2em;
+ padding-right: 4em;
+ padding-left: 4em;
+ margin-top: 2em;
+
+ max-width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+/* Tic-Tac-Toe */
+
+.board {
+ background-color: #ffffff;
+ color: #330002;
+
+ margin-top: 2em;
+
+ padding-top: 1em;
+ padding-bottom: 1em;
+ padding-left: 4em;
+ padding-right: 4em;
+
+ width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+.box {
+ background-color: #62d6fb;
+ border-style: solid;
+ border-color: #ffffff;
+ border-radius: 5px;
+
+ height: 100px;
+ width: 100px;
+
+ font-size: 4em;
+}
+
+#reset {
+ color: #ff6569;
+ font-size: 1.5em;
+
+ background-color: #ffffff;
+ border-style: solid;
+ border-color: #ff6569;
+ border-radius: 5px;
+
+ margin-top: 20px;
+ margin-bottom: 20px;
+
+ width: 100%;
+
+ padding: 0.5em;
+}
+
+#reset:hover {
+ color: #ffffff;
+ background-color: #ff6569;
+}
+
+/* Counter */
+
+.buttons {
+ background-color: #ffffff;
+ color: #330002;
+
+ padding-top: 1em;
+ padding-bottom: 2em;
+ padding-right: 4em;
+ padding-left: 4em;
+ margin-top: 2em;
+
+ max-width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+.increment {
+ color: #ffffff;
+ font-size: 1.5em;
+
+ background-color: #ff6569;
+ border-style: solid;
+ border-color: #ffffff;
+ border-radius: 5px;
+
+ margin-top: 20px;
+ margin-bottom: 20px;
+
+ width: 100%;
+
+ padding: 0.5em;
+}
+
+.increment:hover {
+ background-color: #62d6fb;
+}
diff --git a/www/tsconfig.json b/demo-app-next/tsconfig.json
similarity index 58%
rename from www/tsconfig.json
rename to demo-app-next/tsconfig.json
index 658068a27..1203d7cb2 100644
--- a/www/tsconfig.json
+++ b/demo-app-next/tsconfig.json
@@ -1,21 +1,30 @@
{
"compilerOptions": {
- "target": "es2017",
- "lib": ["dom", "dom.iterable", "esnext"],
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
"allowJs": true,
"skipLibCheck": true,
- "strict": true,
+ "strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
+ "incremental": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
- "incremental": true,
- "noUncheckedIndexedAccess": true
+ "target": "ES2017"
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.cjs", "**/*.mjs"],
- "exclude": ["node_modules"]
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
}
diff --git a/demo-app-remix/.eslintrc.js b/demo-app-remix/.eslintrc.js
new file mode 100644
index 000000000..f2faf1470
--- /dev/null
+++ b/demo-app-remix/.eslintrc.js
@@ -0,0 +1,4 @@
+/** @type {import('eslint').Linter.Config} */
+module.exports = {
+ extends: ['@remix-run/eslint-config', '@remix-run/eslint-config/node'],
+};
diff --git a/demo-app-remix/.gitignore b/demo-app-remix/.gitignore
new file mode 100644
index 000000000..3f7bf98da
--- /dev/null
+++ b/demo-app-remix/.gitignore
@@ -0,0 +1,6 @@
+node_modules
+
+/.cache
+/build
+/public/build
+.env
diff --git a/demo-app-remix/README.md b/demo-app-remix/README.md
new file mode 100644
index 000000000..a456eb3b6
--- /dev/null
+++ b/demo-app-remix/README.md
@@ -0,0 +1,51 @@
+# Welcome to Remix!
+
+- [Remix Docs](https://remix.run/docs)
+
+## Development
+
+Start the Remix development asset server and the Express server by running:
+
+```sh
+npm run dev
+```
+
+This starts your app in development mode, which will purge the server require cache when Remix rebuilds assets so you don't need a process manager restarting the express server.
+
+## Deployment
+
+First, build your app for production:
+
+```sh
+npm run build
+```
+
+Then run the app in production mode:
+
+```sh
+npm start
+```
+
+Now you'll need to pick a host to deploy it to.
+
+### DIY
+
+If you're familiar with deploying express applications you should be right at home just make sure to deploy the output of `remix build`
+
+- `build/`
+- `public/build/`
+
+### Using a Template
+
+When you ran `npx create-remix@latest` there were a few choices for hosting. You can run that again to create a new project, then copy over your `app/` folder to the new project that's pre-configured for your target server.
+
+```sh
+cd ..
+# create a new project, and pick a pre-configured host
+npx create-remix@latest
+cd my-new-remix-app
+# remove the new project's app (not the old one!)
+rm -rf app
+# copy your app over
+cp -R ../my-old-remix-app/app app
+```
diff --git a/demo-app-remix/app/components/Board.tsx b/demo-app-remix/app/components/Board.tsx
new file mode 100644
index 000000000..9eeb7ed58
--- /dev/null
+++ b/demo-app-remix/app/components/Board.tsx
@@ -0,0 +1,137 @@
+import React, { Component } from 'react';
+import Row from './Row';
+import type { BoardContent, Scoreboard, Player } from '../types/types';
+import type { BoardText } from '../types/types';
+
+type BoardState = {
+ board: BoardContent;
+ currentPlayer: Player;
+ gameOver: boolean;
+ message: string;
+ scoreboard: Scoreboard;
+};
+
+class Board extends Component<{}, BoardState> {
+ constructor(props: any) {
+ super(props);
+ this.state = {
+ board: this.newBoard(),
+ currentPlayer: 'X',
+ gameOver: false,
+ message: '',
+ scoreboard: { X: 0, O: 0 },
+ };
+
+ this.resetBoard = this.resetBoard.bind(this);
+ this.handleBoxClick = this.handleBoxClick.bind(this);
+ }
+
+ componentDidUpdate() {
+ this.checkForWinner();
+ }
+
+ /**
+ * @method newBoard
+ * @description - returns a blank BoardContent array,
+ * for the start of a new game
+ */
+ newBoard(): BoardContent {
+ return [
+ ['-', '-', '-'],
+ ['-', '-', '-'],
+ ['-', '-', '-'],
+ ];
+ }
+
+ /**
+ * @method resetBoard
+ * @description - sets to board object to be all '-',
+ * and sets gameOver and message to default state
+ */
+ resetBoard(): void {
+ this.setState({
+ gameOver: false,
+ board: this.newBoard(),
+ message: '',
+ });
+ }
+
+ /**
+ * @method checkForWinner
+ * @description - checks to see if either player has filled a row
+ * if so, ends the game and updates the message to declare winner
+ */
+ checkForWinner(): void {
+ const { board, gameOver, currentPlayer } = this.state;
+
+ const spacesLeft = (): boolean => {
+ for (let i of board) {
+ if (i.includes('-')) return true;
+ }
+ return false;
+ };
+
+ if (!gameOver) {
+ // win conditions: matching rows, columns, or diagonals, that are not empty('-')
+ if (
+ (board[0][0] === board[0][1] && board[0][1] === board[0][2] && board[0][2] !== '-') ||
+ (board[1][0] === board[1][1] && board[1][1] === board[1][2] && board[1][2] !== '-') ||
+ (board[2][0] === board[2][1] && board[2][1] === board[2][2] && board[2][2] !== '-') ||
+ (board[0][0] === board[1][0] && board[1][0] === board[2][0] && board[2][0] !== '-') ||
+ (board[0][1] === board[1][1] && board[1][1] === board[2][1] && board[2][1] !== '-') ||
+ (board[0][2] === board[1][2] && board[1][2] === board[2][2] && board[2][2] !== '-') ||
+ (board[0][0] === board[1][1] && board[1][1] === board[2][2] && board[2][2] !== '-') ||
+ (board[2][0] === board[1][1] && board[1][1] === board[0][2] && board[0][2] !== '-')
+ ) {
+ // winner is the person who's turn was previous
+ const winner: Player = currentPlayer === 'X' ? 'O' : 'X';
+
+ this.setState({
+ gameOver: true,
+ message: `Player ${winner} wins!`,
+ });
+
+ // draw condition: no '-' remaining in board without above win condition triggering
+ } else if (!spacesLeft()) {
+ this.setState({
+ gameOver: true,
+ message: 'Draw!',
+ });
+ }
+ }
+ }
+
+ handleBoxClick(row: number, column: number): void {
+ const boardCopy: BoardContent = [
+ [...this.state.board[0]],
+ [...this.state.board[1]],
+ [...this.state.board[2]],
+ ];
+ boardCopy[row][column] = this.state.currentPlayer;
+ const newPlayer: Player = this.state.currentPlayer === 'X' ? 'O' : 'X';
+ this.setState({ board: boardCopy, currentPlayer: newPlayer });
+ }
+
+ render() {
+ const rows: Array = [];
+ for (let i = 0; i < 3; i++) {
+ rows.push(
+
,
+ );
+ }
+ const { X, O }: Scoreboard = this.state.scoreboard;
+
+ return (
+
+
Tic Tac Toe
+ {this.state.gameOver && {this.state.message} }
+ {rows}
+
+ Reset
+
+
+ );
+ }
+}
+
+export default Board;
diff --git a/demo-app-remix/app/components/Box.tsx b/demo-app-remix/app/components/Box.tsx
new file mode 100644
index 000000000..038a557f3
--- /dev/null
+++ b/demo-app-remix/app/components/Box.tsx
@@ -0,0 +1,18 @@
+import type { BoardText } from '../types/types';
+
+type BoxProps = {
+ value: BoardText;
+ row: number;
+ column: number;
+ handleBoxClick: (row: number, column: number) => void;
+};
+
+const Box = (props: BoxProps) => {
+ return (
+ props.handleBoxClick(props.row, props.column)}>
+ {props.value}
+
+ );
+};
+
+export default Box;
diff --git a/demo-app-remix/app/components/Buttons.tsx b/demo-app-remix/app/components/Buttons.tsx
new file mode 100644
index 000000000..33f154acb
--- /dev/null
+++ b/demo-app-remix/app/components/Buttons.tsx
@@ -0,0 +1,21 @@
+import Increment from './Increment';
+
+function Buttons() {
+ const buttons = [];
+ for (let i = 0; i < 4; i++) {
+ buttons.push( );
+ }
+
+ return (
+
+
Stateful Buttons
+
+ These buttons are functional components that each manage their own state with the useState
+ hook.
+
+ {buttons}
+
+ );
+}
+
+export default Buttons;
diff --git a/demo-app-remix/app/components/Buttons2.tsx b/demo-app-remix/app/components/Buttons2.tsx
new file mode 100644
index 000000000..de0161a9b
--- /dev/null
+++ b/demo-app-remix/app/components/Buttons2.tsx
@@ -0,0 +1,38 @@
+// import StateButton from "./StateButton";
+// import EffectButton from "./EffectButton";
+// import RefComponent from "./RefComponent";
+// import ContextButton from "./ContextButton";
+// import { useState, useEffect, useRef, createContext } from "react";
+
+// export const ButtonContext: any = createContext(null);
+
+// export default function Buttons() {
+// const [count, setCount] = useState(0);
+// const [effectCount, setEffectCount] = useState(0);
+// const renders = useRef(-1);
+
+// useEffect(() => {
+// renders.current = renders.current + 1;
+// document.title = `You clicked ${effectCount} times`;
+// }, [count, effectCount]);
+
+// return (
+//
+//
React Hook Buttons
+//
+// These buttons are functional components that manage their own state with
+// different react hooks.
+//
+// {/* {buttons} */}
+//
+//
+//
A box renders once useRef count is 3
+//
= 3 ? "show" : "hide"}>
+//
+//
+//
+//
+//
+//
+// );
+// }
diff --git a/demo-app-remix/app/components/ContextButton.tsx b/demo-app-remix/app/components/ContextButton.tsx
new file mode 100644
index 000000000..175a8a44b
--- /dev/null
+++ b/demo-app-remix/app/components/ContextButton.tsx
@@ -0,0 +1,20 @@
+// import { validateHeaderValue } from "http";
+// import { useContext } from "react";
+// import { ButtonContext } from "./Buttons";
+
+// export default function ContextButton() {
+// //const [count, setCount] = useState(0);
+
+// // const [count, setCount] = useContext(ButtonContext);
+// const { value }: any = useContext(ButtonContext);
+// const [count, setCount] = value;
+
+// return (
+//
+//
This button tests the useContext hook
+// setCount(count + 1)}>
+// Click to increment: {count}
+//
+//
+// );
+// }
diff --git a/demo-app-remix/app/components/EffectButton.tsx b/demo-app-remix/app/components/EffectButton.tsx
new file mode 100644
index 000000000..b5c242247
--- /dev/null
+++ b/demo-app-remix/app/components/EffectButton.tsx
@@ -0,0 +1,18 @@
+// import React, { useState, useEffect, useRef } from "react";
+
+// export default function StateButton(props: any) {
+// //const [count, setCount] = useState(0);
+
+// return (
+//
+//
This button tests the UseEffect hook
+// props.setEffectCount(props.effectCount + 1)}
+// >
+// {/* You clicked me {count} times. */}
+// Click to update doc title
+//
+//
+// );
+// }
diff --git a/demo-app/src/client/Components/Increment.tsx b/demo-app-remix/app/components/Increment.tsx
similarity index 76%
rename from demo-app/src/client/Components/Increment.tsx
rename to demo-app-remix/app/components/Increment.tsx
index 73fc98650..6e6486908 100644
--- a/demo-app/src/client/Components/Increment.tsx
+++ b/demo-app-remix/app/components/Increment.tsx
@@ -4,7 +4,7 @@ function Increment() {
const [count, setCount] = useState(0);
return (
- setCount(count + 1)}>
+ setCount(count + 1)}>
You clicked me {count} times.
);
diff --git a/demo-app-remix/app/components/RefComponent.tsx b/demo-app-remix/app/components/RefComponent.tsx
new file mode 100644
index 000000000..938e82908
--- /dev/null
+++ b/demo-app-remix/app/components/RefComponent.tsx
@@ -0,0 +1,7 @@
+// export default function RefComponent(props: any) {
+// return (
+//
+//
{`Render count: ${props.counter}`}
+//
+// );
+// }
diff --git a/demo-app-remix/app/components/Row.tsx b/demo-app-remix/app/components/Row.tsx
new file mode 100644
index 000000000..011b7a8ae
--- /dev/null
+++ b/demo-app-remix/app/components/Row.tsx
@@ -0,0 +1,27 @@
+import Box from './Box';
+import type { BoardText } from '../types/types';
+
+type RowProps = {
+ handleBoxClick: (row: number, column: number) => void;
+ values: Array;
+ row: number;
+};
+
+const Row = (props: RowProps) => {
+ const boxes: Array = [];
+ for (let i = 0; i < 3; i++) {
+ boxes.push(
+ ,
+ );
+ }
+
+ return {boxes}
;
+};
+
+export default Row;
diff --git a/demo-app-remix/app/components/StateButton.tsx b/demo-app-remix/app/components/StateButton.tsx
new file mode 100644
index 000000000..4b898c87e
--- /dev/null
+++ b/demo-app-remix/app/components/StateButton.tsx
@@ -0,0 +1,17 @@
+// // import React, { useState } from "react";
+
+// export default function StateButton(props: any) {
+// //const [count, setCount] = useState(0);
+
+// return (
+//
+//
This button tests the UseState hook
+// props.setCount(props.count + 1)}
+// >
+// Click to increment: {props.count}
+//
+//
+// );
+// }
diff --git a/demo-app-remix/app/components/navbar.js b/demo-app-remix/app/components/navbar.js
new file mode 100644
index 000000000..885e6f473
--- /dev/null
+++ b/demo-app-remix/app/components/navbar.js
@@ -0,0 +1,17 @@
+import { Link } from '@remix-run/react';
+
+export default function Navbar() {
+ return (
+
+
+ About
+
+
+ Tic-Tac-Toe
+
+
+ Counter
+
+
+ );
+}
diff --git a/demo-app-remix/app/root.tsx b/demo-app-remix/app/root.tsx
new file mode 100644
index 000000000..26ac3df47
--- /dev/null
+++ b/demo-app-remix/app/root.tsx
@@ -0,0 +1,35 @@
+import type { MetaFunction, LinksFunction } from '@remix-run/node';
+import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';
+import styles from './styles/style.css';
+
+export const meta: MetaFunction = () => ({
+ charset: 'utf-8',
+ title: 'New Remix App',
+ viewport: 'width=device-width,initial-scale=1',
+});
+
+export const links: LinksFunction = () => {
+ return [
+ {
+ rel: 'stylesheet',
+ href: styles,
+ },
+ ];
+};
+
+export default function App() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/demo-app-remix/app/routes/buttons/index.tsx b/demo-app-remix/app/routes/buttons/index.tsx
new file mode 100644
index 000000000..1842d8240
--- /dev/null
+++ b/demo-app-remix/app/routes/buttons/index.tsx
@@ -0,0 +1,11 @@
+import Button from '../../components/Buttons';
+import Navbar from '../../components/navbar';
+
+export default function ButtonsPage() {
+ return (
+
+
+
+
+ );
+}
diff --git a/demo-app-remix/app/routes/index.tsx b/demo-app-remix/app/routes/index.tsx
new file mode 100644
index 000000000..1e26e26d0
--- /dev/null
+++ b/demo-app-remix/app/routes/index.tsx
@@ -0,0 +1,28 @@
+import Navbar from '../components/navbar.js';
+
+export default function Home() {
+ return (
+
+
+
+
Lorem Ipsum
+
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
+ ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
+ ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
+ reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
+ sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
+ est laborum."
+
+
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
+ ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
+ ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
+ reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
+ sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
+ est laborum."
+
+
+
+ );
+}
diff --git a/demo-app-remix/app/routes/tictactoe/index.tsx b/demo-app-remix/app/routes/tictactoe/index.tsx
new file mode 100644
index 000000000..8cd5fae85
--- /dev/null
+++ b/demo-app-remix/app/routes/tictactoe/index.tsx
@@ -0,0 +1,13 @@
+import Board from '../../components/Board';
+import Box from '../../components/Box';
+import Row from '../../components/Row';
+import Navbar from '../../components/navbar';
+
+export default function Tictactoe() {
+ return (
+
+
+
+
+ );
+}
diff --git a/demo-app-remix/app/styles/style.css b/demo-app-remix/app/styles/style.css
new file mode 100644
index 000000000..b8a4b09d8
--- /dev/null
+++ b/demo-app-remix/app/styles/style.css
@@ -0,0 +1,179 @@
+body {
+ margin: 0;
+ font-family: Arial, Helvetica, sans-serif;
+ background-color: #fff4f4;
+}
+
+h1,
+h4 {
+ text-align: center;
+}
+
+/* Navbar */
+
+.nav {
+ background-color: #ff6569;
+
+ display: flex;
+ justify-content: space-evenly;
+
+ padding: 30px;
+ height: 30px;
+}
+
+.link {
+ flex-grow: 1;
+
+ font-size: 1.5em;
+ text-decoration: none;
+ text-align: center;
+
+ color: #fff4f4;
+}
+
+.link:hover {
+ font-size: 2em;
+}
+
+/* About */
+
+.about {
+ background-color: #ffffff;
+ color: #330002;
+
+ padding-top: 1em;
+ padding-bottom: 2em;
+ padding-right: 4em;
+ padding-left: 4em;
+ margin-top: 2em;
+
+ max-width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+/* Tic-Tac-Toe */
+
+.board {
+ background-color: #ffffff;
+ color: #330002;
+
+ margin-top: 2em;
+
+ padding-top: 1em;
+ padding-bottom: 1em;
+ padding-left: 4em;
+ padding-right: 4em;
+
+ width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+.box {
+ background-color: #62d6fb;
+ border-style: solid;
+ border-color: #ffffff;
+ border-radius: 5px;
+
+ height: 100px;
+ width: 100px;
+
+ font-size: 4em;
+}
+
+#reset {
+ color: #ff6569;
+ font-size: 1.5em;
+
+ background-color: #ffffff;
+ border-style: solid;
+ border-color: #ff6569;
+ border-radius: 5px;
+
+ margin-top: 20px;
+ margin-bottom: 20px;
+
+ width: 100%;
+
+ padding: 0.5em;
+}
+
+#reset:hover {
+ color: #ffffff;
+ background-color: #ff6569;
+}
+
+/* Counter */
+
+.buttons {
+ background-color: #ffffff;
+ color: #330002;
+
+ padding-top: 1em;
+ padding-bottom: 2em;
+ padding-right: 4em;
+ padding-left: 4em;
+ margin-top: 2em;
+
+ max-width: 300px;
+ margin-left: auto;
+ margin-right: auto;
+
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+.buttonstyle {
+ color: #ffffff;
+ font-size: 1.5em;
+
+ background-color: #ff6569;
+ border-style: solid;
+ border-color: #ffffff;
+ border-radius: 5px;
+
+ margin-top: -20px;
+ margin-bottom: 10px;
+
+ width: 100%;
+
+ padding: 0.5em;
+}
+
+.description {
+ margin-bottom: 30px;
+}
+
+.increment {
+ color: #ffffff;
+ font-size: 1.5em;
+
+ background-color: #FF6569;
+ border-style: solid;
+ border-color: #ffffff;
+ border-radius: 5px;
+
+ margin-top: 20px;
+ margin-bottom: 20px;
+
+ width: 100%;
+
+ padding: .5em;
+}
+
+.increment:hover {
+ background-color: #62d6fb;
+}
+
+.hide {
+ display: none;
+}
+
+.show {
+ display: block;
+ background-color: lightblue;
+}
diff --git a/demo-app-remix/app/types/types.ts b/demo-app-remix/app/types/types.ts
new file mode 100644
index 000000000..cc8252e42
--- /dev/null
+++ b/demo-app-remix/app/types/types.ts
@@ -0,0 +1,10 @@
+export type Scoreboard = {
+ X: number;
+ O: number;
+};
+
+export type Player = 'X' | 'O';
+
+export type BoardText = 'X' | 'O' | '-';
+
+export type BoardContent = Array>;
diff --git a/demo-app-remix/package.json b/demo-app-remix/package.json
new file mode 100644
index 000000000..5add33863
--- /dev/null
+++ b/demo-app-remix/package.json
@@ -0,0 +1,39 @@
+{
+ "private": true,
+ "sideEffects": false,
+ "scripts": {
+ "build": "remix build",
+ "dev": "npm-run-all build --parallel \"dev:*\"",
+ "dev:node": "cross-env NODE_ENV=development nodemon --require dotenv/config ./server.ts --watch ./server.ts",
+ "dev:remix": "remix watch",
+ "start": "cross-env NODE_ENV=production node ./server.ts",
+ "typecheck": "tsc"
+ },
+ "dependencies": {
+ "@remix-run/express": "^1.14.1",
+ "@remix-run/node": "^1.14.1",
+ "@remix-run/react": "^1.14.1",
+ "compression": "^1.7.4",
+ "cross-env": "^7.0.3",
+ "express": "^4.18.2",
+ "isbot": "^3.6.5",
+ "morgan": "^1.10.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "ts-node": "^10.9.2"
+ },
+ "devDependencies": {
+ "@remix-run/dev": "^1.14.1",
+ "@remix-run/eslint-config": "^1.14.1",
+ "@types/react": "^18.0.25",
+ "@types/react-dom": "^18.0.8",
+ "dotenv": "^16.0.3",
+ "eslint": "^8.27.0",
+ "nodemon": "^2.0.20",
+ "npm-run-all": "^4.1.5",
+ "typescript": "^4.8.4"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+}
diff --git a/demo-app-remix/public/favicon.ico b/demo-app-remix/public/favicon.ico
new file mode 100644
index 000000000..8830cf682
Binary files /dev/null and b/demo-app-remix/public/favicon.ico differ
diff --git a/demo-app-remix/remix.config.js b/demo-app-remix/remix.config.js
new file mode 100644
index 000000000..ddeb138df
--- /dev/null
+++ b/demo-app-remix/remix.config.js
@@ -0,0 +1,8 @@
+/** @type {import('@remix-run/dev').AppConfig} */
+module.exports = {
+ ignoredRouteFiles: ['**/.*'],
+ // appDirectory: "app",
+ // assetsBuildDirectory: 'public/build',
+ // serverBuildPath: "build/index.js",
+ // publicPath: "/build/",
+};
diff --git a/demo-app-remix/remix.env.d.ts b/demo-app-remix/remix.env.d.ts
new file mode 100644
index 000000000..dcf8c45e1
--- /dev/null
+++ b/demo-app-remix/remix.env.d.ts
@@ -0,0 +1,2 @@
+///
+///
diff --git a/demo-app-remix/server.ts b/demo-app-remix/server.ts
new file mode 100644
index 000000000..1e24b658d
--- /dev/null
+++ b/demo-app-remix/server.ts
@@ -0,0 +1,59 @@
+export {}; //JR: added to fix this error message: 'server.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module.
+const path = require('path');
+const express = require('express');
+const compression = require('compression');
+const morgan = require('morgan');
+const { createRequestHandler } = require('@remix-run/express');
+
+const BUILD_DIR = path.join(process.cwd(), 'build');
+
+const app = express();
+
+app.use(compression());
+
+// http://expressjs.com/en/advanced/best-practice-security.html#at-a-minimum-disable-x-powered-by-header
+app.disable('x-powered-by');
+
+// Remix fingerprints its assets so we can cache forever.
+app.use('/build', express.static('public/build', { immutable: true, maxAge: '1y' }));
+
+// Everything else (like favicon.ico) is cached for an hour. You may want to be
+// more aggressive with this caching.
+app.use(express.static('public', { maxAge: '1h' }));
+
+app.use(morgan('tiny'));
+
+app.all(
+ '*',
+ process.env.NODE_ENV === 'development'
+ ? (req: any, res: any, next: any) => {
+ purgeRequireCache();
+
+ return createRequestHandler({
+ build: require(BUILD_DIR),
+ mode: process.env.NODE_ENV,
+ })(req, res, next);
+ }
+ : createRequestHandler({
+ build: require(BUILD_DIR),
+ mode: process.env.NODE_ENV,
+ }),
+);
+const port: number | string = process.env.PORT || 3003;
+
+app.listen(port, () => {
+ console.log(`Express server listening on port ${port}`);
+});
+
+function purgeRequireCache() {
+ // purge require cache on requests for "server side HMR" this won't let
+ // you have in-memory objects between requests in development,
+ // alternatively you can set up nodemon/pm2-dev to restart the server on
+ // file changes, but then you'll have to reconnect to databases/etc on each
+ // change. We prefer the DX of this, so we've included it for you by default
+ for (const key in require.cache) {
+ if (key.startsWith(BUILD_DIR)) {
+ delete require.cache[key];
+ }
+ }
+}
diff --git a/demo-app-remix/tsconfig.json b/demo-app-remix/tsconfig.json
new file mode 100644
index 000000000..0de0b2ee4
--- /dev/null
+++ b/demo-app-remix/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx", "server.ts"],
+ "compilerOptions": {
+ "lib": ["DOM", "DOM.Iterable", "ES2019"],
+ "isolatedModules": true,
+ "esModuleInterop": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "target": "ES2019",
+ "strict": true,
+ "allowJs": true,
+ "forceConsistentCasingInFileNames": true,
+ "baseUrl": ".",
+ "paths": {
+ "~/*": ["./app/*"]
+ },
+
+ // Remix takes care of building everything in `remix build`.
+ "noEmit": true
+ }
+}
diff --git a/demo-app/package.json b/demo-app/package.json
index 2f37d8da9..4003e82fa 100644
--- a/demo-app/package.json
+++ b/demo-app/package.json
@@ -4,21 +4,24 @@
"description": "",
"main": "index.js",
"scripts": {
- "start": "webpack-dev-server",
+ "dev": "webpack-dev-server",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"@babel/core": "^7.16.7",
+ "@babel/plugin-transform-runtime": "^7.25.9",
"@babel/preset-env": "^7.16.7",
"@babel/preset-react": "^7.16.7",
"@types/express": "^4.17.13",
"@types/node": "^17.0.8",
"@types/react": "^17.0.38",
- "@types/react-dom": "^17.0.11",
+ "@types/react-dom": "^17.0.19",
"babel-loader": "^8.2.3",
"copy-webpack-plugin": "^10.2.0",
+ "core-js": "^3.39.0",
"css-loader": "^6.5.1",
"html-webpack-plugin": "^5.5.0",
+ "node": "^16.0.0",
"nodemon": "^2.0.15",
"ts-loader": "^9.2.6",
"typescript": "^4.5.4",
@@ -27,10 +30,12 @@
"webpack-dev-server": "^4.7.2"
},
"dependencies": {
+ "@mui/styled-engine-sc": "^5.12.0",
"express": "^4.17.2",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-router-dom": "^6.3.0",
- "ts-node": "^10.4.0"
+ "ts-node": "^10.4.0",
+ "use-immer": "^0.9.0"
}
}
diff --git a/demo-app/src/client/Components/Board.tsx b/demo-app/src/client/Components/Board.tsx
index 18e610cf8..102f2a2bb 100644
--- a/demo-app/src/client/Components/Board.tsx
+++ b/demo-app/src/client/Components/Board.tsx
@@ -1,7 +1,9 @@
import React, { Component } from 'react';
import Row from './Row';
-import { BoardText, BoardContent, Scoreboard, Player } from './../../types';
+import { BoardContent, Scoreboard, Player } from './../../types';
+//Took away BoardText from import
+//thinking about changing this to an interface
type BoardState = {
board: BoardContent;
currentPlayer: Player;
@@ -10,8 +12,9 @@ type BoardState = {
scoreboard: Scoreboard;
};
+//changed props to unknown instead of any
class Board extends Component<{}, BoardState> {
- constructor(props: any) {
+ constructor(props: unknown) {
super(props);
this.state = {
board: this.newBoard(),
@@ -25,8 +28,9 @@ class Board extends Component<{}, BoardState> {
this.handleBoxClick = this.handleBoxClick.bind(this);
}
- componentDidUpdate() {
- this.checkForWinner();
+ //added void
+ componentDidUpdate(): void {
+ this.checkForWinner()
}
/**
@@ -73,30 +77,14 @@ class Board extends Component<{}, BoardState> {
if (!gameOver) {
// win conditions: matching rows, columns, or diagonals, that are not empty('-')
if (
- (board[0][0] === board[0][1] &&
- board[0][1] === board[0][2] &&
- board[0][2] !== '-') ||
- (board[1][0] === board[1][1] &&
- board[1][1] === board[1][2] &&
- board[1][2] !== '-') ||
- (board[2][0] === board[2][1] &&
- board[2][1] === board[2][2] &&
- board[2][2] !== '-') ||
- (board[0][0] === board[1][0] &&
- board[1][0] === board[2][0] &&
- board[2][0] !== '-') ||
- (board[0][1] === board[1][1] &&
- board[1][1] === board[2][1] &&
- board[2][1] !== '-') ||
- (board[0][2] === board[1][2] &&
- board[1][2] === board[2][2] &&
- board[2][2] !== '-') ||
- (board[0][0] === board[1][1] &&
- board[1][1] === board[2][2] &&
- board[2][2] !== '-') ||
- (board[2][0] === board[1][1] &&
- board[1][1] === board[0][2] &&
- board[0][2] !== '-')
+ (board[0][0] === board[0][1] && board[0][1] === board[0][2] && board[0][2] !== '-') ||
+ (board[1][0] === board[1][1] && board[1][1] === board[1][2] && board[1][2] !== '-') ||
+ (board[2][0] === board[2][1] && board[2][1] === board[2][2] && board[2][2] !== '-') ||
+ (board[0][0] === board[1][0] && board[1][0] === board[2][0] && board[2][0] !== '-') ||
+ (board[0][1] === board[1][1] && board[1][1] === board[2][1] && board[2][1] !== '-') ||
+ (board[0][2] === board[1][2] && board[1][2] === board[2][2] && board[2][2] !== '-') ||
+ (board[0][0] === board[1][1] && board[1][1] === board[2][2] && board[2][2] !== '-') ||
+ (board[2][0] === board[1][1] && board[1][1] === board[0][2] && board[0][2] !== '-')
) {
// winner is the person who's turn was previous
const winner: Player = currentPlayer === 'X' ? 'O' : 'X';
@@ -127,26 +115,22 @@ class Board extends Component<{}, BoardState> {
this.setState({ board: boardCopy, currentPlayer: newPlayer });
}
- render() {
- const rows: Array = [];
+ //added type for render
+ render(): JSX.Element {
+ const rows: Array = [];
for (let i = 0; i < 3; i++) {
rows.push(
-
+
,
);
}
- const { X, O }: Scoreboard = this.state.scoreboard;
+ // const { X, O }: Scoreboard = this.state.scoreboard;
return (
-
+
Tic Tac Toe
{this.state.gameOver && {this.state.message} }
{rows}
-
+
Reset
diff --git a/demo-app/src/client/Components/Box.tsx b/demo-app/src/client/Components/Box.tsx
index 53b79548d..d9c45512e 100644
--- a/demo-app/src/client/Components/Box.tsx
+++ b/demo-app/src/client/Components/Box.tsx
@@ -8,14 +8,13 @@ type BoxProps = {
handleBoxClick: (row: number, column: number) => void;
};
-const Box = (props: BoxProps) => {
+const Box = (props: BoxProps): JSX.Element => {
return (
-
props.handleBoxClick(props.row, props.column)}
- >
- {props.value}
-
+ <>
+
props.handleBoxClick(props.row, props.column)}>
+ {props.value}
+
+ >
);
};
diff --git a/demo-app/src/client/Components/Buttons.tsx b/demo-app/src/client/Components/Buttons.tsx
index af0ffa7a8..60235aa92 100644
--- a/demo-app/src/client/Components/Buttons.tsx
+++ b/demo-app/src/client/Components/Buttons.tsx
@@ -1,19 +1,82 @@
-import React from "react";
-import Increment from "./Increment";
+import React, { Component, useState } from 'react';
-function Buttons() {
- const buttons = [];
- for (let i = 0; i < 4; i++){
- buttons.push(
)
+type ButtonProps = {
+ id: string;
+ label: string;
+ color?: string;
+ initialCount?: number;
+};
+
+type IncrementClassState = {
+ count: number;
+};
+
+class IncrementClass extends Component
{
+ state = {
+ count: this.props.initialCount || 0,
+ };
+
+ handleClick = (): void => {
+ this.setState((prevState: IncrementClassState) => ({
+ count: prevState.count + 1,
+ }));
+ };
+
+ render(): JSX.Element {
+ return (
+
+
+ {this.props.label} {this.state.count} times.
+
+
+ );
}
+}
- return(
-
-
Stateful Buttons
-
These buttons are functional components that each manage their own state with the useState hook.
- {buttons}
+const IncrementFunction = (props: ButtonProps): JSX.Element => {
+ const [count, setCount] = useState(props.initialCount || 0);
+
+ const handleClick = (): void => {
+ setCount((prev) => prev + 1);
+ };
+
+ return (
+
+
+ {props.label} {count} times.
+
- )
+ );
+};
+
+class Buttons extends Component {
+ render(): JSX.Element {
+ return (
+
+
Mixed State Counter
+ First two buttons use class components, last two use function components.
+
+
+
+
+
+ );
+ }
}
-export default Buttons;
\ No newline at end of file
+export default Buttons;
diff --git a/demo-app/src/client/Components/FunctionalReducerCounter.tsx b/demo-app/src/client/Components/FunctionalReducerCounter.tsx
new file mode 100644
index 000000000..85effd454
--- /dev/null
+++ b/demo-app/src/client/Components/FunctionalReducerCounter.tsx
@@ -0,0 +1,231 @@
+import React, { useState, useReducer } from 'react';
+
+type CounterProps = {
+ initialCount?: number;
+ step?: number;
+ title?: string;
+ theme?: {
+ backgroundColor?: string;
+ textColor?: string;
+ };
+};
+
+type CounterState = {
+ count: number;
+ history: number[];
+ lastAction: string;
+};
+
+type CounterAction =
+ | { type: 'INCREMENT' }
+ | { type: 'DECREMENT' }
+ | { type: 'DOUBLE' }
+ | { type: 'RESET' }
+ | { type: 'ADD'; payload: number }
+ | { type: 'SET_STATE'; payload: CounterState };
+
+type SecondaryCounterState = {
+ count: number;
+ multiplier: number;
+ lastOperation: string;
+ history: number[];
+};
+
+type SecondaryCounterAction =
+ | { type: 'MULTIPLY' }
+ | { type: 'DIVIDE' }
+ | { type: 'SET_MULTIPLIER'; payload: number }
+ | { type: 'RESET' }
+ | { type: 'SET_STATE'; payload: SecondaryCounterState };
+
+function counterReducer(state: CounterState, action: CounterAction, step: number): CounterState {
+ switch (action.type) {
+ case 'INCREMENT':
+ return {
+ ...state,
+ count: state.count + step,
+ history: [...state.history, state.count + step],
+ lastAction: 'INCREMENT',
+ };
+ case 'DECREMENT':
+ return {
+ ...state,
+ count: state.count - step,
+ history: [...state.history, state.count - step],
+ lastAction: 'DECREMENT',
+ };
+ case 'DOUBLE':
+ return {
+ ...state,
+ count: state.count * 2,
+ history: [...state.history, state.count * 2],
+ lastAction: 'DOUBLE',
+ };
+ case 'RESET':
+ return {
+ count: 0,
+ history: [],
+ lastAction: 'RESET',
+ };
+ case 'ADD':
+ return {
+ ...state,
+ count: state.count + action.payload,
+ history: [...state.history, state.count + action.payload],
+ lastAction: `ADD ${action.payload}`,
+ };
+ case 'SET_STATE':
+ return {
+ ...action.payload,
+ lastAction: 'SET_STATE',
+ };
+ default:
+ return state;
+ }
+}
+
+function secondaryCounterReducer(
+ state: SecondaryCounterState,
+ action: SecondaryCounterAction,
+): SecondaryCounterState {
+ switch (action.type) {
+ case 'MULTIPLY':
+ return {
+ ...state,
+ count: state.count * state.multiplier,
+ history: [...state.history, state.count * state.multiplier],
+ lastOperation: `Multiplied by ${state.multiplier}`,
+ };
+ case 'DIVIDE':
+ return {
+ ...state,
+ count: state.count / state.multiplier,
+ history: [...state.history, state.count / state.multiplier],
+ lastOperation: `Divided by ${state.multiplier}`,
+ };
+ case 'SET_MULTIPLIER':
+ return {
+ ...state,
+ multiplier: action.payload,
+ history: [...state.history],
+ lastOperation: `Set multiplier to ${action.payload}`,
+ };
+ case 'RESET':
+ return {
+ count: 0,
+ multiplier: 2,
+ history: [],
+ lastOperation: 'Reset',
+ };
+ case 'SET_STATE':
+ return {
+ ...action.payload,
+ lastOperation: 'SET_STATE',
+ };
+ default:
+ return state;
+ }
+}
+
+function FunctionalReducerCounter({
+ initialCount = 0,
+ step = 1,
+ title = 'Function-based Reducer Counter',
+ theme = {
+ backgroundColor: '#ffffff',
+ textColor: '#330002',
+ },
+}: CounterProps): JSX.Element {
+ const [clickCount, setClickCount] = useState(0);
+ const [lastClickTime, setLastClickTime] = useState
(null);
+ const [averageTimeBetweenClicks, setAverageTimeBetweenClicks] = useState(0);
+
+ const [state, dispatch] = useReducer(
+ (state: CounterState, action: CounterAction) => counterReducer(state, action, step),
+ {
+ count: initialCount,
+ history: [],
+ lastAction: 'none',
+ },
+ );
+
+ const [secondaryState, secondaryDispatch] = useReducer(secondaryCounterReducer, {
+ count: initialCount,
+ multiplier: 2,
+ history: [],
+ lastOperation: 'none',
+ });
+
+ return (
+
+
{title}
+
+
+
Primary Counter: {state.count}
+
+
+
+ dispatch({ type: 'INCREMENT' })}>Increment (+{step})
+ dispatch({ type: 'DECREMENT' })}>Decrement (-{step})
+ dispatch({ type: 'DOUBLE' })}>Double Value
+ dispatch({ type: 'ADD', payload: 5 })}>Add 5
+ dispatch({ type: 'RESET' })}>Reset
+
+
+
+
History:
+
+ {state.history.map((value, index) => (
+
+ {value}
+ {index < state.history.length - 1 ? ' → ' : ''}
+
+ ))}
+
+
+
+
+
Secondary Counter: {secondaryState.count}
+
+ secondaryDispatch({ type: 'MULTIPLY' })}>
+ Multiply by {secondaryState.multiplier}
+
+ secondaryDispatch({ type: 'DIVIDE' })}>
+ Divide by {secondaryState.multiplier}
+
+
+ secondaryDispatch({ type: 'SET_MULTIPLIER', payload: secondaryState.multiplier + 1 })
+ }
+ >
+ Increase Multiplier
+
+ secondaryDispatch({ type: 'RESET' })}>Reset
+
+
+
Current Multiplier: {secondaryState.multiplier}
+
History:
+
+ {secondaryState.history.map((value, index) => (
+
+ {value}
+ {index < secondaryState.history.length - 1 ? ' → ' : ''}
+
+ ))}
+
+
+
+
+ );
+}
+
+export default FunctionalReducerCounter;
diff --git a/demo-app/src/client/Components/FunctionalStateCounter.tsx b/demo-app/src/client/Components/FunctionalStateCounter.tsx
new file mode 100644
index 000000000..a49916177
--- /dev/null
+++ b/demo-app/src/client/Components/FunctionalStateCounter.tsx
@@ -0,0 +1,97 @@
+import React, { useState } from 'react';
+
+type CounterProps = {
+ initialCount?: number;
+ step?: number;
+ title?: string;
+ theme?: {
+ backgroundColor?: string;
+ textColor?: string;
+ };
+};
+
+function FunctionalStateCounter({
+ initialCount = 0,
+ step = 1,
+ title = 'Function-based State Counter',
+ theme = {
+ backgroundColor: '#ffffff',
+ textColor: '#330002',
+ },
+}: CounterProps): JSX.Element {
+ const [count, setCount] = useState(initialCount);
+ const [history, setHistory] = useState([]);
+ const [lastAction, setLastAction] = useState('none');
+
+ const handleAction = (type: string, payload?: number) => {
+ let newCount = count;
+ switch (type) {
+ case 'INCREMENT':
+ newCount = count + step;
+ setCount(newCount);
+ setHistory([...history, newCount]);
+ setLastAction('INCREMENT');
+ break;
+ case 'DECREMENT':
+ newCount = count - step;
+ setCount(newCount);
+ setHistory([...history, newCount]);
+ setLastAction('DECREMENT');
+ break;
+ case 'DOUBLE':
+ newCount = count * 2;
+ setCount(newCount);
+ setHistory([...history, newCount]);
+ setLastAction('DOUBLE');
+ break;
+ case 'ADD':
+ newCount = count + (payload || 0);
+ setCount(newCount);
+ setHistory([...history, newCount]);
+ setLastAction(`ADD ${payload}`);
+ break;
+ case 'RESET':
+ setCount(0);
+ setHistory([]);
+ setLastAction('RESET');
+ break;
+ }
+ };
+
+ return (
+
+
{title}
+
+
Current Count: {count}
+
+
+
+ handleAction('INCREMENT')}>Increment (+{step})
+ handleAction('DECREMENT')}>Decrement (-{step})
+ handleAction('DOUBLE')}>Double Value
+ handleAction('ADD', 5)}>Add 5
+ handleAction('RESET')}>Reset
+
+
+
+
History:
+
+ {history.map((value, index) => (
+
+ {value}
+ {index < history.length - 1 ? ' → ' : ''}
+
+ ))}
+
+
+
+ );
+}
+
+export default FunctionalStateCounter;
diff --git a/demo-app/src/client/Components/Home.tsx b/demo-app/src/client/Components/Home.tsx
index 2f38d48c6..9952f9e29 100644
--- a/demo-app/src/client/Components/Home.tsx
+++ b/demo-app/src/client/Components/Home.tsx
@@ -1,29 +1,60 @@
import React from 'react';
+import { useTheme } from '../../contexts/ThemeContext';
+import { useAuth } from '../../contexts/AuthContext';
+
+function Home(): JSX.Element {
+ const { theme } = useTheme();
+ const { user, login, logout } = useAuth();
-function Home() {
return (
-
-
Lorem Ipsum
-
- "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
- tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
- veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
- commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
- velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
- occaecat cupidatat non proident, sunt in culpa qui officia deserunt
- mollit anim id est laborum."
-
-
- "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
- tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
- veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
- commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
- velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
- occaecat cupidatat non proident, sunt in culpa qui officia deserunt
- mollit anim id est laborum."
-
+
+
REACTIME - DEMO APP
+
+ {user ? (
+
+
Welcome, {user.username}!
+
+ Logout
+
+
+ ) : (
+
+
Please log in:
+
login('testUser')}
+ style={{
+ backgroundColor: theme.primaryColor,
+ color: theme.backgroundColor,
+ }}
+ >
+ Login as Test User
+
+
login('admin')}
+ style={{
+ backgroundColor: theme.secondaryColor,
+ color: theme.backgroundColor,
+ marginLeft: '8px',
+ }}
+ >
+ Login as Admin
+
+
+ )}
);
}
-
export default Home;
diff --git a/demo-app/src/client/Components/Nav.tsx b/demo-app/src/client/Components/Nav.tsx
index eb7c28842..274c5ae39 100644
--- a/demo-app/src/client/Components/Nav.tsx
+++ b/demo-app/src/client/Components/Nav.tsx
@@ -1,14 +1,25 @@
-import React from "react";
-import { Link } from "react-router-dom";
+import React from 'react';
+import { Link } from 'react-router-dom';
+import ThemeToggle from './ThemeToggle';
-function Nav() {
- return(
-
-
About
-
Tic-Tac-Toe
-
Counter
+function Nav(): JSX.Element {
+ return (
+
+
+ About
+
+
+ Tic-Tac-Toe
+
+
+ State Counter
+
+
+ Reducer Counter
+
+
- )
+ );
}
-export default Nav;
\ No newline at end of file
+export default Nav;
diff --git a/demo-app/src/client/Components/ReducerCounter.tsx b/demo-app/src/client/Components/ReducerCounter.tsx
new file mode 100644
index 000000000..65b5d6155
--- /dev/null
+++ b/demo-app/src/client/Components/ReducerCounter.tsx
@@ -0,0 +1,141 @@
+import React, { Component } from 'react';
+
+type CounterProps = {
+ initialCount?: number;
+ step?: number;
+ title?: string;
+ theme?: {
+ backgroundColor?: string;
+ textColor?: string;
+ };
+};
+
+type CounterState = {
+ count: number;
+ history: number[];
+ lastAction: string;
+};
+
+type CounterAction =
+ | { type: 'INCREMENT' }
+ | { type: 'DECREMENT' }
+ | { type: 'DOUBLE' }
+ | { type: 'RESET' }
+ | { type: 'ADD'; payload: number };
+
+class ReducerCounter extends Component
{
+ static defaultProps = {
+ initialCount: 0,
+ step: 1,
+ title: 'Class-based Reducer Counter',
+ theme: {
+ backgroundColor: '#ffffff',
+ textColor: '#330002',
+ },
+ };
+
+ static initialState(initialCount: number): CounterState {
+ return {
+ count: initialCount,
+ history: [],
+ lastAction: 'none',
+ };
+ }
+
+ static reducer(state: CounterState, action: CounterAction, step: number): CounterState {
+ switch (action.type) {
+ case 'INCREMENT':
+ return {
+ ...state,
+ count: state.count + step,
+ history: [...state.history, state.count + step],
+ lastAction: 'INCREMENT',
+ };
+ case 'DECREMENT':
+ return {
+ ...state,
+ count: state.count - step,
+ history: [...state.history, state.count - step],
+ lastAction: 'DECREMENT',
+ };
+ case 'DOUBLE':
+ return {
+ ...state,
+ count: state.count * 2,
+ history: [...state.history, state.count * 2],
+ lastAction: 'DOUBLE',
+ };
+ case 'RESET':
+ return {
+ ...ReducerCounter.initialState(0),
+ lastAction: 'RESET',
+ };
+ case 'ADD':
+ return {
+ ...state,
+ count: state.count + action.payload,
+ history: [...state.history, state.count + action.payload],
+ lastAction: `ADD ${action.payload}`,
+ };
+ default:
+ return state;
+ }
+ }
+
+ constructor(props: CounterProps) {
+ super(props);
+ this.state = ReducerCounter.initialState(props.initialCount || 0);
+ this.dispatch = this.dispatch.bind(this);
+ }
+
+ dispatch(action: CounterAction): void {
+ this.setState((currentState) =>
+ ReducerCounter.reducer(currentState, action, this.props.step || 1),
+ );
+ }
+
+ render(): JSX.Element {
+ const { title, theme } = this.props;
+
+ return (
+
+
{title}
+
+
Current Count: {this.state.count}
+
+
+
+ this.dispatch({ type: 'INCREMENT' })}>
+ Increment (+{this.props.step})
+
+ this.dispatch({ type: 'DECREMENT' })}>
+ Decrement (-{this.props.step})
+
+ this.dispatch({ type: 'DOUBLE' })}>Double Value
+ this.dispatch({ type: 'ADD', payload: 5 })}>Add 5
+ this.dispatch({ type: 'RESET' })}>Reset
+
+
+
+
History:
+
+ {this.state.history.map((value, index) => (
+
+ {value}
+ {index < this.state.history.length - 1 ? ' → ' : ''}
+
+ ))}
+
+
+
+ );
+ }
+}
+
+export default ReducerCounter;
diff --git a/demo-app/src/client/Components/Row.tsx b/demo-app/src/client/Components/Row.tsx
index d9bf89ca6..1fcc267b2 100644
--- a/demo-app/src/client/Components/Row.tsx
+++ b/demo-app/src/client/Components/Row.tsx
@@ -8,21 +8,25 @@ type RowProps = {
row: number;
};
-const Row = (props: RowProps) => {
+const Row = (props: RowProps): JSX.Element => {
const boxes: Array = [];
for (let i = 0; i < 3; i++) {
boxes.push(
+ >,
);
}
- return {boxes}
;
+ return (
+ <>
+ {boxes}
+ >
+ );
};
export default Row;
diff --git a/demo-app/src/client/Components/ThemeToggle.tsx b/demo-app/src/client/Components/ThemeToggle.tsx
new file mode 100644
index 000000000..81f203747
--- /dev/null
+++ b/demo-app/src/client/Components/ThemeToggle.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import { useTheme } from '../../contexts/ThemeContext';
+
+const ThemeToggle = (): JSX.Element => {
+ const { theme, toggleTheme } = useTheme();
+ const isDark = theme.backgroundColor === '#1a202c';
+
+ return (
+
+ {isDark ? '☀️ Light Mode' : '🌙 Dark Mode'}
+
+ );
+};
+
+export default ThemeToggle;
diff --git a/demo-app/src/client/Router.tsx b/demo-app/src/client/Router.tsx
index 721d4be5d..619dfce8b 100644
--- a/demo-app/src/client/Router.tsx
+++ b/demo-app/src/client/Router.tsx
@@ -1,19 +1,59 @@
-import * as React from "react";
-import * as ReactDOM from "react-dom";
-import { BrowserRouter, Routes, Route } from "react-router-dom";
-import Nav from "./Components/Nav";
-import Board from "./Components/Board";
-import Home from "./Components/Home";
-import Buttons from "./Components/Buttons";
+// src/client/Router.tsx
+import * as React from 'react';
+import { createRoot } from 'react-dom/client';
+import { BrowserRouter, Routes, Route } from 'react-router-dom';
+import { ThemeProvider } from '../contexts/ThemeContext';
+import { AuthProvider } from '../contexts/AuthContext';
+import Nav from './Components/Nav';
+import Board from './Components/Board';
+import Home from './Components/Home';
+import Buttons from './Components/Buttons';
+import ReducerCounter from './Components/ReducerCounter';
+import FunctionalReducerCounter from './Components/FunctionalReducerCounter';
+import FunctionalStateCounter from './Components/FunctionalStateCounter';
-const root = document.getElementById("root");
+const domNode = document.getElementById('root');
+if (!domNode) throw new Error('Root element not found');
+const root = createRoot(domNode);
-ReactDOM.render(
-
-
-
- }/>
- }/>
- }/>
-
- , root);
+const CounterPage = () => (
+
+
+
+
+
+);
+
+root.render(
+
+
+
+
+
+ } />
+ } />
+ } />
+ } />
+
+
+
+ ,
+);
diff --git a/demo-app/src/client/index.html b/demo-app/src/client/index.html
index 8fe6a994a..180bd93fe 100644
--- a/demo-app/src/client/index.html
+++ b/demo-app/src/client/index.html
@@ -1,8 +1,9 @@
-
+
- Reactime MVP
-
+ Demo App
+
+
diff --git a/demo-app/src/client/style.css b/demo-app/src/client/style.css
index ad19d8b7f..657b149d9 100644
--- a/demo-app/src/client/style.css
+++ b/demo-app/src/client/style.css
@@ -1,115 +1,428 @@
+@import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap');
+
+:root {
+ --primary-red-color: #f00008;
+ --secondary-blue-color: #62d6fb;
+ --fire-rose-red: #ff6569;
+ --secondary-color: #6288fb;
+ --text-color: #330002;
+}
body {
margin: 0;
- font-family: Arial, Helvetica, sans-serif;
- background-color: #FFF4F4;
+ font-family: 'Lato', sans-serif;
+ transition: all 0.3s ease;
}
-h1, h4 {
- text-align: center;
+/* Navbar */
+.nav {
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(10px);
+ box-shadow:
+ 0 4px 6px -1px rgba(0, 0, 0, 0.1),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 1rem 2rem;
+ position: sticky;
+ top: 0;
+ z-index: 1000;
+ height: auto;
+ gap: 2rem;
}
-/* Navbar */
+.link {
+ position: relative;
+ color: #4a5568;
+ text-decoration: none;
+ font-size: 1rem;
+ font-weight: 500;
+ padding: 0.5rem 1rem;
+ border-radius: 8px;
+ transition: all 0.2s ease;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
-.nav {
- background-color: #FF6569;
+.link::after {
+ content: '';
+ position: absolute;
+ bottom: -2px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 0;
+ height: 2px;
+ background: linear-gradient(90deg, #667eea, #764ba2);
+ transition: width 0.3s ease;
+}
+
+.link:hover {
+ color: #1a202c;
+ font-size: 1rem;
+ background: rgba(237, 242, 247, 0.5);
+}
+
+.link:hover::after {
+ width: calc(100% - 2rem);
+}
+
+/* Active link state */
+.link.active {
+ color: #1a202c;
+ background: rgba(237, 242, 247, 0.8);
+}
+
+.link.active::after {
+ width: calc(100% - 2rem);
+}
+
+@media (max-width: 768px) {
+ .nav {
+ flex-direction: column;
+ padding: 1rem;
+ gap: 1rem;
+ }
+
+ .link {
+ width: 100%;
+ text-align: center;
+ }
+
+ .link::after {
+ bottom: 0;
+ }
+}
+
+/* Theme Toggle Button Styles */
+.nav button {
+ position: absolute;
+ top: 50%;
+ right: 2rem;
+ transform: translateY(-50%);
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ border: none;
+ border-radius: 8px;
+ padding: 0.5rem 1rem;
+ font-size: 0.875rem;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+.nav button:hover {
+ transform: translateY(-50%) scale(1.05);
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.25);
+}
+
+@media (max-width: 768px) {
+ .nav button {
+ position: static;
+ transform: none;
+ width: 100%;
+ margin-bottom: 1rem;
+ }
+}
+
+.theme-toggle {
+ position: absolute;
+ top: 50%;
+ right: 2rem;
+ transform: translateY(-50%);
+ padding: 0.75rem 1.25rem;
+ font-size: 0.875rem;
+ font-weight: 600;
+ border-radius: 8px;
+ cursor: pointer;
+ transition: all 0.3s ease;
display: flex;
- justify-content: space-evenly;
+ align-items: center;
+ gap: 0.5rem;
+}
- padding: 30px;
- height: 30px;
+.theme-toggle:hover {
+ transform: translateY(-50%) scale(1.05);
+ box-shadow:
+ 0 4px 6px rgba(0, 0, 0, 0.1),
+ 0 2px 4px rgba(0, 0, 0, 0.06);
}
-.link {
- flex-grow: 1;
+.theme-toggle:active {
+ transform: translateY(-50%) scale(0.95);
+}
- font-size: 1.5em;
- text-decoration: none;
+@media (max-width: 768px) {
+ .theme-toggle {
+ position: static;
+ transform: none;
+ width: 100%;
+ margin-bottom: 1rem;
+ justify-content: center;
+ }
+
+ .theme-toggle:hover {
+ transform: scale(1.02);
+ }
+
+ .theme-toggle:active {
+ transform: scale(0.98);
+ }
+}
+
+/* About */
+.about {
+ background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+ border-radius: 24px;
+ padding: 3rem;
+ margin: 3rem auto;
+ max-width: 600px;
+ box-shadow:
+ 0 20px 25px -5px rgba(0, 0, 0, 0.1),
+ 0 10px 10px -5px rgba(0, 0, 0, 0.04),
+ 0 0 100px rgba(0, 0, 0, 0.05);
+ transition:
+ transform 0.3s ease,
+ box-shadow 0.3s ease;
+ position: relative;
+ overflow: hidden;
+}
+
+.about::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 4px;
+ background: linear-gradient(90deg, #667eea, #764ba2);
+ border-radius: 4px 4px 0 0;
+}
+
+.about:hover {
+ transform: translateY(-5px);
+ box-shadow:
+ 0 25px 30px -5px rgba(0, 0, 0, 0.1),
+ 0 15px 15px -5px rgba(0, 0, 0, 0.04),
+ 0 0 120px rgba(0, 0, 0, 0.05);
+}
+
+.about h2 {
+ color: #1a202c;
+ font-size: 2.5rem;
+ font-weight: 800;
+ margin-bottom: 2rem;
text-align: center;
+ background: linear-gradient(120deg, #2d3748 0%, #4a5568 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ letter-spacing: -0.02em;
+}
- color: #FFF4F4;
+.about p {
+ color: #4a5568;
+ font-size: 1.1rem;
+ line-height: 1.7;
+ margin: 1.5rem 0;
}
-.link:hover {
- font-size: 2em;
+/* Login Section Styles */
+.about button {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ border: none;
+ border-radius: 12px;
+ font-size: 1rem;
+ font-weight: 600;
+ padding: 0.75rem 1.5rem;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ margin: 0.5rem 0;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
}
-/* About */
+.about button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.25);
+}
-.about {
- background-color: #ffffff;
- color: #330002;
+.about button:active {
+ transform: translateY(0);
+}
- padding-top: 1em;
- padding-bottom: 2em;
- padding-right: 4em;
- padding-left: 4em;
- margin-top: 2em;
+.about button:nth-of-type(2) {
+ background: linear-gradient(135deg, #4299e1 0%, #3182ce 100%);
+ margin-left: 1rem;
+}
- max-width: 300px;
- margin-left: auto;
- margin-right: auto;
+.about button:nth-of-type(2):hover {
+ box-shadow: 0 4px 12px rgba(66, 153, 225, 0.25);
+}
- box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+.about div p:first-of-type {
+ font-size: 1.25rem;
+ color: #2d3748;
+ font-weight: 600;
+ margin-bottom: 1.5rem;
}
-/* Tic-Tac-Toe */
+@media (max-width: 768px) {
+ .about {
+ margin: 2rem 1rem;
+ padding: 2rem;
+ }
+
+ .about h2 {
+ font-size: 2rem;
+ }
+
+ .about button {
+ width: 100%;
+ margin: 0.5rem 0;
+ }
+
+ .about button:nth-of-type(2) {
+ margin-left: 0;
+ }
+}
+
+/* Animation for content loading */
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.about > * {
+ animation: fadeIn 0.5s ease-out forwards;
+}
+
+.about > *:nth-child(2) {
+ animation-delay: 0.1s;
+}
+.about > *:nth-child(3) {
+ animation-delay: 0.2s;
+}
+/* Tic-Tac-Toe */
.board {
- background-color: #ffffff;
- color: #330002;
+ background: linear-gradient(135deg, #ffffff 0%, #f5f7fa 100%);
+ border-radius: 20px;
+ padding: 2rem;
+ width: 400px;
+ margin: 2em auto;
+ box-shadow:
+ 0 10px 20px rgba(0, 0, 0, 0.1),
+ 0 6px 6px rgba(0, 0, 0, 0.05),
+ 0 0 100px rgba(0, 0, 0, 0.1);
+ transition: transform 0.2s ease;
+}
- margin-top: 2em;
-
- padding-top: 1em;
- padding-bottom: 1em;
- padding-left: 4em;
- padding-right: 4em;
+.board:hover {
+ transform: translateY(-5px);
+}
- width: 300px;
- margin-left: auto;
- margin-right: auto;
+.board h1 {
+ color: #2d3748;
+ font-size: 2.5rem;
+ margin-bottom: 1.5rem;
+ font-weight: 800;
+ background: linear-gradient(120deg, #2d3748 0%, #4a5568 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ text-align: center;
+}
- box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+.board h4 {
+ color: #4a5568;
+ font-size: 1.25rem;
+ margin: 1rem 0;
+ text-align: center;
+ font-weight: 600;
}
-.box {
- background-color: #62d6fb;
- border-style: solid;
- border-color: #ffffff;
- border-radius: 5px;
+.row {
+ display: flex;
+ justify-content: center;
+ gap: 0.75rem;
+ margin: 0.75rem 0;
+}
+.box {
+ background: white;
+ border: none !important;
+ border-radius: 12px !important;
height: 100px;
width: 100px;
+ font-size: 3rem !important;
+ font-weight: bold;
+ color: #4a5568;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ box-shadow:
+ 0 4px 6px rgba(0, 0, 0, 0.05),
+ 0 1px 3px rgba(0, 0, 0, 0.1);
+}
- font-size: 4em;
+.box:hover {
+ transform: scale(1.05);
+ box-shadow:
+ 0 10px 15px rgba(0, 0, 0, 0.1),
+ 0 4px 6px rgba(0, 0, 0, 0.05);
}
-#reset {
- color: #FF6569;
- font-size: 1.5em;
+.box:active {
+ transform: scale(0.95);
+}
- background-color: #ffffff;
- border-style: solid;
- border-color: #FF6569;
- border-radius: 5px;
+/* Player X styling */
+.box:has(text='X') {
+ background: linear-gradient(135deg, #63b3ed 0%, #4299e1 100%);
+ color: white;
+}
- margin-top: 20px;
- margin-bottom: 20px;
+/* Player O styling */
+.box:has(text='O') {
+ background: linear-gradient(135deg, #f6ad55 0%, #ed8936 100%);
+ color: white;
+}
+#reset {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ border: none;
+ border-radius: 12px;
+ font-size: 1.25rem;
+ font-weight: 600;
+ padding: 1rem 2rem;
width: 100%;
-
- padding: .5em;
+ margin-top: 2rem;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ text-transform: uppercase;
+ letter-spacing: 1px;
}
#reset:hover {
- color: #ffffff;
- background-color: #FF6569
+ transform: translateY(-2px);
+ box-shadow:
+ 0 10px 15px rgba(0, 0, 0, 0.1),
+ 0 4px 6px rgba(0, 0, 0, 0.05);
}
-/* Counter */
+#reset:active {
+ transform: translateY(1px);
+}
+/* Counter */
.buttons {
background-color: #ffffff;
color: #330002;
@@ -131,7 +444,7 @@ h1, h4 {
color: #ffffff;
font-size: 1.5em;
- background-color: #FF6569;
+ background-color: var(--primary-red-color);
border-style: solid;
border-color: #ffffff;
border-radius: 5px;
@@ -141,9 +454,200 @@ h1, h4 {
width: 100%;
- padding: .5em;
+ padding: 0.5em;
}
.increment:hover {
- background-color: #62d6fb;
-}
\ No newline at end of file
+ background-color: var(--secondary-blue-color);
+}
+
+.hook-data-section {
+ border: 2px solid --primary-red-color;
+ border-radius: 5px;
+ margin: 10px 0;
+ padding: 8px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.hook-data-section h4 {
+ margin: 2px 0;
+}
+
+.hook-data-section p {
+ text-align: center;
+ margin: 8px;
+}
+
+.reducer-counter {
+ background-color: #ffffff;
+ color: #330002;
+ padding: 2em;
+ margin-top: 2em;
+ max-width: 500px;
+ margin-left: auto;
+ margin-right: auto;
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
+}
+
+.counter-value {
+ text-align: center;
+ font-size: 1.2em;
+ margin: 1em 0;
+}
+
+.counter-buttons {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ justify-content: center;
+ margin: 1em 0;
+}
+
+.counter-buttons button {
+ color: #ffffff;
+ font-size: 1em;
+ background-color: var(--primary-red-color);
+ border: 2px solid #ffffff;
+ border-radius: 5px;
+ padding: 0.5em 1em;
+ cursor: pointer;
+}
+
+.counter-buttons button:hover {
+ background-color: var(--secondary-blue-color);
+}
+
+.counter-info {
+ text-align: center;
+ margin-top: 2em;
+}
+
+.history-list {
+ margin: 1em 0;
+ padding: 1em;
+ background-color: var(--background-color1);
+ border-radius: 5px;
+ word-wrap: break-word;
+}
+
+.nav {
+ background: var(--theme-nav-background, rgba(255, 255, 255, 0.95));
+ transition: all 0.3s ease;
+}
+
+.nav .link {
+ transition: all 0.3s ease;
+}
+
+[data-theme='dark'] .nav {
+ --theme-nav-background: rgba(26, 32, 44, 0.95);
+}
+
+[data-theme='dark'] .nav .link {
+ color: #f7fafc;
+}
+
+[data-theme='dark'] .nav .link:hover {
+ background: rgba(255, 255, 255, 0.1);
+}
+
+/* Light theme (default) */
+body[data-theme='light'] {
+ background-color: #f6f6f6;
+ color: #1a202c;
+}
+
+/* Dark theme */
+body[data-theme='dark'] {
+ background-color: #121826;
+ color: #f7fafc;
+}
+
+/* Update board styling for dark mode */
+body[data-theme='dark'] .board {
+ background: linear-gradient(135deg, #1e2837 0%, #2d3748 100%);
+ box-shadow:
+ 0 10px 20px rgba(0, 0, 0, 0.2),
+ 0 6px 6px rgba(0, 0, 0, 0.1),
+ 0 0 100px rgba(0, 0, 0, 0.2);
+}
+
+body[data-theme='dark'] .board h1 {
+ background: linear-gradient(120deg, #f7fafc 0%, #e2e8f0 100%);
+ -webkit-background-clip: text;
+}
+
+body[data-theme='dark'] .box {
+ background: #2d3748;
+ color: #f7fafc;
+ box-shadow:
+ 0 4px 6px rgba(0, 0, 0, 0.2),
+ 0 1px 3px rgba(0, 0, 0, 0.3);
+}
+
+/* Update buttons container for dark mode */
+body[data-theme='dark'] .buttons {
+ background-color: #2d3748;
+ color: #f7fafc;
+ box-shadow: rgba(0, 0, 0, 0.5) 0px 5px 15px;
+}
+
+/* Update reducer counter for dark mode */
+body[data-theme='dark'] .reducer-counter {
+ background-color: #2d3748;
+ color: #f7fafc;
+ box-shadow: rgba(0, 0, 0, 0.5) 0px 5px 15px;
+}
+
+body[data-theme='dark'] .history-list {
+ background-color: #1a202c;
+}
+
+/* Update about section for dark mode */
+body[data-theme='dark'] .about {
+ background: linear-gradient(135deg, #2d3748 0%, #1a202c 100%);
+ box-shadow:
+ 0 20px 25px -5px rgba(0, 0, 0, 0.3),
+ 0 10px 10px -5px rgba(0, 0, 0, 0.2),
+ 0 0 100px rgba(0, 0, 0, 0.1);
+}
+
+body[data-theme='dark'] .about h2 {
+ background: linear-gradient(120deg, #f7fafc 0%, #e2e8f0 100%);
+ -webkit-background-clip: text;
+}
+
+body[data-theme='dark'] .about p {
+ color: #e2e8f0;
+}
+
+/* Update nav for dark mode */
+body[data-theme='dark'] .nav {
+ background: rgba(26, 32, 44, 0.95);
+ box-shadow:
+ 0 4px 6px -1px rgba(0, 0, 0, 0.2),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.1);
+}
+
+body[data-theme='dark'] .link {
+ color: #e2e8f0;
+}
+
+body[data-theme='dark'] .link:hover {
+ color: #f7fafc;
+ background: rgba(255, 255, 255, 0.1);
+}
+
+/* Transition for all themed elements */
+.board,
+.buttons,
+.reducer-counter,
+.about,
+.nav,
+.link,
+.box,
+.history-list {
+ transition: all 0.3s ease;
+}
diff --git a/demo-app/src/contexts/AuthContext.tsx b/demo-app/src/contexts/AuthContext.tsx
new file mode 100644
index 000000000..a1109470c
--- /dev/null
+++ b/demo-app/src/contexts/AuthContext.tsx
@@ -0,0 +1,37 @@
+import React, { createContext, useState, useContext } from 'react';
+
+type User = {
+ username: string;
+ isAdmin: boolean;
+} | null;
+
+type AuthContextType = {
+ user: User;
+ login: (username: string) => void;
+ logout: () => void;
+};
+
+export const AuthContext = createContext({
+ user: null,
+ login: () => {},
+ logout: () => {},
+});
+
+export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+ const [user, setUser] = useState(null);
+
+ const login = (username: string) => {
+ setUser({
+ username,
+ isAdmin: username === 'admin',
+ });
+ };
+
+ const logout = () => {
+ setUser(null);
+ };
+
+ return {children} ;
+};
+
+export const useAuth = () => useContext(AuthContext);
diff --git a/demo-app/src/contexts/ThemeContext.tsx b/demo-app/src/contexts/ThemeContext.tsx
new file mode 100644
index 000000000..a95bfb91f
--- /dev/null
+++ b/demo-app/src/contexts/ThemeContext.tsx
@@ -0,0 +1,55 @@
+import React, { createContext, useState, useContext } from 'react';
+
+type Theme = {
+ backgroundColor: string;
+ textColor: string;
+ primaryColor: string;
+ secondaryColor: string;
+};
+
+type ThemeContextType = {
+ theme: Theme;
+ toggleTheme: () => void;
+};
+
+const defaultTheme: Theme = {
+ backgroundColor: '#ffffff',
+ textColor: '#1a202c',
+ primaryColor: '#3182ce',
+ secondaryColor: '#805ad5',
+};
+
+const darkTheme: Theme = {
+ backgroundColor: '#1a202c',
+ textColor: '#f7fafc',
+ primaryColor: '#63b3ed',
+ secondaryColor: '#b794f4',
+};
+
+export const ThemeContext = createContext({
+ theme: defaultTheme,
+ toggleTheme: () => {},
+});
+
+export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+ const [isDark, setIsDark] = useState(false);
+
+ const toggleTheme = () => {
+ setIsDark(!isDark);
+ document.body.setAttribute('data-theme', !isDark ? 'dark' : 'light');
+ };
+
+ // Set initial theme
+ React.useEffect(() => {
+ document.body.setAttribute('data-theme', isDark ? 'dark' : 'light');
+ }, []);
+
+ const value = {
+ theme: isDark ? darkTheme : defaultTheme,
+ toggleTheme,
+ };
+
+ return {children} ;
+};
+
+export const useTheme = () => useContext(ThemeContext);
diff --git a/demo-app/src/index.d.ts b/demo-app/src/index.d.ts
new file mode 100644
index 000000000..7f25dc3a3
--- /dev/null
+++ b/demo-app/src/index.d.ts
@@ -0,0 +1,4 @@
+declare module 'react-dom/client' {
+ const ReactDOMClient: { createRoot: any };
+ export = ReactDOMClient;
+}
diff --git a/demo-app/src/types.ts b/demo-app/src/types.ts
index 44e160f54..013fb8307 100644
--- a/demo-app/src/types.ts
+++ b/demo-app/src/types.ts
@@ -1,10 +1,13 @@
export type Scoreboard = {
- X: number,
- O: number
-}
+ X: number;
+ O: number;
+};
export type Player = 'X' | 'O';
export type BoardText = 'X' | 'O' | '-';
export type BoardContent = Array>;
+
+//will move scoreboard and player into Board.tsx as these two types are only being used there
+//wont make a difference but this is for cleanliness sake
diff --git a/demo-app/webpack.config.js b/demo-app/webpack.config.js
index 3b6da32b5..8dae226ab 100644
--- a/demo-app/webpack.config.js
+++ b/demo-app/webpack.config.js
@@ -17,19 +17,49 @@ module.exports = {
use: {
loader: 'babel-loader',
options: {
- presets: ['@babel/preset-env', '@babel/preset-react'],
+ presets: [
+ [
+ '@babel/preset-env',
+ {
+ targets: {
+ node: 'current',
+ browsers: ['last 2 versions', 'not dead', 'not < 2%', 'not ie 11'],
+ },
+ useBuiltIns: 'usage',
+ corejs: 3,
+ },
+ ],
+ [
+ '@babel/preset-react',
+ {
+ runtime: 'automatic',
+ },
+ ],
+ ],
+ plugins: ['@babel/plugin-transform-runtime'],
},
},
},
{
test: /\.tsx?$/,
- use: 'ts-loader',
+ use: [
+ {
+ loader: 'ts-loader',
+ options: {
+ transpileOnly: true,
+ compilerOptions: {
+ target: 'es2018',
+ module: 'esnext',
+ },
+ },
+ },
+ ],
exclude: /node_modules/,
- }
+ },
],
},
resolve: {
- extensions: ['.jsx', '.js','.ts','.tsx'],
+ extensions: ['.jsx', '.js', '.ts', '.tsx'],
},
plugins: [
new HtmlWebpackPlugin({
@@ -47,8 +77,11 @@ module.exports = {
},
proxy: {
'/api': 'http://localhost:3000',
- secure: false
- }
+ secure: false,
+ },
},
-
-}
\ No newline at end of file
+ watchOptions: {
+ poll: true,
+ ignored: /node_modules/,
+ },
+};
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index efae73c0b..000000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-version: '2'
-services:
- test:
- image: reacttt/test-lint
- container_name: reacttt-test-lint
- volumes:
- - .:/usr/src/app
- - /usr/src/app/node_modules
- command: npm run docker-test-lint
diff --git a/docs/assets/css/main.css b/docs/assets/css/main.css
deleted file mode 100644
index aa04f3b30..000000000
--- a/docs/assets/css/main.css
+++ /dev/null
@@ -1,2679 +0,0 @@
-/*! normalize.css v1.1.3 | MIT License | git.io/normalize */
-/* ==========================================================================
- * * HTML5 display definitions
- * * ========================================================================== */
-/**
- * * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3. */
-article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary {
- display: block;
-}
-
-/**
- * * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. */
-audio, canvas, video {
- display: inline-block;
- *display: inline;
- *zoom: 1;
-}
-
-/**
- * * Prevent modern browsers from displaying `audio` without controls.
- * * Remove excess height in iOS 5 devices. */
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-
-/**
- * * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4.
- * * Known issue: no IE 6 support. */
-[hidden] {
- display: none;
-}
-
-/* ==========================================================================
- * * Base
- * * ========================================================================== */
-/**
- * * 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using
- * * `em` units.
- * * 2. Prevent iOS text size adjust after orientation change, without disabling
- * * user zoom. */
-html {
- font-size: 100%;
- /* 1 */
- -ms-text-size-adjust: 100%;
- /* 2 */
- -webkit-text-size-adjust: 100%;
- /* 2 */
- font-family: sans-serif;
-}
-
-/**
- * * Address `font-family` inconsistency between `textarea` and other form
- * * elements. */
-button, input, select, textarea {
- font-family: sans-serif;
-}
-
-/**
- * * Address margins handled incorrectly in IE 6/7. */
-body {
- margin: 0;
-}
-
-/* ==========================================================================
- * * Links
- * * ========================================================================== */
-/**
- * * Address `outline` inconsistency between Chrome and other browsers. */
-a:focus {
- outline: thin dotted;
-}
-a:active, a:hover {
- outline: 0;
-}
-
-/**
- * * Improve readability when focused and also mouse hovered in all browsers. */
-/* ==========================================================================
- * * Typography
- * * ========================================================================== */
-/**
- * * Address font sizes and margins set differently in IE 6/7.
- * * Address font sizes within `section` and `article` in Firefox 4+, Safari 5,
- * * and Chrome. */
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-h2 {
- font-size: 1.5em;
- margin: 0.83em 0;
-}
-
-h3 {
- font-size: 1.17em;
- margin: 1em 0;
-}
-
-h4, .tsd-index-panel h3 {
- font-size: 1em;
- margin: 1.33em 0;
-}
-
-h5 {
- font-size: 0.83em;
- margin: 1.67em 0;
-}
-
-h6 {
- font-size: 0.67em;
- margin: 2.33em 0;
-}
-
-/**
- * * Address styling not present in IE 7/8/9, Safari 5, and Chrome. */
-abbr[title] {
- border-bottom: 1px dotted;
-}
-
-/**
- * * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. */
-b, strong {
- font-weight: bold;
-}
-
-blockquote {
- margin: 1em 40px;
-}
-
-/**
- * * Address styling not present in Safari 5 and Chrome. */
-dfn {
- font-style: italic;
-}
-
-/**
- * * Address differences between Firefox and other browsers.
- * * Known issue: no IE 6/7 normalization. */
-hr {
- box-sizing: content-box;
- height: 0;
-}
-
-/**
- * * Address styling not present in IE 6/7/8/9. */
-mark {
- background: #ff0;
- color: #000;
-}
-
-/**
- * * Address margins set differently in IE 6/7. */
-p, pre {
- margin: 1em 0;
-}
-
-/**
- * * Correct font family set oddly in IE 6, Safari 4/5, and Chrome. */
-code, kbd, pre, samp {
- font-family: monospace, serif;
- _font-family: "courier new", monospace;
- font-size: 1em;
-}
-
-/**
- * * Improve readability of pre-formatted text in all browsers. */
-pre {
- white-space: pre;
- white-space: pre-wrap;
- word-wrap: break-word;
-}
-
-/**
- * * Address CSS quotes not supported in IE 6/7. */
-q {
- quotes: none;
-}
-q:before, q:after {
- content: "";
- content: none;
-}
-
-/**
- * * Address `quotes` property not supported in Safari 4. */
-/**
- * * Address inconsistent and variable font size in all browsers. */
-small {
- font-size: 80%;
-}
-
-/**
- * * Prevent `sub` and `sup` affecting `line-height` in all browsers. */
-sub {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
- top: -0.5em;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-/* ==========================================================================
- * * Lists
- * * ========================================================================== */
-/**
- * * Address margins set differently in IE 6/7. */
-dl, menu, ol, ul {
- margin: 1em 0;
-}
-
-dd {
- margin: 0 0 0 40px;
-}
-
-/**
- * * Address paddings set differently in IE 6/7. */
-menu, ol, ul {
- padding: 0 0 0 40px;
-}
-
-/**
- * * Correct list images handled incorrectly in IE 7. */
-nav ul, nav ol {
- list-style: none;
- list-style-image: none;
-}
-
-/* ==========================================================================
- * * Embedded content
- * * ========================================================================== */
-/**
- * * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3.
- * * 2. Improve image quality when scaled in IE 7. */
-img {
- border: 0;
- /* 1 */
- -ms-interpolation-mode: bicubic;
-}
-
-/* 2 */
-/**
- * * Correct overflow displayed oddly in IE 9. */
-svg:not(:root) {
- overflow: hidden;
-}
-
-/* ==========================================================================
- * * Figures
- * * ========================================================================== */
-/**
- * * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. */
-figure, form {
- margin: 0;
-}
-
-/* ==========================================================================
- * * Forms
- * * ========================================================================== */
-/**
- * * Correct margin displayed oddly in IE 6/7. */
-/**
- * * Define consistent border, margin, and padding. */
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * * 1. Correct color not being inherited in IE 6/7/8/9.
- * * 2. Correct text not wrapping in Firefox 3.
- * * 3. Correct alignment displayed oddly in IE 6/7. */
-legend {
- border: 0;
- /* 1 */
- padding: 0;
- white-space: normal;
- /* 2 */
- *margin-left: -7px;
-}
-
-/* 3 */
-/**
- * * 1. Correct font size not being inherited in all browsers.
- * * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5,
- * * and Chrome.
- * * 3. Improve appearance and consistency in all browsers. */
-button, input, select, textarea {
- font-size: 100%;
- /* 1 */
- margin: 0;
- /* 2 */
- vertical-align: baseline;
- /* 3 */
- *vertical-align: middle;
-}
-
-/* 3 */
-/**
- * * Address Firefox 3+ setting `line-height` on `input` using `!important` in
- * * the UA stylesheet. */
-button, input {
- line-height: normal;
-}
-
-/**
- * * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * * All other form control elements do not inherit `text-transform` values.
- * * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+.
- * * Correct `select` style inheritance in Firefox 4+ and Opera. */
-button, select {
- text-transform: none;
-}
-
-/**
- * * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * * and `video` controls.
- * * 2. Correct inability to style clickable `input` types in iOS.
- * * 3. Improve usability and consistency of cursor style between image-type
- * * `input` and others.
- * * 4. Remove inner spacing in IE 7 without affecting normal text inputs.
- * * Known issue: inner spacing remains in IE 6. */
-button, html input[type=button] {
- -webkit-appearance: button;
- /* 2 */
- cursor: pointer;
- /* 3 */
- *overflow: visible;
-}
-
-/* 4 */
-input[type=reset], input[type=submit] {
- -webkit-appearance: button;
- /* 2 */
- cursor: pointer;
- /* 3 */
- *overflow: visible;
-}
-
-/* 4 */
-/**
- * * Re-set default cursor for disabled elements. */
-button[disabled], html input[disabled] {
- cursor: default;
-}
-
-/**
- * * 1. Address box sizing set to content-box in IE 8/9.
- * * 2. Remove excess padding in IE 8/9.
- * * 3. Remove excess padding in IE 7.
- * * Known issue: excess padding remains in IE 6. */
-input {
- /* 3 */
-}
-input[type=checkbox], input[type=radio] {
- box-sizing: border-box;
- /* 1 */
- padding: 0;
- /* 2 */
- *height: 13px;
- /* 3 */
- *width: 13px;
-}
-input[type=search] {
- -webkit-appearance: textfield;
- /* 1 */
- /* 2 */
- box-sizing: content-box;
-}
-input[type=search]::-webkit-search-cancel-button, input[type=search]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/**
- * * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
- * * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
- * * (include `-moz` to future-proof). */
-/**
- * * Remove inner padding and search cancel button in Safari 5 and Chrome
- * * on OS X. */
-/**
- * * Remove inner padding and border in Firefox 3+. */
-button::-moz-focus-inner, input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-/**
- * * 1. Remove default vertical scrollbar in IE 6/7/8/9.
- * * 2. Improve readability and alignment in all browsers. */
-textarea {
- overflow: auto;
- /* 1 */
- vertical-align: top;
-}
-
-/* 2 */
-/* ==========================================================================
- * * Tables
- * * ========================================================================== */
-/**
- * * Remove most spacing between table cells. */
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-
-/* *
- * *Visual Studio-like style based on original C# coloring by Jason Diamond */
-.hljs {
- display: inline-block;
- padding: 0.5em;
- background: white;
- color: black;
-}
-
-.hljs-comment, .hljs-annotation, .hljs-template_comment, .diff .hljs-header, .hljs-chunk, .apache .hljs-cbracket {
- color: #008000;
-}
-
-.hljs-keyword, .hljs-id, .hljs-built_in, .css .smalltalk .hljs-class, .hljs-winutils, .bash .hljs-variable, .tex .hljs-command, .hljs-request, .hljs-status, .nginx .hljs-title {
- color: #00f;
-}
-
-.xml .hljs-tag {
- color: #00f;
-}
-.xml .hljs-tag .hljs-value {
- color: #00f;
-}
-
-.hljs-string, .hljs-title, .hljs-parent, .hljs-tag .hljs-value, .hljs-rules .hljs-value {
- color: #a31515;
-}
-
-.ruby .hljs-symbol {
- color: #a31515;
-}
-.ruby .hljs-symbol .hljs-string {
- color: #a31515;
-}
-
-.hljs-template_tag, .django .hljs-variable, .hljs-addition, .hljs-flow, .hljs-stream, .apache .hljs-tag, .hljs-date, .tex .hljs-formula, .coffeescript .hljs-attribute {
- color: #a31515;
-}
-
-.ruby .hljs-string, .hljs-decorator, .hljs-filter .hljs-argument, .hljs-localvars, .hljs-array, .hljs-attr_selector, .hljs-pseudo, .hljs-pi, .hljs-doctype, .hljs-deletion, .hljs-envvar, .hljs-shebang, .hljs-preprocessor, .hljs-pragma, .userType, .apache .hljs-sqbracket, .nginx .hljs-built_in, .tex .hljs-special, .hljs-prompt {
- color: #2b91af;
-}
-
-.hljs-phpdoc, .hljs-javadoc, .hljs-xmlDocTag {
- color: #808080;
-}
-
-.vhdl .hljs-typename {
- font-weight: bold;
-}
-.vhdl .hljs-string {
- color: #666666;
-}
-.vhdl .hljs-literal {
- color: #a31515;
-}
-.vhdl .hljs-attribute {
- color: #00b0e8;
-}
-
-.xml .hljs-attribute {
- color: #f00;
-}
-
-ul.tsd-descriptions > li > :first-child, .tsd-panel > :first-child, .col > :first-child, .col-11 > :first-child, .col-10 > :first-child, .col-9 > :first-child, .col-8 > :first-child, .col-7 > :first-child, .col-6 > :first-child, .col-5 > :first-child, .col-4 > :first-child, .col-3 > :first-child, .col-2 > :first-child, .col-1 > :first-child,
-ul.tsd-descriptions > li > :first-child > :first-child,
-.tsd-panel > :first-child > :first-child,
-.col > :first-child > :first-child,
-.col-11 > :first-child > :first-child,
-.col-10 > :first-child > :first-child,
-.col-9 > :first-child > :first-child,
-.col-8 > :first-child > :first-child,
-.col-7 > :first-child > :first-child,
-.col-6 > :first-child > :first-child,
-.col-5 > :first-child > :first-child,
-.col-4 > :first-child > :first-child,
-.col-3 > :first-child > :first-child,
-.col-2 > :first-child > :first-child,
-.col-1 > :first-child > :first-child,
-ul.tsd-descriptions > li > :first-child > :first-child > :first-child,
-.tsd-panel > :first-child > :first-child > :first-child,
-.col > :first-child > :first-child > :first-child,
-.col-11 > :first-child > :first-child > :first-child,
-.col-10 > :first-child > :first-child > :first-child,
-.col-9 > :first-child > :first-child > :first-child,
-.col-8 > :first-child > :first-child > :first-child,
-.col-7 > :first-child > :first-child > :first-child,
-.col-6 > :first-child > :first-child > :first-child,
-.col-5 > :first-child > :first-child > :first-child,
-.col-4 > :first-child > :first-child > :first-child,
-.col-3 > :first-child > :first-child > :first-child,
-.col-2 > :first-child > :first-child > :first-child,
-.col-1 > :first-child > :first-child > :first-child {
- margin-top: 0;
-}
-ul.tsd-descriptions > li > :last-child, .tsd-panel > :last-child, .col > :last-child, .col-11 > :last-child, .col-10 > :last-child, .col-9 > :last-child, .col-8 > :last-child, .col-7 > :last-child, .col-6 > :last-child, .col-5 > :last-child, .col-4 > :last-child, .col-3 > :last-child, .col-2 > :last-child, .col-1 > :last-child,
-ul.tsd-descriptions > li > :last-child > :last-child,
-.tsd-panel > :last-child > :last-child,
-.col > :last-child > :last-child,
-.col-11 > :last-child > :last-child,
-.col-10 > :last-child > :last-child,
-.col-9 > :last-child > :last-child,
-.col-8 > :last-child > :last-child,
-.col-7 > :last-child > :last-child,
-.col-6 > :last-child > :last-child,
-.col-5 > :last-child > :last-child,
-.col-4 > :last-child > :last-child,
-.col-3 > :last-child > :last-child,
-.col-2 > :last-child > :last-child,
-.col-1 > :last-child > :last-child,
-ul.tsd-descriptions > li > :last-child > :last-child > :last-child,
-.tsd-panel > :last-child > :last-child > :last-child,
-.col > :last-child > :last-child > :last-child,
-.col-11 > :last-child > :last-child > :last-child,
-.col-10 > :last-child > :last-child > :last-child,
-.col-9 > :last-child > :last-child > :last-child,
-.col-8 > :last-child > :last-child > :last-child,
-.col-7 > :last-child > :last-child > :last-child,
-.col-6 > :last-child > :last-child > :last-child,
-.col-5 > :last-child > :last-child > :last-child,
-.col-4 > :last-child > :last-child > :last-child,
-.col-3 > :last-child > :last-child > :last-child,
-.col-2 > :last-child > :last-child > :last-child,
-.col-1 > :last-child > :last-child > :last-child {
- margin-bottom: 0;
-}
-
-.container {
- max-width: 1200px;
- margin: 0 auto;
- padding: 0 40px;
-}
-@media (max-width: 640px) {
- .container {
- padding: 0 20px;
- }
-}
-
-.container-main {
- padding-bottom: 200px;
-}
-
-.row {
- display: -ms-flexbox;
- display: flex;
- position: relative;
- margin: 0 -10px;
-}
-.row:after {
- visibility: hidden;
- display: block;
- content: "";
- clear: both;
- height: 0;
-}
-
-.col, .col-11, .col-10, .col-9, .col-8, .col-7, .col-6, .col-5, .col-4, .col-3, .col-2, .col-1 {
- box-sizing: border-box;
- float: left;
- padding: 0 10px;
-}
-
-.col-1 {
- width: 8.3333333333%;
-}
-
-.offset-1 {
- margin-left: 8.3333333333%;
-}
-
-.col-2 {
- width: 16.6666666667%;
-}
-
-.offset-2 {
- margin-left: 16.6666666667%;
-}
-
-.col-3 {
- width: 25%;
-}
-
-.offset-3 {
- margin-left: 25%;
-}
-
-.col-4 {
- width: 33.3333333333%;
-}
-
-.offset-4 {
- margin-left: 33.3333333333%;
-}
-
-.col-5 {
- width: 41.6666666667%;
-}
-
-.offset-5 {
- margin-left: 41.6666666667%;
-}
-
-.col-6 {
- width: 50%;
-}
-
-.offset-6 {
- margin-left: 50%;
-}
-
-.col-7 {
- width: 58.3333333333%;
-}
-
-.offset-7 {
- margin-left: 58.3333333333%;
-}
-
-.col-8 {
- width: 66.6666666667%;
-}
-
-.offset-8 {
- margin-left: 66.6666666667%;
-}
-
-.col-9 {
- width: 75%;
-}
-
-.offset-9 {
- margin-left: 75%;
-}
-
-.col-10 {
- width: 83.3333333333%;
-}
-
-.offset-10 {
- margin-left: 83.3333333333%;
-}
-
-.col-11 {
- width: 91.6666666667%;
-}
-
-.offset-11 {
- margin-left: 91.6666666667%;
-}
-
-.tsd-kind-icon {
- display: block;
- position: relative;
- padding-left: 20px;
- text-indent: -20px;
-}
-.tsd-kind-icon:before {
- content: "";
- display: inline-block;
- vertical-align: middle;
- width: 17px;
- height: 17px;
- margin: 0 3px 2px 0;
- background-image: url(../images/icons.png);
-}
-@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
- .tsd-kind-icon:before {
- background-image: url(../images/icons@2x.png);
- background-size: 238px 204px;
- }
-}
-
-.tsd-signature.tsd-kind-icon:before {
- background-position: 0 -153px;
-}
-
-.tsd-kind-object-literal > .tsd-kind-icon:before {
- background-position: 0px -17px;
-}
-.tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -17px;
-}
-.tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -17px;
-}
-
-.tsd-kind-class > .tsd-kind-icon:before {
- background-position: 0px -34px;
-}
-.tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -34px;
-}
-.tsd-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -34px;
-}
-
-.tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before {
- background-position: 0px -51px;
-}
-.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -51px;
-}
-.tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -51px;
-}
-
-.tsd-kind-interface > .tsd-kind-icon:before {
- background-position: 0px -68px;
-}
-.tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -68px;
-}
-.tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -68px;
-}
-
-.tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before {
- background-position: 0px -85px;
-}
-.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -85px;
-}
-.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -85px;
-}
-
-.tsd-kind-namespace > .tsd-kind-icon:before {
- background-position: 0px -102px;
-}
-.tsd-kind-namespace.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -102px;
-}
-.tsd-kind-namespace.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -102px;
-}
-
-.tsd-kind-module > .tsd-kind-icon:before {
- background-position: 0px -102px;
-}
-.tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -102px;
-}
-.tsd-kind-module.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -102px;
-}
-
-.tsd-kind-enum > .tsd-kind-icon:before {
- background-position: 0px -119px;
-}
-.tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -119px;
-}
-.tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -119px;
-}
-
-.tsd-kind-enum-member > .tsd-kind-icon:before {
- background-position: 0px -136px;
-}
-.tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -136px;
-}
-.tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -136px;
-}
-
-.tsd-kind-signature > .tsd-kind-icon:before {
- background-position: 0px -153px;
-}
-.tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -153px;
-}
-.tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -153px;
-}
-
-.tsd-kind-type-alias > .tsd-kind-icon:before {
- background-position: 0px -170px;
-}
-.tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -170px;
-}
-.tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -170px;
-}
-
-.tsd-kind-type-alias.tsd-has-type-parameter > .tsd-kind-icon:before {
- background-position: 0px -187px;
-}
-.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -17px -187px;
-}
-.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before {
- background-position: -34px -187px;
-}
-
-.tsd-kind-variable > .tsd-kind-icon:before {
- background-position: -136px -0px;
-}
-.tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -0px;
-}
-.tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -0px;
-}
-.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -0px;
-}
-
-.tsd-kind-property > .tsd-kind-icon:before {
- background-position: -136px -0px;
-}
-.tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -0px;
-}
-.tsd-kind-property.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -0px;
-}
-.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -0px;
-}
-
-.tsd-kind-get-signature > .tsd-kind-icon:before {
- background-position: -136px -17px;
-}
-.tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -17px;
-}
-.tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -17px;
-}
-.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -17px;
-}
-
-.tsd-kind-set-signature > .tsd-kind-icon:before {
- background-position: -136px -34px;
-}
-.tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -34px;
-}
-.tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -34px;
-}
-.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -34px;
-}
-
-.tsd-kind-accessor > .tsd-kind-icon:before {
- background-position: -136px -51px;
-}
-.tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -51px;
-}
-.tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -51px;
-}
-.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -51px;
-}
-
-.tsd-kind-function > .tsd-kind-icon:before {
- background-position: -136px -68px;
-}
-.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -68px;
-}
-.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -68px;
-}
-.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -68px;
-}
-
-.tsd-kind-method > .tsd-kind-icon:before {
- background-position: -136px -68px;
-}
-.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -68px;
-}
-.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -68px;
-}
-.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -68px;
-}
-
-.tsd-kind-call-signature > .tsd-kind-icon:before {
- background-position: -136px -68px;
-}
-.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -68px;
-}
-.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -68px;
-}
-.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -68px;
-}
-
-.tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before {
- background-position: -136px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -85px;
-}
-.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -85px;
-}
-
-.tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before {
- background-position: -136px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -85px;
-}
-.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -85px;
-}
-
-.tsd-kind-constructor > .tsd-kind-icon:before {
- background-position: -136px -102px;
-}
-.tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -102px;
-}
-.tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -102px;
-}
-.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -102px;
-}
-
-.tsd-kind-constructor-signature > .tsd-kind-icon:before {
- background-position: -136px -102px;
-}
-.tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -102px;
-}
-.tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -102px;
-}
-.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -102px;
-}
-
-.tsd-kind-index-signature > .tsd-kind-icon:before {
- background-position: -136px -119px;
-}
-.tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -119px;
-}
-.tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -119px;
-}
-.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -119px;
-}
-
-.tsd-kind-event > .tsd-kind-icon:before {
- background-position: -136px -136px;
-}
-.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -136px;
-}
-.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -136px;
-}
-.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -136px;
-}
-
-.tsd-is-static > .tsd-kind-icon:before {
- background-position: -136px -153px;
-}
-.tsd-is-static.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -153px;
-}
-.tsd-is-static.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -153px;
-}
-.tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -153px;
-}
-.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -153px;
-}
-.tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -153px;
-}
-.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -153px;
-}
-.tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -153px;
-}
-.tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -153px;
-}
-.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -153px;
-}
-.tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -153px;
-}
-.tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -153px;
-}
-.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -153px;
-}
-
-.tsd-is-static.tsd-kind-function > .tsd-kind-icon:before {
- background-position: -136px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -170px;
-}
-.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -170px;
-}
-
-.tsd-is-static.tsd-kind-method > .tsd-kind-icon:before {
- background-position: -136px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -170px;
-}
-.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -170px;
-}
-
-.tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before {
- background-position: -136px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -170px;
-}
-.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -170px;
-}
-
-.tsd-is-static.tsd-kind-event > .tsd-kind-icon:before {
- background-position: -136px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -153px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before {
- background-position: -51px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -68px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -85px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -102px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before {
- background-position: -170px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before {
- background-position: -187px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before {
- background-position: -119px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before {
- background-position: -204px -187px;
-}
-.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before {
- background-position: -221px -187px;
-}
-
-@keyframes fade-in {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
-}
-@keyframes fade-out {
- from {
- opacity: 1;
- visibility: visible;
- }
- to {
- opacity: 0;
- }
-}
-@keyframes fade-in-delayed {
- 0% {
- opacity: 0;
- }
- 33% {
- opacity: 0;
- }
- 100% {
- opacity: 1;
- }
-}
-@keyframes fade-out-delayed {
- 0% {
- opacity: 1;
- visibility: visible;
- }
- 66% {
- opacity: 0;
- }
- 100% {
- opacity: 0;
- }
-}
-@keyframes shift-to-left {
- from {
- transform: translate(0, 0);
- }
- to {
- transform: translate(-25%, 0);
- }
-}
-@keyframes unshift-to-left {
- from {
- transform: translate(-25%, 0);
- }
- to {
- transform: translate(0, 0);
- }
-}
-@keyframes pop-in-from-right {
- from {
- transform: translate(100%, 0);
- }
- to {
- transform: translate(0, 0);
- }
-}
-@keyframes pop-out-to-right {
- from {
- transform: translate(0, 0);
- visibility: visible;
- }
- to {
- transform: translate(100%, 0);
- }
-}
-body {
- background: #fdfdfd;
- font-family: "Segoe UI", sans-serif;
- font-size: 16px;
- color: #222;
-}
-
-a {
- color: #4da6ff;
- text-decoration: none;
-}
-a:hover {
- text-decoration: underline;
-}
-
-code, pre {
- font-family: 'Roboto', sans-serif;
- padding: 0.2em;
- margin: 0;
- font-size: 14px;
- background-color: rgba(0, 0, 0, 0.04);
-}
-
-pre {
- padding: 10px;
-}
-pre code {
- padding: 0;
- font-size: 100%;
- background-color: transparent;
-}
-
-.tsd-typography {
- line-height: 1.333em;
-}
-.tsd-typography ul {
- list-style: square;
- padding: 0 0 0 20px;
- margin: 0;
-}
-.tsd-typography h4, .tsd-typography .tsd-index-panel h3, .tsd-index-panel .tsd-typography h3, .tsd-typography h5, .tsd-typography h6 {
- font-size: 1em;
- margin: 0;
-}
-.tsd-typography h5, .tsd-typography h6 {
- font-weight: normal;
-}
-.tsd-typography p, .tsd-typography ul, .tsd-typography ol {
- margin: 1em 0;
-}
-
-@media (min-width: 901px) and (max-width: 1024px) {
- html.default .col-content {
- width: 72%;
- }
- html.default .col-menu {
- width: 28%;
- }
- html.default .tsd-navigation {
- padding-left: 10px;
- }
-}
-@media (max-width: 900px) {
- html.default .col-content {
- float: none;
- width: 100%;
- }
- html.default .col-menu {
- position: fixed !important;
- overflow: auto;
- -webkit-overflow-scrolling: touch;
- z-index: 1024;
- top: 0 !important;
- bottom: 0 !important;
- left: auto !important;
- right: 0 !important;
- width: 100%;
- padding: 20px 20px 0 0;
- max-width: 450px;
- visibility: hidden;
- background-color: #fff;
- transform: translate(100%, 0);
- }
- html.default .col-menu > *:last-child {
- padding-bottom: 20px;
- }
- html.default .overlay {
- content: "";
- display: block;
- position: fixed;
- z-index: 1023;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.75);
- visibility: hidden;
- }
- html.default.to-has-menu .overlay {
- animation: fade-in 0.4s;
- }
- html.default.to-has-menu header,
-html.default.to-has-menu footer,
-html.default.to-has-menu .col-content {
- animation: shift-to-left 0.4s;
- }
- html.default.to-has-menu .col-menu {
- animation: pop-in-from-right 0.4s;
- }
- html.default.from-has-menu .overlay {
- animation: fade-out 0.4s;
- }
- html.default.from-has-menu header,
-html.default.from-has-menu footer,
-html.default.from-has-menu .col-content {
- animation: unshift-to-left 0.4s;
- }
- html.default.from-has-menu .col-menu {
- animation: pop-out-to-right 0.4s;
- }
- html.default.has-menu body {
- overflow: hidden;
- }
- html.default.has-menu .overlay {
- visibility: visible;
- }
- html.default.has-menu header,
-html.default.has-menu footer,
-html.default.has-menu .col-content {
- transform: translate(-25%, 0);
- }
- html.default.has-menu .col-menu {
- visibility: visible;
- transform: translate(0, 0);
- }
-}
-
-.tsd-page-title {
- padding: 70px 0 20px 0;
- margin: 0 0 40px 0;
- background: #fff;
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.35);
-}
-.tsd-page-title h1 {
- margin: 0;
-}
-
-.tsd-breadcrumb {
- margin: 0;
- padding: 0;
- color: #808080;
-}
-.tsd-breadcrumb a {
- color: #808080;
- text-decoration: none;
-}
-.tsd-breadcrumb a:hover {
- text-decoration: underline;
-}
-.tsd-breadcrumb li {
- display: inline;
-}
-.tsd-breadcrumb li:after {
- content: " / ";
-}
-
-html.minimal .container {
- margin: 0;
-}
-html.minimal .container-main {
- padding-top: 50px;
- padding-bottom: 0;
-}
-html.minimal .content-wrap {
- padding-left: 300px;
-}
-html.minimal .tsd-navigation {
- position: fixed !important;
- overflow: auto;
- -webkit-overflow-scrolling: touch;
- box-sizing: border-box;
- z-index: 1;
- left: 0;
- top: 40px;
- bottom: 0;
- width: 300px;
- padding: 20px;
- margin: 0;
-}
-html.minimal .tsd-member .tsd-member {
- margin-left: 0;
-}
-html.minimal .tsd-page-toolbar {
- position: fixed;
- z-index: 2;
-}
-html.minimal #tsd-filter .tsd-filter-group {
- right: 0;
- transform: none;
-}
-html.minimal footer {
- background-color: transparent;
-}
-html.minimal footer .container {
- padding: 0;
-}
-html.minimal .tsd-generator {
- padding: 0;
-}
-@media (max-width: 900px) {
- html.minimal .tsd-navigation {
- display: none;
- }
- html.minimal .content-wrap {
- padding-left: 0;
- }
-}
-
-dl.tsd-comment-tags {
- overflow: hidden;
-}
-dl.tsd-comment-tags dt {
- float: left;
- padding: 1px 5px;
- margin: 0 10px 0 0;
- border-radius: 4px;
- border: 1px solid #808080;
- color: #808080;
- font-size: 0.8em;
- font-weight: normal;
-}
-dl.tsd-comment-tags dd {
- margin: 0 0 10px 0;
-}
-dl.tsd-comment-tags dd:before, dl.tsd-comment-tags dd:after {
- display: table;
- content: " ";
-}
-dl.tsd-comment-tags dd pre, dl.tsd-comment-tags dd:after {
- clear: both;
-}
-dl.tsd-comment-tags p {
- margin: 0;
-}
-
-.tsd-panel.tsd-comment .lead {
- font-size: 1.1em;
- line-height: 1.333em;
- margin-bottom: 2em;
-}
-.tsd-panel.tsd-comment .lead:last-child {
- margin-bottom: 0;
-}
-
-.toggle-protected .tsd-is-private {
- display: none;
-}
-
-.toggle-public .tsd-is-private,
-.toggle-public .tsd-is-protected,
-.toggle-public .tsd-is-private-protected {
- display: none;
-}
-
-.toggle-inherited .tsd-is-inherited {
- display: none;
-}
-
-.toggle-only-exported .tsd-is-not-exported {
- display: none;
-}
-
-.toggle-externals .tsd-is-external {
- display: none;
-}
-
-#tsd-filter {
- position: relative;
- display: inline-block;
- height: 40px;
- vertical-align: bottom;
-}
-.no-filter #tsd-filter {
- display: none;
-}
-#tsd-filter .tsd-filter-group {
- display: inline-block;
- height: 40px;
- vertical-align: bottom;
- white-space: nowrap;
-}
-#tsd-filter input {
- display: none;
-}
-@media (max-width: 900px) {
- #tsd-filter .tsd-filter-group {
- display: block;
- position: absolute;
- top: 40px;
- right: 20px;
- height: auto;
- background-color: #fff;
- visibility: hidden;
- transform: translate(50%, 0);
- box-shadow: 0 0 4px rgba(0, 0, 0, 0.25);
- }
- .has-options #tsd-filter .tsd-filter-group {
- visibility: visible;
- }
- .to-has-options #tsd-filter .tsd-filter-group {
- animation: fade-in 0.2s;
- }
- .from-has-options #tsd-filter .tsd-filter-group {
- animation: fade-out 0.2s;
- }
- #tsd-filter label,
-#tsd-filter .tsd-select {
- display: block;
- padding-right: 20px;
- }
-}
-
-footer {
- border-top: 1px solid #eee;
- background-color: #fff;
-}
-footer.with-border-bottom {
- border-bottom: 1px solid #eee;
-}
-footer .tsd-legend-group {
- font-size: 0;
-}
-footer .tsd-legend {
- display: inline-block;
- width: 25%;
- padding: 0;
- font-size: 16px;
- list-style: none;
- line-height: 1.333em;
- vertical-align: top;
-}
-@media (max-width: 900px) {
- footer .tsd-legend {
- width: 50%;
- }
-}
-
-.tsd-hierarchy {
- list-style: square;
- padding: 0 0 0 20px;
- margin: 0;
-}
-.tsd-hierarchy .target {
- font-weight: bold;
-}
-
-.tsd-index-panel .tsd-index-content {
- margin-bottom: -30px !important;
-}
-.tsd-index-panel .tsd-index-section {
- margin-bottom: 30px !important;
-}
-.tsd-index-panel h3 {
- margin: 0 -20px 10px -20px;
- padding: 0 20px 10px 20px;
- border-bottom: 1px solid #eee;
-}
-.tsd-index-panel ul.tsd-index-list {
- -moz-column-count: 3;
- -ms-column-count: 3;
- -o-column-count: 3;
- column-count: 3;
- -moz-column-gap: 20px;
- -ms-column-gap: 20px;
- -o-column-gap: 20px;
- column-gap: 20px;
- padding: 0;
- list-style: none;
- line-height: 1.333em;
-}
-@media (max-width: 900px) {
- .tsd-index-panel ul.tsd-index-list {
- -moz-column-count: 1;
- -ms-column-count: 1;
- -o-column-count: 1;
- column-count: 1;
- }
-}
-@media (min-width: 901px) and (max-width: 1024px) {
- .tsd-index-panel ul.tsd-index-list {
- -moz-column-count: 2;
- -ms-column-count: 2;
- -o-column-count: 2;
- column-count: 2;
- }
-}
-.tsd-index-panel ul.tsd-index-list li {
- -webkit-page-break-inside: avoid;
- -moz-page-break-inside: avoid;
- -ms-page-break-inside: avoid;
- -o-page-break-inside: avoid;
- page-break-inside: avoid;
-}
-.tsd-index-panel a,
-.tsd-index-panel .tsd-parent-kind-module a {
- color: #9600ff;
-}
-.tsd-index-panel .tsd-parent-kind-interface a {
- color: #7da01f;
-}
-.tsd-index-panel .tsd-parent-kind-enum a {
- color: #cc9900;
-}
-.tsd-index-panel .tsd-parent-kind-class a {
- color: #4da6ff;
-}
-.tsd-index-panel .tsd-kind-module a {
- color: #9600ff;
-}
-.tsd-index-panel .tsd-kind-interface a {
- color: #7da01f;
-}
-.tsd-index-panel .tsd-kind-enum a {
- color: #cc9900;
-}
-.tsd-index-panel .tsd-kind-class a {
- color: #4da6ff;
-}
-.tsd-index-panel .tsd-is-private a {
- color: #808080;
-}
-
-.tsd-flag {
- display: inline-block;
- padding: 1px 5px;
- border-radius: 4px;
- color: #fff;
- background-color: #808080;
- text-indent: 0;
- font-size: 14px;
- font-weight: normal;
-}
-
-.tsd-anchor {
- position: absolute;
- top: -100px;
-}
-
-.tsd-member {
- position: relative;
-}
-.tsd-member .tsd-anchor + h3 {
- margin-top: 0;
- margin-bottom: 0;
- border-bottom: none;
-}
-
-.tsd-navigation {
- margin: 0 0 0 40px;
-}
-.tsd-navigation a {
- display: block;
- padding-top: 2px;
- padding-bottom: 2px;
- border-left: 2px solid transparent;
- color: #222;
- text-decoration: none;
- transition: border-left-color 0.1s;
-}
-.tsd-navigation a:hover {
- text-decoration: underline;
-}
-.tsd-navigation ul {
- margin: 0;
- padding: 0;
- list-style: none;
-}
-.tsd-navigation li {
- padding: 0;
-}
-
-.tsd-navigation.primary {
- padding-bottom: 40px;
-}
-.tsd-navigation.primary a {
- display: block;
- padding-top: 6px;
- padding-bottom: 6px;
-}
-.tsd-navigation.primary ul li a {
- padding-left: 5px;
-}
-.tsd-navigation.primary ul li li a {
- padding-left: 25px;
-}
-.tsd-navigation.primary ul li li li a {
- padding-left: 45px;
-}
-.tsd-navigation.primary ul li li li li a {
- padding-left: 65px;
-}
-.tsd-navigation.primary ul li li li li li a {
- padding-left: 85px;
-}
-.tsd-navigation.primary ul li li li li li li a {
- padding-left: 105px;
-}
-.tsd-navigation.primary > ul {
- border-bottom: 1px solid #eee;
-}
-.tsd-navigation.primary li {
- border-top: 1px solid #eee;
-}
-.tsd-navigation.primary li.current > a {
- font-weight: bold;
-}
-.tsd-navigation.primary li.label span {
- display: block;
- padding: 20px 0 6px 5px;
- color: #808080;
-}
-.tsd-navigation.primary li.globals + li > span, .tsd-navigation.primary li.globals + li > a {
- padding-top: 20px;
-}
-
-.tsd-navigation.secondary {
- max-height: calc(100vh - 1rem - 40px);
- overflow: auto;
- position: -webkit-sticky;
- position: sticky;
- top: calc(.5rem + 40px);
- transition: 0.3s;
-}
-.tsd-navigation.secondary.tsd-navigation--toolbar-hide {
- max-height: calc(100vh - 1rem);
- top: 0.5rem;
-}
-.tsd-navigation.secondary ul {
- transition: opacity 0.2s;
-}
-.tsd-navigation.secondary ul li a {
- padding-left: 25px;
-}
-.tsd-navigation.secondary ul li li a {
- padding-left: 45px;
-}
-.tsd-navigation.secondary ul li li li a {
- padding-left: 65px;
-}
-.tsd-navigation.secondary ul li li li li a {
- padding-left: 85px;
-}
-.tsd-navigation.secondary ul li li li li li a {
- padding-left: 105px;
-}
-.tsd-navigation.secondary ul li li li li li li a {
- padding-left: 125px;
-}
-.tsd-navigation.secondary ul.current a {
- border-left-color: #eee;
-}
-.tsd-navigation.secondary li.focus > a,
-.tsd-navigation.secondary ul.current li.focus > a {
- border-left-color: #000;
-}
-.tsd-navigation.secondary li.current {
- margin-top: 20px;
- margin-bottom: 20px;
- border-left-color: #eee;
-}
-.tsd-navigation.secondary li.current > a {
- font-weight: bold;
-}
-
-@media (min-width: 901px) {
- .menu-sticky-wrap {
- position: static;
- }
-}
-
-.tsd-panel {
- margin: 20px 0;
- padding: 20px;
- background-color: #fff;
- box-shadow: 0 0 4px rgba(0, 0, 0, 0.25);
-}
-.tsd-panel:empty {
- display: none;
-}
-.tsd-panel > h1, .tsd-panel > h2, .tsd-panel > h3 {
- margin: 1.5em -20px 10px -20px;
- padding: 0 20px 10px 20px;
- border-bottom: 1px solid #eee;
-}
-.tsd-panel > h1.tsd-before-signature, .tsd-panel > h2.tsd-before-signature, .tsd-panel > h3.tsd-before-signature {
- margin-bottom: 0;
- border-bottom: 0;
-}
-.tsd-panel table {
- display: block;
- width: 100%;
- overflow: auto;
- margin-top: 10px;
- word-break: normal;
- word-break: keep-all;
-}
-.tsd-panel table th {
- font-weight: bold;
-}
-.tsd-panel table th, .tsd-panel table td {
- padding: 6px 13px;
- border: 1px solid #ddd;
-}
-.tsd-panel table tr {
- background-color: #fff;
- border-top: 1px solid #ccc;
-}
-.tsd-panel table tr:nth-child(2n) {
- background-color: #f8f8f8;
-}
-
-.tsd-panel-group {
- margin: 60px 0;
-}
-.tsd-panel-group > h1, .tsd-panel-group > h2, .tsd-panel-group > h3 {
- padding-left: 20px;
- padding-right: 20px;
-}
-
-#tsd-search {
- transition: background-color 0.2s;
-}
-#tsd-search .title {
- position: relative;
- z-index: 2;
-}
-#tsd-search .field {
- position: absolute;
- left: 0;
- top: 0;
- right: 40px;
- height: 40px;
-}
-#tsd-search .field input {
- box-sizing: border-box;
- position: relative;
- top: -50px;
- z-index: 1;
- width: 100%;
- padding: 0 10px;
- opacity: 0;
- outline: 0;
- border: 0;
- background: transparent;
- color: #222;
-}
-#tsd-search .field label {
- position: absolute;
- overflow: hidden;
- right: -40px;
-}
-#tsd-search .field input,
-#tsd-search .title {
- transition: opacity 0.2s;
-}
-#tsd-search .results {
- position: absolute;
- visibility: hidden;
- top: 40px;
- width: 100%;
- margin: 0;
- padding: 0;
- list-style: none;
- box-shadow: 0 0 4px rgba(0, 0, 0, 0.25);
-}
-#tsd-search .results li {
- padding: 0 10px;
- background-color: #fdfdfd;
-}
-#tsd-search .results li:nth-child(even) {
- background-color: #fff;
-}
-#tsd-search .results li.state {
- display: none;
-}
-#tsd-search .results li.current,
-#tsd-search .results li:hover {
- background-color: #eee;
-}
-#tsd-search .results a {
- display: block;
-}
-#tsd-search .results a:before {
- top: 10px;
-}
-#tsd-search .results span.parent {
- color: #808080;
- font-weight: normal;
-}
-#tsd-search.has-focus {
- background-color: #eee;
-}
-#tsd-search.has-focus .field input {
- top: 0;
- opacity: 1;
-}
-#tsd-search.has-focus .title {
- z-index: 0;
- opacity: 0;
-}
-#tsd-search.has-focus .results {
- visibility: visible;
-}
-#tsd-search.loading .results li.state.loading {
- display: block;
-}
-#tsd-search.failure .results li.state.failure {
- display: block;
-}
-
-.tsd-signature {
- margin: 0 0 1em 0;
- padding: 10px;
- border: 1px solid #eee;
- font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
- font-size: 14px;
- overflow-x: auto;
-}
-.tsd-signature.tsd-kind-icon {
- padding-left: 30px;
-}
-.tsd-signature.tsd-kind-icon:before {
- top: 10px;
- left: 10px;
-}
-.tsd-panel > .tsd-signature {
- margin-left: -20px;
- margin-right: -20px;
- border-width: 1px 0;
-}
-.tsd-panel > .tsd-signature.tsd-kind-icon {
- padding-left: 40px;
-}
-.tsd-panel > .tsd-signature.tsd-kind-icon:before {
- left: 20px;
-}
-
-.tsd-signature-symbol {
- color: #808080;
- font-weight: normal;
-}
-
-.tsd-signature-type {
- font-style: italic;
- font-weight: normal;
-}
-
-.tsd-signatures {
- padding: 0;
- margin: 0 0 1em 0;
- border: 1px solid #eee;
-}
-.tsd-signatures .tsd-signature {
- margin: 0;
- border-width: 1px 0 0 0;
- transition: background-color 0.1s;
-}
-.tsd-signatures .tsd-signature:first-child {
- border-top-width: 0;
-}
-.tsd-signatures .tsd-signature.current {
- background-color: #eee;
-}
-.tsd-signatures.active > .tsd-signature {
- cursor: pointer;
-}
-.tsd-panel > .tsd-signatures {
- margin-left: -20px;
- margin-right: -20px;
- border-width: 1px 0;
-}
-.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon {
- padding-left: 40px;
-}
-.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before {
- left: 20px;
-}
-.tsd-panel > a.anchor + .tsd-signatures {
- border-top-width: 0;
- margin-top: -20px;
-}
-
-ul.tsd-descriptions {
- position: relative;
- overflow: hidden;
- padding: 0;
- list-style: none;
-}
-ul.tsd-descriptions.active > .tsd-description {
- display: none;
-}
-ul.tsd-descriptions.active > .tsd-description.current {
- display: block;
-}
-ul.tsd-descriptions.active > .tsd-description.fade-in {
- animation: fade-in-delayed 0.3s;
-}
-ul.tsd-descriptions.active > .tsd-description.fade-out {
- animation: fade-out-delayed 0.3s;
- position: absolute;
- display: block;
- top: 0;
- left: 0;
- right: 0;
- opacity: 0;
- visibility: hidden;
-}
-ul.tsd-descriptions h4, ul.tsd-descriptions .tsd-index-panel h3, .tsd-index-panel ul.tsd-descriptions h3 {
- font-size: 16px;
- margin: 1em 0 0.5em 0;
-}
-
-ul.tsd-parameters,
-ul.tsd-type-parameters {
- list-style: square;
- margin: 0;
- padding-left: 20px;
-}
-ul.tsd-parameters > li.tsd-parameter-signature,
-ul.tsd-type-parameters > li.tsd-parameter-signature {
- list-style: none;
- margin-left: -20px;
-}
-ul.tsd-parameters h5,
-ul.tsd-type-parameters h5 {
- font-size: 16px;
- margin: 1em 0 0.5em 0;
-}
-ul.tsd-parameters .tsd-comment,
-ul.tsd-type-parameters .tsd-comment {
- margin-top: -0.5em;
-}
-
-.tsd-sources {
- font-size: 14px;
- color: #808080;
- margin: 0 0 1em 0;
-}
-.tsd-sources a {
- color: #808080;
- text-decoration: underline;
-}
-.tsd-sources ul, .tsd-sources p {
- margin: 0 !important;
-}
-.tsd-sources ul {
- list-style: none;
- padding: 0;
-}
-
-.tsd-page-toolbar {
- position: fixed;
- z-index: 1;
- top: 0;
- left: 0;
- width: 100%;
- height: 40px;
- color: #333;
- background: #fff;
- border-bottom: 1px solid #eee;
- transition: transform 0.3s linear;
-}
-.tsd-page-toolbar a {
- color: #333;
- text-decoration: none;
-}
-.tsd-page-toolbar a.title {
- font-weight: bold;
-}
-.tsd-page-toolbar a.title:hover {
- text-decoration: underline;
-}
-.tsd-page-toolbar .table-wrap {
- display: table;
- width: 100%;
- height: 40px;
-}
-.tsd-page-toolbar .table-cell {
- display: table-cell;
- position: relative;
- white-space: nowrap;
- line-height: 40px;
-}
-.tsd-page-toolbar .table-cell:first-child {
- width: 100%;
-}
-
-.tsd-page-toolbar--hide {
- transform: translateY(-100%);
-}
-
-.tsd-select .tsd-select-list li:before, .tsd-select .tsd-select-label:before, .tsd-widget:before {
- content: "";
- display: inline-block;
- width: 40px;
- height: 40px;
- margin: 0 -8px 0 0;
- background-image: url(../images/widgets.png);
- background-repeat: no-repeat;
- text-indent: -1024px;
- vertical-align: bottom;
-}
-@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
- .tsd-select .tsd-select-list li:before, .tsd-select .tsd-select-label:before, .tsd-widget:before {
- background-image: url(../images/widgets@2x.png);
- background-size: 320px 40px;
- }
-}
-
-.tsd-widget {
- display: inline-block;
- overflow: hidden;
- opacity: 0.6;
- height: 40px;
- transition: opacity 0.1s, background-color 0.2s;
- vertical-align: bottom;
- cursor: pointer;
-}
-.tsd-widget:hover {
- opacity: 0.8;
-}
-.tsd-widget.active {
- opacity: 1;
- background-color: #eee;
-}
-.tsd-widget.no-caption {
- width: 40px;
-}
-.tsd-widget.no-caption:before {
- margin: 0;
-}
-.tsd-widget.search:before {
- background-position: 0 0;
-}
-.tsd-widget.menu:before {
- background-position: -40px 0;
-}
-.tsd-widget.options:before {
- background-position: -80px 0;
-}
-.tsd-widget.options, .tsd-widget.menu {
- display: none;
-}
-@media (max-width: 900px) {
- .tsd-widget.options, .tsd-widget.menu {
- display: inline-block;
- }
-}
-input[type=checkbox] + .tsd-widget:before {
- background-position: -120px 0;
-}
-input[type=checkbox]:checked + .tsd-widget:before {
- background-position: -160px 0;
-}
-
-.tsd-select {
- position: relative;
- display: inline-block;
- height: 40px;
- transition: opacity 0.1s, background-color 0.2s;
- vertical-align: bottom;
- cursor: pointer;
-}
-.tsd-select .tsd-select-label {
- opacity: 0.6;
- transition: opacity 0.2s;
-}
-.tsd-select .tsd-select-label:before {
- background-position: -240px 0;
-}
-.tsd-select.active .tsd-select-label {
- opacity: 0.8;
-}
-.tsd-select.active .tsd-select-list {
- visibility: visible;
- opacity: 1;
- transition-delay: 0s;
-}
-.tsd-select .tsd-select-list {
- position: absolute;
- visibility: hidden;
- top: 40px;
- left: 0;
- margin: 0;
- padding: 0;
- opacity: 0;
- list-style: none;
- box-shadow: 0 0 4px rgba(0, 0, 0, 0.25);
- transition: visibility 0s 0.2s, opacity 0.2s;
-}
-.tsd-select .tsd-select-list li {
- padding: 0 20px 0 0;
- background-color: #fdfdfd;
-}
-.tsd-select .tsd-select-list li:before {
- background-position: 40px 0;
-}
-.tsd-select .tsd-select-list li:nth-child(even) {
- background-color: #fff;
-}
-.tsd-select .tsd-select-list li:hover {
- background-color: #eee;
-}
-.tsd-select .tsd-select-list li.selected:before {
- background-position: -200px 0;
-}
-@media (max-width: 900px) {
- .tsd-select .tsd-select-list {
- top: 0;
- left: auto;
- right: 100%;
- margin-right: -5px;
- }
- .tsd-select .tsd-select-label:before {
- background-position: -280px 0;
- }
-}
-
-img {
- max-width: 100%;
-}
\ No newline at end of file
diff --git a/docs/assets/images/icons.png b/docs/assets/images/icons.png
deleted file mode 100644
index 3836d5fe4..000000000
Binary files a/docs/assets/images/icons.png and /dev/null differ
diff --git a/docs/assets/images/icons@2x.png b/docs/assets/images/icons@2x.png
deleted file mode 100644
index 5a209e2f6..000000000
Binary files a/docs/assets/images/icons@2x.png and /dev/null differ
diff --git a/docs/assets/images/widgets.png b/docs/assets/images/widgets.png
deleted file mode 100644
index c7380532a..000000000
Binary files a/docs/assets/images/widgets.png and /dev/null differ
diff --git a/docs/assets/images/widgets@2x.png b/docs/assets/images/widgets@2x.png
deleted file mode 100644
index 4bbbd5727..000000000
Binary files a/docs/assets/images/widgets@2x.png and /dev/null differ
diff --git a/docs/assets/js/main.js b/docs/assets/js/main.js
deleted file mode 100644
index 39a806694..000000000
--- a/docs/assets/js/main.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(){var e=function(t){var r=new e.Builder;return r.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),r.searchPipeline.add(e.stemmer),t.call(r,r),r.build()};e.version="2.3.7",e.utils={},e.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),e.utils.asString=function(e){return null==e?"":e.toString()},e.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),r=Object.keys(e),i=0;i=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){for(var t,r;47<(r=(t=this.next()).charCodeAt(0))&&r<58;);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos=this.scrollTop||0===this.scrollTop,isShown!==this.showToolbar&&(this.toolbar.classList.toggle("tsd-page-toolbar--hide"),this.secondaryNav.classList.toggle("tsd-navigation--toolbar-hide")),this.lastY=this.scrollTop},Viewport}(typedoc.EventTarget);typedoc.Viewport=Viewport,typedoc.registerService(Viewport,"viewport")}(typedoc||(typedoc={})),function(typedoc){function Component(options){this.el=options.el}typedoc.Component=Component}(typedoc||(typedoc={})),function(typedoc){typedoc.pointerDown="mousedown",typedoc.pointerMove="mousemove",typedoc.pointerUp="mouseup",typedoc.pointerDownPosition={x:0,y:0},typedoc.preventNextClick=!1,typedoc.isPointerDown=!1,typedoc.isPointerTouch=!1,typedoc.hasPointerMoved=!1,typedoc.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),document.documentElement.classList.add(typedoc.isMobile?"is-mobile":"not-mobile"),typedoc.isMobile&&"ontouchstart"in document.documentElement&&(typedoc.isPointerTouch=!0,typedoc.pointerDown="touchstart",typedoc.pointerMove="touchmove",typedoc.pointerUp="touchend"),document.addEventListener(typedoc.pointerDown,function(e){typedoc.isPointerDown=!0,typedoc.hasPointerMoved=!1;var t="touchstart"==typedoc.pointerDown?e.targetTouches[0]:e;typedoc.pointerDownPosition.y=t.pageY||0,typedoc.pointerDownPosition.x=t.pageX||0}),document.addEventListener(typedoc.pointerMove,function(e){if(typedoc.isPointerDown&&!typedoc.hasPointerMoved){var t="touchstart"==typedoc.pointerDown?e.targetTouches[0]:e,x=typedoc.pointerDownPosition.x-(t.pageX||0),y=typedoc.pointerDownPosition.y-(t.pageY||0);typedoc.hasPointerMoved=10scrollTop;)index-=1;for(;index"+match+""}),parent=row.parent||"";(parent=parent.replace(new RegExp(this.query,"i"),function(match){return""+match+" "}))&&(name=''+parent+". "+name);var item=document.createElement("li");item.classList.value=row.classes,item.innerHTML='\n '+name+" \n ",this.results.appendChild(item)}}},Search.prototype.setLoadingState=function(value){this.loadingState!=value&&(this.el.classList.remove(SearchLoadingState[this.loadingState].toLowerCase()),this.loadingState=value,this.el.classList.add(SearchLoadingState[this.loadingState].toLowerCase()),this.updateResults())},Search.prototype.setHasFocus=function(value){this.hasFocus!=value&&(this.hasFocus=value,this.el.classList.toggle("has-focus"),value?(this.setQuery(""),this.field.value=""):this.field.value=this.query)},Search.prototype.setQuery=function(value){this.query=value.trim(),this.updateResults()},Search.prototype.setCurrentResult=function(dir){var current=this.results.querySelector(".current");if(current){var rel=1==dir?current.nextElementSibling:current.previousElementSibling;rel&&(current.classList.remove("current"),rel.classList.add("current"))}else(current=this.results.querySelector(1==dir?"li:first-child":"li:last-child"))&¤t.classList.add("current")},Search.prototype.gotoCurrentResult=function(){var current=this.results.querySelector(".current");if(current||(current=this.results.querySelector("li:first-child")),current){var link=current.querySelector("a");link&&(window.location.href=link.href),this.field.blur()}},Search.prototype.bindEvents=function(){var _this=this;this.results.addEventListener("mousedown",function(){_this.resultClicked=!0}),this.results.addEventListener("mouseup",function(){_this.resultClicked=!1,_this.setHasFocus(!1)}),this.field.addEventListener("focusin",function(){_this.setHasFocus(!0),_this.loadIndex()}),this.field.addEventListener("focusout",function(){_this.resultClicked?_this.resultClicked=!1:setTimeout(function(){return _this.setHasFocus(!1)},100)}),this.field.addEventListener("input",function(){_this.setQuery(_this.field.value)}),this.field.addEventListener("keydown",function(e){13==e.keyCode||27==e.keyCode||38==e.keyCode||40==e.keyCode?(_this.preventPress=!0,e.preventDefault(),13==e.keyCode?_this.gotoCurrentResult():27==e.keyCode?_this.field.blur():38==e.keyCode?_this.setCurrentResult(-1):40==e.keyCode&&_this.setCurrentResult(1)):_this.preventPress=!1}),this.field.addEventListener("keypress",function(e){_this.preventPress&&e.preventDefault()}),document.body.addEventListener("keydown",function(e){e.altKey||e.ctrlKey||e.metaKey||!_this.hasFocus&&47this.groups.length-1&&(index=this.groups.length-1),this.index!=index){var to=this.groups[index];if(-1
-
-
-
-
- Chart | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
-
-
- Constructors
-
-
- constructor
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Methods
-
-
- componentDidMount
-
- componentDidMount( ) : void
-
-
-
-
-
- componentDidUpdate
-
- componentDidUpdate( ) : void
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
- Class
- Constructor
- Method
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/classes/_app_components_errorhandler_.errorhandler.html b/docs/classes/_app_components_errorhandler_.errorhandler.html
deleted file mode 100644
index cfbb81fd7..000000000
--- a/docs/classes/_app_components_errorhandler_.errorhandler.html
+++ /dev/null
@@ -1,241 +0,0 @@
-
-
-
-
-
- ErrorHandler | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Methods
-
-
- componentDidCatch
-
- componentDidCatch( error: string , info: string ) : void
-
-
-
-
- Parameters
-
-
- error: string
-
-
- info: string
-
-
- Returns void
-
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
- Class
- Constructor
- Method
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/classes/_backend_tree_.tree.html b/docs/classes/_backend_tree_.tree.html
deleted file mode 100644
index 94fbaf980..000000000
--- a/docs/classes/_backend_tree_.tree.html
+++ /dev/null
@@ -1,407 +0,0 @@
-
-
-
-
-
- Tree | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Constructors
-
-
- constructor
-
- new Tree( state: string | {} , name?: string , componentData?: {} ) : Tree
-
-
-
-
- Parameters
-
-
- state: string | {}
-
-
- Default value name: string = "nameless"
-
-
- Default value componentData: {} = {}
-
-
-
-
-
-
-
-
-
- Properties
-
-
- children
- children
: ( string | Tree ) []
-
-
-
-
- componentData
- componentData: {}
-
-
-
-
-
- name
- name: string
-
-
-
-
-
- state
- state: string | {}
-
-
-
-
-
- Methods
-
-
- addChild
-
- addChild( state: string | {} , name: string , componentData: {} ) : Tree
-
-
-
-
- Parameters
-
-
- state: string | {}
-
-
- name: string
-
-
- componentData: {}
-
-
-
-
-
-
-
-
-
- addSibling
-
- addSibling( state: string | {} , name: string , componentData: {} ) : Tree
-
-
-
-
- Parameters
-
-
- state: string | {}
-
-
- name: string
-
-
- componentData: {}
-
-
-
-
-
-
-
-
-
- cleanTreeCopy
-
- cleanTreeCopy( ) : Tree
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
- Class
- Constructor
- Property
- Method
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/globals.html b/docs/globals.html
deleted file mode 100644
index 7f6119d75..000000000
--- a/docs/globals.html
+++ /dev/null
@@ -1,243 +0,0 @@
-
-
-
-
-
- Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
deleted file mode 100644
index 1d0d8efc0..000000000
--- a/docs/index.html
+++ /dev/null
@@ -1,297 +0,0 @@
-
-
-
-
-
- Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
State Debugger for React
-
-
-
Reactime is a debugging tool for React developers. It records state whenever it is changed and allows the user to jump to any previously recorded state.
-
This tool is for React apps using stateful components and prop drilling, and has beta support for Context API, conditional state routing, Hooks (useState, useEffect) and functional components.
-
The latest release extends the core functionality by including support for TypeScript applications, improving the user experience through more declarative titles in the actions panel, and extending support for components with conditional state fields. The testing suite has also been expanded with the inclusion of a Sandbox utility to aid future expansion as well as additional E2E and integration tests with Puppeteer and React Testing Library.
-
After installing the Reactime, you can test its functionalities in the following demo repositories:
-
-
Reactime was nominated for the Productivity Booster award at React Open Source Awards 2020 !
-
- Installation
-
-
Just one step needed Chrome extension and an NPM package .
-
- Install the Reactime extension from Chrome Web Store. Alternatively, use src/extension/build/build.zip
for manual installation in Developer mode . Turn on 'Allow access to file URLs' in extension details page if testing locally.
-
-
* for old version instaling click here *
-
- How to Use
-
-
After installing both the Chrome extension and the NPM package, just open up your project in the browser.
-
Then open up your Chrome DevTools and navigate to the Reactime tab.
-
- Features
-
-
- Recording
-
-
Whenever state is changed (whenever setState or useState is called), this extension will create a snapshot of the current state tree and record it. Each snapshot will be displayed in Chrome DevTools under the Reactime panel.
-
- Viewing
-
-
You can click on a snapshot to view your app's state. State can be visualized in a JSON or a tree. Also, snapshots can be diffed with the previous snapshot, which can be viewed under the Diff tab.
-
- Jumping
-
-
Jumping is the most important feature of all. It allows you to jump to any previous recorded snapshots. Hitting the jump button on any snapshot will change the DOM by setting their state.
-
- TypeScript Support
-
-
Reactime offers beta support for TypeScript applications using stateful class components and functional components with useState hooks. Further testing and development is required for custom hooks, Context API, and Concurrent Mode.
-
- Additional Features
-
-
- multiple tree graph branches depicting state changes
- tree graph hover functionality to view state changes
- ability to pan and zoom tree graph
- multiple tabs support
- a slider to move through snapshots quickly
- a play button to move through snapshots automatically
- a pause button, which stops recording each snapshot
- a lock button to freeze the DOM in place. setState will lose all functionality while the extension is locked
- a persist button to keep snapshots upon refresh (handy when changing code and debugging)
- export/import the current snapshots in memory
- declarative titles in the actions panel
- extended support for components with conditional state fields
- a Sandbox utility to aid future expansion
-
-
- Authors
-
-
-
- License
-
-
This project is licensed under the MIT License - see the LICENSE file for details
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_action_.actionprops.html b/docs/interfaces/_app_components_action_.actionprops.html
deleted file mode 100644
index e88317de5..000000000
--- a/docs/interfaces/_app_components_action_.actionprops.html
+++ /dev/null
@@ -1,374 +0,0 @@
-
-
-
-
-
- ActionProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface ActionProps
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
- componentData
- componentData: { actualDuration: number } | undefined
-
-
-
-
- componentName
- componentName: string
-
-
-
-
- dispatch
- dispatch: ( a: any ) => void
-
-
-
Type declaration
-
-
-
-
-
- Parameters
-
- Returns void
-
-
-
-
-
-
-
-
- displayName
- displayName: string
-
-
-
-
- handleOnkeyDown
- handleOnkeyDown: ( e: any , i: number ) => void
-
-
-
Type declaration
-
-
-
- ( e: any , i: number ) : void
-
-
-
- Parameters
-
-
- e: any
-
-
- i: number
-
-
- Returns void
-
-
-
-
-
-
-
-
- index
- index: number
-
-
-
-
- key
- key: string
-
-
-
-
- last
- last: boolean
-
-
-
-
- selected
- selected: boolean
-
-
-
-
- sliderIndex
- sliderIndex: number
-
-
-
-
- Optional state
- state: Record < string , unknown >
-
-
-
-
- viewIndex
- viewIndex: number
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_chart_.chartprops.html b/docs/interfaces/_app_components_chart_.chartprops.html
deleted file mode 100644
index 4162bac2b..000000000
--- a/docs/interfaces/_app_components_chart_.chartprops.html
+++ /dev/null
@@ -1,172 +0,0 @@
-
-
-
-
-
- ChartProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface ChartProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- hierarchy
- hierarchy: Record < string , unknown >
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_diff_.diffprops.html b/docs/interfaces/_app_components_diff_.diffprops.html
deleted file mode 100644
index ef300b721..000000000
--- a/docs/interfaces/_app_components_diff_.diffprops.html
+++ /dev/null
@@ -1,188 +0,0 @@
-
-
-
-
-
- DiffProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface DiffProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- Optional show
- show: boolean | undefined
-
-
-
-
- snapshot
- snapshot: { state?: Record < string , unknown > }
-
-
-
Type declaration
-
-
- Optional state?: Record < string , unknown >
-
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_diffroute_.diffrouteprops.html b/docs/interfaces/_app_components_diffroute_.diffrouteprops.html
deleted file mode 100644
index e369e7dfe..000000000
--- a/docs/interfaces/_app_components_diffroute_.diffrouteprops.html
+++ /dev/null
@@ -1,166 +0,0 @@
-
-
-
-
-
- DiffRouteProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface DiffRouteProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- snapshot
- snapshot: Record < string , { children?: unknown [] ; componentData?: Record < string , unknown > ; name?: string ; state?: string | unknown ; stateSnaphot?: Record < string , unknown > } >
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_dropdown_.dropdownprops.html b/docs/interfaces/_app_components_dropdown_.dropdownprops.html
deleted file mode 100644
index cd42fb898..000000000
--- a/docs/interfaces/_app_components_dropdown_.dropdownprops.html
+++ /dev/null
@@ -1,220 +0,0 @@
-
-
-
-
-
- DropdownProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface DropdownProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- selectedSpeed
- selectedSpeed: { label: string ; value: number }
-
-
-
Type declaration
-
-
- label: string
-
-
- value: number
-
-
-
-
-
-
- setSpeed
- setSpeed: ( ) => void
-
-
-
-
-
- speeds
- speeds: { label: string ; value: number } []
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_mainslider_.handleprops.html b/docs/interfaces/_app_components_mainslider_.handleprops.html
deleted file mode 100644
index 1ddb2a7d5..000000000
--- a/docs/interfaces/_app_components_mainslider_.handleprops.html
+++ /dev/null
@@ -1,203 +0,0 @@
-
-
-
-
-
- handleProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface handleProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- dragging
- dragging: boolean
-
-
-
-
- index
- index: number
-
-
-
-
- value
- value: number
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_mainslider_.mainsliderprops.html b/docs/interfaces/_app_components_mainslider_.mainsliderprops.html
deleted file mode 100644
index 10d5a1262..000000000
--- a/docs/interfaces/_app_components_mainslider_.mainsliderprops.html
+++ /dev/null
@@ -1,175 +0,0 @@
-
-
-
-
-
- MainSliderProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface MainSliderProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- snapshotsLength
- snapshotsLength: number
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_perfview_.perfviewprops.html b/docs/interfaces/_app_components_perfview_.perfviewprops.html
deleted file mode 100644
index 6ac11d7a9..000000000
--- a/docs/interfaces/_app_components_perfview_.perfviewprops.html
+++ /dev/null
@@ -1,208 +0,0 @@
-
-
-
-
-
- PerfViewProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface PerfViewProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- height
- height: number
-
-
-
-
- snapshots
- snapshots: any []
-
-
-
-
- viewIndex
- viewIndex: number
-
-
-
-
- width
- width: number
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_stateroute_.staterouteprops.html b/docs/interfaces/_app_components_stateroute_.staterouteprops.html
deleted file mode 100644
index 0198b140a..000000000
--- a/docs/interfaces/_app_components_stateroute_.staterouteprops.html
+++ /dev/null
@@ -1,237 +0,0 @@
-
-
-
-
-
- StateRouteProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface StateRouteProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- hierarchy
- hierarchy: object
-
-
-
-
- snapshot
- snapshot: { children?: any [] ; componentData?: object ; name?: string ; state?: string | object ; stateSnaphot?: object }
-
-
-
Type declaration
-
-
- Optional children?: any []
-
-
- Optional componentData?: object
-
-
- Optional name?: string
-
-
- Optional state?: string | object
-
-
- Optional stateSnaphot?: object
-
-
-
-
-
-
- snapshots
- snapshots: [ ]
-
-
-
-
- viewIndex
- viewIndex: number
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_components_tree_.treeprops.html b/docs/interfaces/_app_components_tree_.treeprops.html
deleted file mode 100644
index 64c09ec20..000000000
--- a/docs/interfaces/_app_components_tree_.treeprops.html
+++ /dev/null
@@ -1,189 +0,0 @@
-
-
-
-
-
- TreeProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface TreeProps
-
-
-
-
-
-
-
-
-
- Properties
-
-
- snapshot
- snapshot: { children?: any [] ; componentData?: object ; name?: string ; state?: string | object ; stateSnaphot?: object }
-
-
-
Type declaration
-
-
- Optional children?: any []
-
-
- Optional componentData?: object
-
-
- Optional name?: string
-
-
- Optional state?: string | object
-
-
- Optional stateSnaphot?: object
-
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_containers_statecontainer_.statecontainerprops.html b/docs/interfaces/_app_containers_statecontainer_.statecontainerprops.html
deleted file mode 100644
index 6fbc62494..000000000
--- a/docs/interfaces/_app_containers_statecontainer_.statecontainerprops.html
+++ /dev/null
@@ -1,208 +0,0 @@
-
-
-
-
-
- StateContainerProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface StateContainerProps
-
-
-
-
-
-
-
- Hierarchy
-
-
- StateContainerProps
-
-
-
-
-
- Properties
-
-
- hierarchy
- hierarchy: Record < string , unknown >
-
-
-
-
- snapshot
- snapshot: Record < number , { children?: unknown [] ; componentData?: Record < string , unknown > ; name?: string ; state?: Record < string , unknown > ; stateSnaphot?: Record < string , unknown > } >
-
-
-
-
- snapshots
- snapshots: [ ]
-
-
-
-
- viewIndex
- viewIndex: number
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_app_containers_travelcontainer_.travelcontainerprops.html b/docs/interfaces/_app_containers_travelcontainer_.travelcontainerprops.html
deleted file mode 100644
index 5eb2b08d7..000000000
--- a/docs/interfaces/_app_containers_travelcontainer_.travelcontainerprops.html
+++ /dev/null
@@ -1,172 +0,0 @@
-
-
-
-
-
- TravelContainerProps | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Interface TravelContainerProps
-
-
-
-
-
-
-
- Hierarchy
-
-
- TravelContainerProps
-
-
-
-
-
- Properties
-
-
- snapshotsLength
- snapshotsLength: number
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/interfaces/_backend_linkfiber_.__global.window.html b/docs/interfaces/_backend_linkfiber_.__global.window.html
deleted file mode 100644
index 53264847e..000000000
--- a/docs/interfaces/_backend_linkfiber_.__global.window.html
+++ /dev/null
@@ -1,171 +0,0 @@
-
-
-
-
-
- Window | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
- Optional __REACT_DEVTOOLS_GLOBAL_HOOK__
- __REACT_DEVTOOLS_GLOBAL_HOOK__: any
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_actions_actions_.html b/docs/modules/_app_actions_actions_.html
deleted file mode 100644
index f6af1471e..000000000
--- a/docs/modules/_app_actions_actions_.html
+++ /dev/null
@@ -1,643 +0,0 @@
-
-
-
-
-
- "app/actions/actions" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/actions/actions"
-
-
-
-
-
-
-
-
- Functions
-
-
- Const addNewSnapshots
-
- addNewSnapshots( tabsObj: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const changeSlider
-
- changeSlider( index: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const changeView
-
- changeView( index: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const deleteTab
-
- deleteTab( tab: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const emptySnapshots
-
- emptySnapshots( ) : { type: string }
-
-
-
-
- Returns { type: string }
-
-
-
-
-
-
- Const importSnapshots
-
- importSnapshots( newSnaps: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const initialConnect
-
- initialConnect( tabsObj: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const moveBackward
-
- moveBackward( ) : { payload: boolean ; type: string }
-
-
-
-
- Returns { payload: boolean ; type: string }
-
-
- payload: boolean
-
-
- type: string
-
-
-
-
-
-
-
- Const moveForward
-
- moveForward( ) : { payload: boolean ; type: string }
-
-
-
-
- Returns { payload: boolean ; type: string }
-
-
- payload: boolean
-
-
- type: string
-
-
-
-
-
-
-
- Const pause
-
- pause( ) : { type: string }
-
-
-
-
- Returns { type: string }
-
-
-
-
-
-
- Const playForward
-
- playForward( ) : { payload: boolean ; type: string }
-
-
-
-
- Returns { payload: boolean ; type: string }
-
-
- payload: boolean
-
-
- type: string
-
-
-
-
-
-
-
- Const resetSlider
-
- resetSlider( ) : { type: string }
-
-
-
-
- Returns { type: string }
-
-
-
-
-
-
- Const setPort
-
- setPort( port: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const setTab
-
- setTab( tab: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const startPlaying
-
- startPlaying( intervalId: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
- Const toggleMode
-
- toggleMode( mode: any ) : { payload: any ; type: string }
-
-
-
-
- Parameters
-
- Returns { payload: any ; type: string }
-
-
- payload: any
-
-
- type: string
-
-
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_action_.html b/docs/modules/_app_components_action_.html
deleted file mode 100644
index e96a7d279..000000000
--- a/docs/modules/_app_components_action_.html
+++ /dev/null
@@ -1,177 +0,0 @@
-
-
-
-
-
- "app/components/Action" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/Action"
-
-
-
-
-
-
-
-
- Functions
-
-
- Const Action
-
-
-
-
-
- Parameters
-
- Returns unknown
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_app_.html b/docs/modules/_app_components_app_.html
deleted file mode 100644
index cd48dce68..000000000
--- a/docs/modules/_app_components_app_.html
+++ /dev/null
@@ -1,206 +0,0 @@
-
-
-
-
-
- "app/components/App" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/App"
-
-
-
-
-
-
-
-
- Functions
-
-
- App
-
-
-
-
- Returns unknown
-
-
-
-
-
- Object literals
-
-
- Const initialState
- initialState: object
-
-
-
- currentTab
- currentTab: null = null
-
-
-
-
- port
- port: null = null
-
-
-
-
- tabs
- tabs: {}
-
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_chart_.html b/docs/modules/_app_components_chart_.html
deleted file mode 100644
index 7c684461e..000000000
--- a/docs/modules/_app_components_chart_.html
+++ /dev/null
@@ -1,186 +0,0 @@
-
-
-
-
-
- "app/components/Chart" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/Chart"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const colors
- colors: string [] = ['#95B6B7', '#475485', '#519331', '#AA5039', '#8B2F5F', '#C5B738', '#858DFF', '#FF8D02', '#FFCD51', '#ACDAE6', '#FC997E', '#CF93AD', '#AA3939', '#AA6C39', '#226666', '#2C4870']
-
-
-
-
-
- Let root
- root: {}
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_diff_.html b/docs/modules/_app_components_diff_.html
deleted file mode 100644
index b9f67d085..000000000
--- a/docs/modules/_app_components_diff_.html
+++ /dev/null
@@ -1,174 +0,0 @@
-
-
-
-
-
- "app/components/Diff" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/Diff"
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_diffroute_.html b/docs/modules/_app_components_diffroute_.html
deleted file mode 100644
index 43233f4ff..000000000
--- a/docs/modules/_app_components_diffroute_.html
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
-
- "app/components/DiffRoute" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/DiffRoute"
-
-
-
-
-
-
-
-
- Functions
-
-
- Const DiffRoute
-
-
-
-
- Parameters
-
- Returns unknown
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_dropdown_.html b/docs/modules/_app_components_dropdown_.html
deleted file mode 100644
index b337d8b4c..000000000
--- a/docs/modules/_app_components_dropdown_.html
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
-
- "app/components/Dropdown" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/Dropdown"
-
-
-
-
-
-
-
-
- Functions
-
-
- Const Dropdown
-
-
-
-
- Parameters
-
- Returns unknown
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_errorhandler_.html b/docs/modules/_app_components_errorhandler_.html
deleted file mode 100644
index c63bce694..000000000
--- a/docs/modules/_app_components_errorhandler_.html
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
- "app/components/ErrorHandler" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/ErrorHandler"
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_mainslider_.html b/docs/modules/_app_components_mainslider_.html
deleted file mode 100644
index 2bf545ae6..000000000
--- a/docs/modules/_app_components_mainslider_.html
+++ /dev/null
@@ -1,217 +0,0 @@
-
-
-
-
-
- "app/components/MainSlider" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/MainSlider"
-
-
-
-
-
-
-
-
- Variables
-
-
- Handle
- Handle: any
-
-
-
-
- Functions
-
-
- MainSlider
-
-
-
-
- Parameters
-
- Returns any
-
-
-
-
-
- Const handle
-
-
-
-
- Parameters
-
- Returns any
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_perfview_.html b/docs/modules/_app_components_perfview_.html
deleted file mode 100644
index 65f459bdc..000000000
--- a/docs/modules/_app_components_perfview_.html
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
-
- "app/components/PerfView" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/PerfView"
-
-
-
-
-
-
-
-
- Functions
-
-
- Const PerfView
-
-
-
-
- Parameters
-
- Returns any
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_stateroute_.html b/docs/modules/_app_components_stateroute_.html
deleted file mode 100644
index 220ddb487..000000000
--- a/docs/modules/_app_components_stateroute_.html
+++ /dev/null
@@ -1,214 +0,0 @@
-
-
-
-
-
- "app/components/StateRoute" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/StateRoute"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const Chart
- Chart: any = require('./Chart').default
-
-
-
-
- Const ErrorHandler
- ErrorHandler: any = require('./ErrorHandler').default
-
-
-
-
- Const NO_STATE_MSG
- NO_STATE_MSG: "No state change detected. Trigger an event to change state" = "No state change detected. Trigger an event to change state"
-
-
-
-
- Functions
-
-
- Const StateRoute
-
-
-
-
- Parameters
-
- Returns any
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_switchapp_.html b/docs/modules/_app_components_switchapp_.html
deleted file mode 100644
index e1651e052..000000000
--- a/docs/modules/_app_components_switchapp_.html
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
-
-
- "app/components/SwitchApp" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/SwitchApp"
-
-
-
-
-
-
-
-
- Functions
-
-
- Const SwitchAppDropdown
-
- SwitchAppDropdown( ) : any
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_components_tree_.html b/docs/modules/_app_components_tree_.html
deleted file mode 100644
index 3ea0eef9b..000000000
--- a/docs/modules/_app_components_tree_.html
+++ /dev/null
@@ -1,205 +0,0 @@
-
-
-
-
-
- "app/components/Tree" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/components/Tree"
-
-
-
-
-
-
-
-
- Functions
-
-
- Const Tree
-
-
-
-
- Parameters
-
- Returns any
-
-
-
-
-
- Const getItemString
-
- getItemString( type: any , data: { children: [ ] ; name: string ; state?: object | string } ) : any
-
-
-
-
- Parameters
-
-
- type: any
-
-
- data: { children: [ ] ; name: string ; state?: object | string }
-
-
- children: [ ]
-
-
- name: string
-
-
- Optional state?: object | string
-
-
-
-
- Returns any
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_constants_actiontypes_.html b/docs/modules/_app_constants_actiontypes_.html
deleted file mode 100644
index 684535170..000000000
--- a/docs/modules/_app_constants_actiontypes_.html
+++ /dev/null
@@ -1,338 +0,0 @@
-
-
-
-
-
- "app/constants/actionTypes" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/constants/actionTypes"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const CHANGE_SLIDER
- CHANGE_SLIDER: "CHANGE_SLIDER" = "CHANGE_SLIDER"
-
-
-
-
- Const CHANGE_VIEW
- CHANGE_VIEW: "CHANGE_VIEW" = "CHANGE_VIEW"
-
-
-
-
- Const DELETE_TAB
- DELETE_TAB: "DELETE_TAB" = "DELETE_TAB"
-
-
-
-
- Const EMPTY
- EMPTY: "EMPTY" = "EMPTY"
-
-
-
-
- Const IMPORT
- IMPORT: "IMPORT" = "IMPORT"
-
-
-
-
- Const INITIAL_CONNECT
- INITIAL_CONNECT: "INITIAL_CONNECT" = "INITIAL_CONNECT"
-
-
-
-
- Const MOVE_BACKWARD
- MOVE_BACKWARD: "MOVE_BACKWARD" = "MOVE_BACKWARD"
-
-
-
-
- Const MOVE_FORWARD
- MOVE_FORWARD: "MOVEFORWARD" = "MOVEFORWARD"
-
-
-
-
- Const NEW_SNAPSHOTS
- NEW_SNAPSHOTS: "NEW_SNAPSHOTS" = "NEW_SNAPSHOTS"
-
-
-
-
- Const PAUSE
- PAUSE: "PAUSE" = "PAUSE"
-
-
-
-
- Const PLAY
- PLAY: "PLAY" = "PLAY"
-
-
-
-
- Const SET_PORT
- SET_PORT: "SET_PORT" = "SET_PORT"
-
-
-
-
- Const SET_TAB
- SET_TAB: "SET_TAB" = "SET_TAB"
-
-
-
-
- Const SLIDER_ZERO
- SLIDER_ZERO: "SLIDER_ZERO" = "SLIDER_ZERO"
-
-
-
-
- Const TOGGLE_MODE
- TOGGLE_MODE: "TOGGLE_MODE" = "TOGGLE_MODE"
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_containers_actioncontainer_.html b/docs/modules/_app_containers_actioncontainer_.html
deleted file mode 100644
index 8020efa64..000000000
--- a/docs/modules/_app_containers_actioncontainer_.html
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
- "app/containers/ActionContainer" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/containers/ActionContainer"
-
-
-
-
-
-
-
-
- Functions
-
-
- ActionContainer
-
- ActionContainer( ) : any
-
-
-
-
-
- Const resetSlider
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_containers_buttonscontainer_.html b/docs/modules/_app_containers_buttonscontainer_.html
deleted file mode 100644
index 1c3b382cc..000000000
--- a/docs/modules/_app_containers_buttonscontainer_.html
+++ /dev/null
@@ -1,221 +0,0 @@
-
-
-
-
-
- "app/containers/ButtonsContainer" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/containers/ButtonsContainer"
-
-
-
-
-
-
-
-
- Functions
-
-
- ButtonsContainer
-
- ButtonsContainer( ) : any
-
-
-
-
-
- exportHandler
-
- exportHandler( snapshots: [ ] ) : void
-
-
-
-
- Parameters
-
- Returns void
-
-
-
-
-
- importHandler
-
- importHandler( dispatch: ( a: any ) => void ) : void
-
-
-
-
- Parameters
-
-
- dispatch: ( a: any ) => void
-
-
-
-
-
- Parameters
-
- Returns void
-
-
-
-
-
-
- Returns void
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_containers_headcontainer_.html b/docs/modules/_app_containers_headcontainer_.html
deleted file mode 100644
index 473a25435..000000000
--- a/docs/modules/_app_containers_headcontainer_.html
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
-
-
- "app/containers/HeadContainer" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/containers/HeadContainer"
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_containers_maincontainer_.html b/docs/modules/_app_containers_maincontainer_.html
deleted file mode 100644
index f73649f45..000000000
--- a/docs/modules/_app_containers_maincontainer_.html
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
-
-
- "app/containers/MainContainer" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/containers/MainContainer"
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_containers_statecontainer_.html b/docs/modules/_app_containers_statecontainer_.html
deleted file mode 100644
index ae133dd5c..000000000
--- a/docs/modules/_app_containers_statecontainer_.html
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
-
- "app/containers/StateContainer" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/containers/StateContainer"
-
-
-
-
-
-
-
-
- Functions
-
-
- Const StateContainer
-
-
-
-
- Parameters
-
- Returns unknown
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_containers_travelcontainer_.html b/docs/modules/_app_containers_travelcontainer_.html
deleted file mode 100644
index 256ca3a6e..000000000
--- a/docs/modules/_app_containers_travelcontainer_.html
+++ /dev/null
@@ -1,243 +0,0 @@
-
-
-
-
-
- "app/containers/TravelContainer" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/containers/TravelContainer"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const speeds
- speeds: { label: string ; value: number } [] = [{ value: 2000, label: '0.5x' },{ value: 1000, label: '1.0x' },{ value: 500, label: '2.0x' },]
-
-
-
-
- Functions
-
-
- TravelContainer
-
-
-
-
- Parameters
-
- Returns any
-
-
-
-
-
- play
-
- play( speed: number , playing: boolean , dispatch: ( a: any ) => void , snapshotsLength: number , sliderIndex: number ) : void
-
-
-
-
- Parameters
-
-
- speed: number
-
-
- playing: boolean
-
-
- dispatch: ( a: any ) => void
-
-
-
-
-
- Parameters
-
- Returns void
-
-
-
-
-
-
- snapshotsLength: number
-
-
- sliderIndex: number
-
-
- Returns void
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_index_.html b/docs/modules/_app_index_.html
deleted file mode 100644
index e15ed2a53..000000000
--- a/docs/modules/_app_index_.html
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
- "app/index" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_reducers_mainreducer_.html b/docs/modules/_app_reducers_mainreducer_.html
deleted file mode 100644
index b4a60b706..000000000
--- a/docs/modules/_app_reducers_mainreducer_.html
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
- "app/reducers/mainReducer" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "app/reducers/mainReducer"
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_app_store_.html b/docs/modules/_app_store_.html
deleted file mode 100644
index 9e0797ec2..000000000
--- a/docs/modules/_app_store_.html
+++ /dev/null
@@ -1,171 +0,0 @@
-
-
-
-
-
- "app/store" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
-
- Variables
-
-
- Const StoreContext
- StoreContext: any = React.createContext()
-
-
-
-
- Functions
-
-
- Const useStoreContext
-
- useStoreContext( ) : any
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_astparser_.html b/docs/modules/_backend_astparser_.html
deleted file mode 100644
index 10ce4db65..000000000
--- a/docs/modules/_backend_astparser_.html
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
- "backend/astParser" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "backend/astParser"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const JSXParser
- JSXParser: any = acorn.Parser.extend(jsx())
-
-
-
-
- Const acorn
- acorn: any = require('acorn')
-
-
-
-
- Const jsx
- jsx: any = require('acorn-jsx')
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_helpers_.html b/docs/modules/_backend_helpers_.html
deleted file mode 100644
index 24deea0e5..000000000
--- a/docs/modules/_backend_helpers_.html
+++ /dev/null
@@ -1,235 +0,0 @@
-
-
-
-
-
- "backend/helpers" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "backend/helpers"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const JSXParser
- JSXParser: any = acorn.Parser.extend(jsx())
-
-
-
-
- Const acorn
- acorn: any = require('acorn')
-
-
-
-
- Const jsx
- jsx: any = require('acorn-jsx')
-
-
-
-
- Functions
-
-
- Const getHooksNames
-
- getHooksNames( elementType: any ) : any []
-
-
-
-
- Parameters
-
- Returns any []
-
-
-
-
-
- Const throttle
-
- throttle( f: any , t: any ) : throttledFunc
-
-
-
-
- Parameters
-
-
- f: any
-
-
- t: any
-
-
- Returns throttledFunc
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_index_.html b/docs/modules/_backend_index_.html
deleted file mode 100644
index 4f3f1ec33..000000000
--- a/docs/modules/_backend_index_.html
+++ /dev/null
@@ -1,292 +0,0 @@
-
-
-
-
-
- "backend/index" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "backend/index"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const linkFiber
- linkFiber: ( ) => void = linkFiberStart(snapShot, mode)
-
-
-
-
-
- Const timeJump
- timeJump: (Anonymous function) = timeJumpStart(snapShot, mode)
-
-
-
-
- Functions
-
-
- getRouteURL
-
- getRouteURL( node: SnapshotNode ) : string
-
-
-
-
- Parameters
-
-
- node: SnapshotNode
-
-
- Returns string
-
-
-
-
-
- Object literals
-
-
- Const mode
- mode: object
-
-
-
- jumping
- jumping: false = false
-
-
-
-
- locked
- locked: false = false
-
-
-
-
- paused
- paused: false = false
-
-
-
-
-
- Const snapShot
- snapShot: object
-
-
-
- tree
- tree: null = null
-
-
-
-
- unfilteredTree
- unfilteredTree: null = null
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_linkfiber_.__global.html b/docs/modules/_backend_linkfiber_.__global.html
deleted file mode 100644
index 6738f971a..000000000
--- a/docs/modules/_backend_linkfiber_.__global.html
+++ /dev/null
@@ -1,137 +0,0 @@
-
-
-
-
-
- __global | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_linkfiber_.html b/docs/modules/_backend_linkfiber_.html
deleted file mode 100644
index 446a6c7d6..000000000
--- a/docs/modules/_backend_linkfiber_.html
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
-
-
-
- "backend/linkFiber" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "backend/linkFiber"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const circularComponentTable
- circularComponentTable: Set < unknown > = new Set()
-
-
-
-
- Let doWork
- doWork: boolean = true
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_masterstate_.html b/docs/modules/_backend_masterstate_.html
deleted file mode 100644
index 993327f93..000000000
--- a/docs/modules/_backend_masterstate_.html
+++ /dev/null
@@ -1,156 +0,0 @@
-
-
-
-
-
- "backend/masterState" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "backend/masterState"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const componentActionsRecord
-
-
-
-
-
- Let index
- index: number = 0
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_reactworktags_.html b/docs/modules/_backend_reactworktags_.html
deleted file mode 100644
index 4cddf94b0..000000000
--- a/docs/modules/_backend_reactworktags_.html
+++ /dev/null
@@ -1,142 +0,0 @@
-
-
-
-
-
- "backend/reactWorkTags" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "backend/reactWorkTags"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const reactWorkTags
- reactWorkTags: ( { 0: string } | { 1: string } | { 2: string } | { 3: string } | { 4: string } | { 5: string } | { 6: string } ) [] = [{ 0: 'FunctionComponent' },{ 1: 'ClassComponent' },{ 2: 'IndeterminateComponent' },{ 3: 'HostRoot' }, // Root of a host tree. Could be nested inside another node.{ 4: 'HostPortal' }, // A subtree. Could be an entry point to a different renderer.{ 5: 'HostComponent' },{ 6: 'HostText' },]
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_timejump_.html b/docs/modules/_backend_timejump_.html
deleted file mode 100644
index 10d910c82..000000000
--- a/docs/modules/_backend_timejump_.html
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
- "backend/timeJump" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "backend/timeJump"
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/modules/_backend_tree_.html b/docs/modules/_backend_tree_.html
deleted file mode 100644
index 6c2a980c6..000000000
--- a/docs/modules/_backend_tree_.html
+++ /dev/null
@@ -1,200 +0,0 @@
-
-
-
-
-
- "backend/tree" | Reactime 4.0
-
-
-
-
-
-
-
-
-
-
-
- Search
-
-
-
- Preparing search index...
- The search index is not available
-
-
Reactime 4.0
-
-
-
-
-
-
-
-
-
Module "backend/tree"
-
-
-
-
-
-
-
-
- Variables
-
-
- Const circularComponentTable
- circular
ComponentTable: Set < Tree > = new Set<Tree>()
-
-
-
-
- Let copyInstances
- copyInstances: number = 0
-
-
-
-
- Functions
-
-
- scrubUnserializableMembers
-
- scrubUnserializableMembers( tree: Tree ) : Tree
-
-
-
-
-
-
-
-
-
-
-
Legend
-
-
- Namespace
- Object literal
- Variable
- Function
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/high-contrast-colors.md b/high-contrast-colors.md
new file mode 100644
index 000000000..69eb3dd6b
--- /dev/null
+++ b/high-contrast-colors.md
@@ -0,0 +1,17 @@
+## High Contrast Colors to Help with Color Blindness
+- Dark Blue (#000080)
+- Light Blue (#ADD8E6)
+- Dark Green (#006400)
+- Light Green (#90EE90)
+- Dark Red (#8B0000)
+- Light Red (#FFC0CB)
+- Dark Purple (#800080)
+- Light Purple (#BA55D3)
+- Dark Yellow (#FFD700)
+- Light Yellow (#FFFFE0)
+- Dark Orange (#FF8C00)
+- Light Orange (#FFA500)
+- Dark Brown (#8B4513)
+- Light Brown (#D2691E)
+- Dark Gray (#A9A9A9)
+- Light Gray (#D3D3D3)
\ No newline at end of file
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 000000000..9373f1aff
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,32 @@
+const { TextEncoder } = require('util');
+module.exports = {
+ globals: {
+ TextEncoder: TextEncoder,
+ },
+ transform: {
+ '^.+\\.(js|ts|tsx)$': 'ts-jest',
+ },
+ testPathIgnorePatterns: [
+ 'www',
+ './src/backend/__tests__/ignore',
+ './src/app/__tests__enzyme/ignore',
+ // './src/backend/__tests__/linkFiber.test.ts',
+ './src/app/slices/mainSlice.ts',
+ ],
+ coveragePathIgnorePatterns: [
+ '/src/backend/__tests__/ignore/',
+ '/src/app/__tests__enzyme/ignore',
+ // './src/backend/__tests__/linkFiber.test.ts',
+ './src/app/slices/mainSlice.ts',
+ ],
+ transformIgnorePatterns: ['/node_modules/(?!d3|d3-array|internmap|delaunator|robust-predicates)'],
+ testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$',
+ moduleFileExtensions: ['ts', 'tsx', 'js'],
+ setupFilesAfterEnv: ['@testing-library/jest-dom'],
+ testEnvironment: 'jsdom',
+ moduleNameMapper: {
+ '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
+ '/__mocks__/fileMock.js',
+ '\\.(scss|sass|css)$': 'identity-obj-proxy',
+ },
+};
diff --git a/package.json b/package.json
index ec09829ab..b1e3c6dd5 100644
--- a/package.json
+++ b/package.json
@@ -1,30 +1,18 @@
{
"name": "reactime",
"description": "build web extension bundle.js",
- "jest": {
- "transform": {
- "^.+\\.(js|ts|tsx)$": "ts-jest"
- },
- "testPathIgnorePatterns": ["www"],
- "transformIgnorePatterns": [
- "/node_modules/(?!d3|d3-array|internmap|delaunator|robust-predicates)"
- ],
- "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
- "moduleFileExtensions": [
- "ts",
- "tsx",
- "js"
- ]
- },
"scripts": {
- "build": "NODE_OPTIONS=--openssl-legacy-provider webpack --mode production",
- "dev": "NODE_OPTIONS=--openssl-legacy-provider webpack --mode development --watch",
- "buildlegacy": "webpack --mode production",
- "devlegacy": "webpack --mode development --watch",
+ "build": "webpack --mode production",
+ "dev": "cross-env NODE_ENV=development webpack --mode development --watch",
+ "buildlegacy": "NODE_OPTIONS=--openssl-legacy-provider webpack --mode production",
+ "devlegacy": "NODE_OPTIONS=--openssl-legacy-provider webpack --mode development --watch",
"test": "jest --verbose --coverage",
+ "test-backend": "jest --verbose --coverage src/backend",
+ "test-frontend": "jest --verbose --coverage src/app",
"test-on": "./node_modules/.bin/jest $1",
"docker-test-lint": "eslint --ext .js --ext .jsx src",
- "docs": "typedoc --json docs --inputFiles src/app --inputFiles src/backend --readme docs/readme.md"
+ "docs": "typedoc",
+ "format": "prettier --config .prettierrc './**/*.{ts,tsx,js,jsx}' --write"
},
"keywords": [
"react",
@@ -44,8 +32,15 @@
"url": "https://github.com/open-source-labs/reactime"
},
"contributors": [
+ "Jesse Guerrero",
+ "Oliver Cho",
+ "Eva Ury",
+ "Amy Yang",
"Abaas Khorrami",
+ "Alex Gomez",
+ "Alexander Landeros",
"Ali Rahman",
+ "Andrew Byun",
"Andy Tsou",
"Andy Wong",
"Becca Viner",
@@ -55,156 +50,167 @@
"Caner Demir",
"Carlos Perez",
"Chris Flannery",
+ "Chris Guizzetti",
"Christopher LeBrett",
+ "Christopher Stamper",
"Cole Styron",
+ "Daljit Gill",
+ "Dane Corpion",
+ "Daniel Ryczek",
+ "David Bernstein",
"David Chai",
"David Kim",
+ "David Moore",
"Dennis Lopez",
+ "Edar Liu",
"Edwin Menendez",
+ "Eivind Del Fierro",
+ "Ellie Simens",
"Ergi Shehu",
"Eric Yun",
"Freya Wu",
"Gabriela Jardim Aquino",
+ "Garrett Chow",
"Gregory Panciera",
"Haejin Jo",
+ "Harry Fox",
"Hien Nguyen",
"Jack Crish",
+ "Jackie Yuan",
+ "James McCollough",
"James Nghiem",
+ "Jasmine Noor",
+ "Jason Victor",
+ "Jesse Rosengrant",
+ "Jimmy Phy",
+ "John Banks",
"Joseph Park",
+ "Joseph Stern",
"Josh Kim",
"Joshua Howard",
+ "Kelvin Mirhan",
"Kevin Fey",
"Kevin HoEun Lee",
"Kevin Ngo",
"Kim Mai Nguyen",
+ "Kris Sorensen",
+ "Kristina Wallen",
+ "Kyle Bell",
+ "Lance Ziegler",
+ "Liam Donaher",
"Lina Shin",
+ "Mark Teets",
+ "Mike Bednarz",
+ "Minzo Kim",
+ "Morah Geist",
"Nathanael Wa Mwenze",
+ "Nathan Richardson",
+ "Ngoc Zwolinski",
+ "Nick Huemmer",
+ "Patrice Pinardo",
+ "Peter Lam",
"Prasanna Malla",
+ "Quan Le",
+ "Ragad Mohammed",
"Rajeeb Banstola",
"Raymond Kwan",
"Robby Tipton",
+ "Robert Maeda",
"Rocky Lin",
"Ruth Anam",
"Ryan Dang",
+ "Sergei Liubchenko",
+ "Sean Kelly",
"Sierra Swaby",
"Tania Lind",
"Viet Nguyen",
+ "Vincent Nguyen",
"Wilton Lee",
- "Yujin Kang"
+ "Yididia Ketema",
+ "Yujin Kang",
+ "Zachary Freeman"
],
"license": "ISC",
"devDependencies": {
- "@babel/core": "^7.12.7",
- "@babel/plugin-proposal-class-properties": "^7.10.4",
- "@babel/plugin-proposal-decorators": "^7.10.5",
- "@babel/preset-env": "^7.12.7",
- "@babel/preset-react": "^7.12.7",
- "@emotion/babel-plugin": "^11.7.2",
- "@testing-library/jest-dom": "^4.2.4",
- "@testing-library/react": "^13.4.0",
- "@types/chai": "^4.2.14",
- "@types/chrome": "^0.0.119",
- "@types/d3": "^7.4.0",
- "@types/d3-scale-chromatic": "^2.0.0",
- "@types/jest": "^26.0.4",
- "@types/lodash.isequal": "^4.5.5",
- "@types/node": "^12.19.6",
- "@types/react": "^17.0.43",
- "@typescript-eslint/eslint-plugin": "^3.6.1",
- "@typescript-eslint/parser": "^3.6.1",
- "babel-loader": "^8.1.0",
- "babel-preset-airbnb": "^5.0.0",
- "core-js": "^3.6.5",
- "css-loader": "^3.6.0",
- "enzyme": "^3.11.0",
- "enzyme-adapter-react-16": "^1.15.6",
- "eslint": "^6.8.0",
- "eslint-config-airbnb": "^18.2.0",
- "eslint-plugin-import": "^2.22.0",
- "eslint-plugin-jest": "^22.21.0",
- "eslint-plugin-jsx-a11y": "^6.3.1",
- "eslint-plugin-react": "^7.20.3",
- "eslint-plugin-react-hooks": "^1.7.0",
- "express": "^4.17.1",
- "jest": "^26.1.0",
- "jest-cli": "^26.1.0",
- "jest-diff": "^26.1.0",
- "jest-runner-eslint": "^0.7.7",
- "jscharting-react": "^1.2.1",
- "puppeteer": "^14.3.0",
- "sass": "^1.26.10",
- "sass-loader": "^7.3.1",
- "sinon-chrome": "^3.0.1",
- "style-loader": "^0.23.1",
- "ts-jest": "^26.1.2",
- "ts-loader": "^7.0.5",
- "ts-node": "^9.1.1",
- "typedoc": "^0.17.8",
- "typedoc-webpack-plugin": "^1.1.4",
- "typescript": "^3.9.6",
- "webpack": "^4.43.0",
- "webpack-chrome-extension-reloader": "^1.3.0",
- "webpack-cli": "^3.3.12"
+ "@babel/parser": "^7.26.2",
+ "@babel/types": "^7.26.0",
+ "@testing-library/jest-dom": "^6.1.5",
+ "@testing-library/react": "^14.1.2",
+ "@testing-library/user-event": "^14.5.1",
+ "@types/chrome": "^0.0.254",
+ "@types/jest": "^29.5.11",
+ "@types/node": "^20.10.5",
+ "@typescript-eslint/eslint-plugin": "^6.15.0",
+ "copy-webpack-plugin": "^11.0.0",
+ "css-loader": "^6.8.1",
+ "eslint-plugin-jest": "^27.6.0",
+ "eslint-plugin-jest-dom": "^5.1.0",
+ "eslint-plugin-react": "^7.33.2",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-testing-library": "^6.2.0",
+ "html-webpack-plugin": "^5.5.4",
+ "identity-obj-proxy": "^3.0.0",
+ "jest": "^29.7.0",
+ "jsdom": "^23.0.1",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.21.1",
+ "sass": "^1.83.0",
+ "sass-loader": "^16.0.4",
+ "style-loader": "^3.3.3",
+ "ts-jest": "^29.1.2",
+ "ts-loader": "^9.5.1",
+ "typedoc": "^0.25.4",
+ "typescript": "^5.3.3",
+ "webpack": "^5.89.0",
+ "webpack-cli": "^5.1.4"
},
"dependencies": {
- "@emotion/react": "^11.9.0",
- "@emotion/styled": "^11.8.1",
- "@fortawesome/fontawesome-free": "^5.15.1",
- "@fortawesome/fontawesome-svg-core": "^1.2.32",
- "@fortawesome/free-regular-svg-icons": "^5.15.1",
- "@fortawesome/free-solid-svg-icons": "^5.15.1",
- "@fortawesome/react-fontawesome": "^0.1.12",
- "@material-ui/core": "^4.11.2",
- "@mui/material": "^5.8.2",
- "@types/react-dom": "^17.0.14",
- "@types/react-router-dom": "^5.3.3",
- "@visx/axis": "^1.0.0",
- "@visx/brush": "^1.2.0",
- "@visx/clip-path": "^1.0.0",
- "@visx/event": "^1.0.0",
- "@visx/glyph": "^1.0.0",
- "@visx/gradient": "^1.0.0",
- "@visx/grid": "^1.0.0",
- "@visx/group": "^1.0.0",
- "@visx/hierarchy": "^1.0.0",
- "@visx/legend": "^1.0.0",
- "@visx/responsive": "^1.0.0",
- "@visx/scale": "^1.0.0",
- "@visx/shape": "^1.0.0",
- "@visx/text": "^1.0.0",
- "@visx/tooltip": "^1.0.0",
- "@visx/zoom": "^1.0.0",
- "acorn": "^7.3.1",
- "acorn-jsx": "^5.2.0",
- "apexcharts": "^3.23.1",
- "chai": "^4.2.0",
- "d3": "^7.6.1",
+ "@emotion/react": "^11.11.1",
+ "@emotion/styled": "^11.11.0",
+ "@mui/icons-material": "^5.15.1",
+ "@mui/material": "^5.15.1",
+ "@mui/system": "^5.15.1",
+ "@reduxjs/toolkit": "^2.0.1",
+ "@visx/axis": "^3.5.0",
+ "@visx/event": "^3.3.0",
+ "@visx/gradient": "^3.3.0",
+ "@visx/grid": "^3.5.0",
+ "@visx/group": "^3.3.0",
+ "@visx/hierarchy": "^3.3.0",
+ "@visx/responsive": "^3.3.0",
+ "@visx/scale": "^3.5.0",
+ "@visx/shape": "^3.5.0",
+ "@visx/text": "^3.3.0",
+ "@visx/tooltip": "^3.3.0",
+ "cross-env": "^7.0.3",
+ "d3": "^7.8.5",
"d3-scale-chromatic": "^3.0.0",
- "d3-shape": "^2.0.0",
- "d3-zoom": "^3.0.0",
- "immer": "^9.0.12",
- "intro.js": "^5.0.0",
- "intro.js-react": "^0.6.0",
- "jest-runner": "^26.1.0",
- "jscharting": "^3.0.2",
- "jsondiffpatch": "^0.3.11",
+ "d3-shape": "^3.2.0",
+ "dotenv": "^16.3.1",
+ "express": "^4.18.2",
+ "html-react-parser": "^5.0.11",
+ "intro.js": "^7.2.0",
+ "intro.js-react": "^1.0.0",
+ "jest-environment-jsdom": "^29.7.0",
+ "jsondiffpatch": "^0.5.0",
"lodash": "^4.17.21",
- "prop-types": "^15.7.2",
- "rc-slider": "^8.7.1",
- "rc-tooltip": "^3.7.3",
- "react": "^16.14.0",
- "react-apexcharts": "^1.3.7",
- "react-dom": "^16.13.1",
- "react-hover": "^2.0.0",
- "react-html-parser": "^2.0.2",
- "react-json-tree": "^0.11.2",
- "react-router-dom": "^5.2.0",
- "react-select": "^3.2.0",
- "react-spinners": "^0.11.0",
- "react-split": "^2.0.14",
- "recoil": "0.0.10",
- "util": "^0.12.4",
- "web-vitals": "^1.1.0",
- "yarn": "^1.22.19"
+ "lucide-react": "^0.468.0",
+ "node": "^18.12.1",
+ "prettier": "^3.1.1",
+ "rc-slider": "^10.5.0",
+ "rc-tooltip": "^6.1.3",
+ "react": "^18.2.0",
+ "react-apexcharts": "^1.4.1",
+ "react-hot-toast": "^2.4.1",
+ "react-hover": "^3.0.1",
+ "react-json-tree": "^0.18.0",
+ "react-redux": "^9.0.4",
+ "react-select": "^5.8.0",
+ "react-spinners": "^0.13.8",
+ "redux": "^5.0.0",
+ "redux-mock-store": "^1.5.5",
+ "regenerator-runtime": "^0.14.1",
+ "styled-components": "^6.1.2",
+ "web-vitals": "^3.5.0"
}
}
diff --git a/src/DEVELOPER_README.md b/src/DEVELOPER_README.md
new file mode 100644
index 000000000..6a9491529
--- /dev/null
+++ b/src/DEVELOPER_README.md
@@ -0,0 +1,302 @@
+# Developer README
+
+## Brief
+
+Our mission at Reactime is to maintain and iterate constantly, but never at the expense of future developers. We know how hard it is to quickly get up to speed and onboard in a new codebase. So here are some helpful pointers to help you hit the ground running. 🏃🏾
+
+## Building from source
+
+1. [Download]("https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en") React Dev Tools from the Chrome Webstore Here
+
+2. Clone down the Reactime repo onto your machine.
+
+```
+git clone https://github.com/open-source-labs/reactime.git
+```
+
+3. Install dependencies and build.
+
+```
+cd reactime
+npm install
+npm run dev
+```
+
+With release of Node v18.12.1 (LTS) on 11/4/22, the script has been updated to 'npm run dev' || 'npm run build' for backwards compatibility.
+For version Node v16.16.0, please use script 'npm run devlegacy' || 'npm run buildlegacy'
+
+4. Spin up the demo application.
+
+```
+cd demo-app
+npm install
+npm run dev
+```
+
+Similar approach for Next.js and Remix demo apps
+
+5. Add Reactime to your Chrome extensions.
+
+- Navigate to chrome://extensions
+- Select “Load Unpacked”
+- Choose reactime > src > extension > build
+- Navigate to http://localhost:8080/ to inspect the demo application using Reactime!
+- Once the initial build has been completed and loaded into chrome as an unpacked extension, you may enter the root directory and run ‘npm run dev’ to hot load the chrome extension. You should see ‘[ Starting the Chrome Hot Plugin Reload Server... ]’. You should now be able to see changes without having to rebuild the extension. If for some reason it does not, feel free to rebuild and then try the Hot Plugin Reload Server again.
+
+
+
+## Linting
+
+_Before_ beginning development, especially on teams, make sure to configure your linter and code formatting to conform to one unified setting (We recommend [the Airbnb style guide](https://github.com/airbnb/javascript)!) This will make reviewing PRs much more readable and less error-prone.
+
+
+# Possible Avenues for Future Iterators
+
+Here are some notes on the current state of Reactime and considerations for future development.
+
+## Address open issues on the main OSLabs Reactime Github
+
+There are a variety of open issues on the [OSLabs Reactime Github](https://github.com/open-source-labs/reactime) that remain to be addressed.
+
+## Support for useReducer Time Travel
+
+Reactime currently shows data stored via useState, but has limited support for other hooks such as useReducer. While Reactime can now display state data from useReducer hooks in its component view, maintaining full time travel functionality for reducer states presents significant challenges.
+
+Current Implementation
+
+Reactime successfully captures and displays the current state of useReducer hooks in components
+The state data and last dispatched action for reducers are captured in the component snapshot
+This data is accessible in the component tooltips when hovering over nodes in the component map
+Reducer states are stored separately from useState data in the componentData structure
+
+Challenges with Time Travel
+
+Unlike useState which has a simple state setter function, useReducer state changes must go through the reducer function
+The reducer function defines the valid state transitions through actions
+Simply setting a new state value would bypass the reducer's action-based state management
+Maintaining the correct action history and ensuring state validity through time travel becomes complex
+The current implementation can show reducer states at different points in time but cannot reliably replay state transitions
+
+Future Considerations
+Teams working on expanding reducer support should consider:
+
+How to capture and replay sequences of reducer actions
+Ways to maintain reducer state validity during time travel
+Potential approaches for reconstructing reducer state history
+Methods to handle complex reducer patterns like middleware or side effects
+Trade-offs between full reducer state management and simplified state snapshots
+
+## Expanding Support for Custom Hooks
+
+Reactime currently has a robust system for detecting and handling built-in React hooks, but custom hooks present unique opportunities and challenges for state tracking and visualization.
+
+Current Implementation
+
+Reactime uses AST parsing via @babel/parser to analyze hook usage in components
+The system identifies hook patterns through memoizedState examination in the Fiber tree
+Hook names and state variables are extracted and matched with their corresponding state values
+This works well for direct useState and useReducer calls but may miss custom hook implementations
+
+Challenges
+
+Custom hooks can contain multiple internal state management hooks
+The relationship between custom hook state and component state is not always clear in the Fiber tree
+Hook naming patterns may vary across different custom hook implementations
+State updates in custom hooks might use complex patterns or composition
+The current AST parsing system is optimized for standard hook patterns
+
+Future Considerations
+Teams looking to expand custom hook support should consider:
+
+How to identify and group state belonging to the same custom hook
+Ways to visualize the relationship between custom hook state and component state
+Methods to track state flow through custom hook composition
+Approaches for handling custom hooks that combine multiple state management methods
+Strategies for maintaining time travel functionality with custom hook state
+
+## Newsletter functionality on the Reactime website
+
+As noted in the [Reactime Webite Github](https://github.com/reactimetravel/reactime-website), a newsletter functionality would be nice but has not been implemented yet.
+
+# File Structure
+
+In the _src_ folder, there are three directories we care about: _app_, _backend_, and _extension_.
+
+```
+src/
+├── app/ # Frontend code
+│ ├── __tests__/ # React Testing Library
+│ ├── components/ # React components
+│ ├── containers/ # More React components
+│ ├── slices/ # Redux Toolkit mechanism for updating state
+│ ├── styles/ #
+| ├── App.tsx
+│ ├── FrontendTypes.ts # Library of typescript interfaces
+│ ├── index.tsx # Starting point for root App component
+│ ├── module.d.ts #
+│ └── store.ts #
+│
+├── backend/ # "Backend" code (injected into target app)
+│ │ # Focus especially on linkFiber, timeJump, tree, and helpers
+│ ├── __tests__/ #
+│ ├── controllers/ #
+│ ├── createComponentActionsRecord.ts # Update the componentActionsRecord with new bound state-update methods
+│ ├── createTree.ts # Construct a tree snapshot from the FiberRoot tree given by ReactFiber.
+│ ├── statePropExtractor.ts # Helper functions to extract & format prop, state, and context data
+│ ├── throttle.ts #
+│ ├── timeJump.ts # Rerenders DOM based on snapshot from background script
+│ ├── models/
+│ ├── filterConditions.ts #
+│ ├── masterState.ts # Component action record interface
+│ ├── routes.ts # Interfaces with the browser history stack
+│ ├── tree.ts # Custom structure to send to background
+│ ├── routers/
+│ ├── linkFiber.ts # Check for all requirement to start Reactime and
+│ ├── snapShot.ts #
+│ ├── types/ # Typescript interfaces
+│ ├── index.ts # Starting point for backend functionality
+│ ├── index.d.ts # Definitely Type file for Index
+│ ├── module.d.ts #
+│ ├── puppeteerServer.ts #
+│
+├── extension/ # Chrome Extension code
+│ ├── build/ # Destination for bundles and manifest.json (Chrome config file)
+│ │ #
+│ ├── background.js # Chrome Background Script
+│ └── contentScript.ts # Chrome Content Script
+└──
+```
+
+# Diagrams
+
+All the diagrams of data flows are available on [MIRO](https://miro.com/app/board/uXjVPictrsM=/)
+
+1. The _app_ folder is responsible for the Single Page Application that you see when you open the chrome dev tools under the Reactime tab.
+
+
+
+
+
+
+
+2. The _backend_ folder contains the set of all scripts that we inject into our "target" application via `background.js`
+ - In Reactime, its main role is to generate data and handle time-jump requests from the background script in our _extension_ folder.
+
+
+
+
+
+3. The _extension_ folder is where the `contentScript.js` and `background.js` are located.
+ - Like regular web apps, Chrome Extensions are event-based. The background script (aka service worker) is where one typically monitors for browser triggers (e.g. events like closing a tab, for example). The content script is what allows us to read or write to our target web application, usually as a result of [messages passed](https://developer.chrome.com/extensions/messaging) from the background script.
+ - These two files help us handle requests both from the web browser and from the Reactime extension itself
+
+## Data Flow Architecture
+
+The general flow of data is described in the following steps:
+
+
+
+1. When the background bundle is loaded by the browser, it executes a script injection into the dom. (see section on _backend_). This script uses a technique called [throttle](https://medium.com/@bitupon.211/debounce-and-throttle-160affa5457b) to send state data from the app to the content script every specified milliseconds (in our case, this interval is 70ms).
+
+2. The content script always listens for messages being passed from the extension's target application. Upon receiving data from the target app, the content script will immediately forward this data to the background script which then updates an object called `tabsObj`. Each time `tabsObj` is updated, its latest version will be passed to Reactime, where it is processed for displaying to the user by the _app_ folder scripts.
+
+3. Likewise, when Reactime emits an action due to user interaction -- a "jump" request for example -- a message will be passed from Reactime via the background script to the content script. Then, the content script will pass a message to the target application containing a payload that represents the state the user wants the DOM to reflect or "jump" to.
+ - One important thing to note here is that this jump action must be dispatched in the target application (i.e. _backend_ land), because only there do we have direct access to the DOM.
+
+# Reacti.me Website:
+
+See [Reacti.me README](https://github.com/reactimetravel/reactime-website/blob/main/README.md) for instruction of how to update the website.
+Note: all other domain names that may still function are no longer registered/paid for by Codesmith. These websites may be removed at any time. Please focus on renewing Reacti.me as the primary domain for future iterations to remain consistent.
+
+# Console logs
+
+Navigation between different console.log panels can be confusing when running Reactime. We created a short instruction where you can find the results for your console.log
+
+### /src/extension
+
+Console.logs from the Extension folder you can find here:
+
+- Chrome Extension (Developer mode)
+- Background page
+
+
+
+### /src/app
+
+Console.logs from the App folder you can find here:
+
+- Chrome Browser
+- Inspect
+
+
+
+### /src/backend
+
+Console.logs from the App folder you can find here:
+
+- Open the Reactime extension in Chrome
+- Click "Inspect" on Reactime
+
+
+
+# Chrome Developer Resources
+
+Still unsure about what content scripts and background scripts do for Reactime, or for a chrome extensions in general?
+
+- The implementation details [can be found](./extension/background.js) [in the source files](./extension/contentScript.ts) themselves.
+- We also encourage you to dive into [the official Chrome Developer Docs](https://developer.chrome.com/home).
+
+Some relevant sections are reproduced below:
+
+> Content scripts are files that run in the context of web pages.
+>
+> By using the standard Document Object Model (DOM), they are able to **read** details of the web pages the browser visits, **make changes** to them and **pass information back** to their parent extension. ([Source](https://developer.chrome.com/extensions/content_scripts))
+
+- One helpful way to remember a content script's role in the Chrome ecosystem is to think: a _content_ script is used to read and modify a target web page's rendered _content_.
+
+> A background page is loaded when it is needed, and unloaded when it goes idle.
+>
+> Some examples of events include:
+> The extension is first installed or updated to a new version.
+> The background page was listening for an event, and the event is dispatched.
+> A content script or other extension sends a message.
+> Another view in the extension, such as a popup, calls `runtime.getBackgroundPage`.
+>
+> Once it has been loaded, a background page will stay running as long as it is performing an action, such as calling a Chrome API or issuing a network request.
+>
+> Additionally, the background page will not unload until all visible views and all message ports are closed. Note that opening a view does not cause the event page to load, but only prevents it from closing once loaded. ([Source](https://developer.chrome.com/extensions/background_pages))
+
+- You can think of background scripts serving a purpose analogous to that of a **server** in the client/server paradigm. Much like a server, our `background.js` listens constantly for messages (i.e. requests) from two main places:
+ 1. The content script
+ 2. The chrome extension "front-end" **(_NOT_ the interface of the browser, this is an important distinction.)**
+- In other words, a background script works as a sort of middleman, directly maintaining connection with its parent extension, and acting as a proxy enabling communication between it and the content script.
+
+# Launching to Chrome Web Store
+
+Once you are ready for launch, follow these steps to simplify deployment to the Chrome Web Store:
+
+1. Run npm run build in Reactime to build the production version of Reactime
+2. Right click on the build folder and click “compress” to make a compressed zip version of the build folder. The compressed zip is what you will upload to the Chrome Web Store
+3. Navigate to the Chrome Web Store Developer Dashboard (logged in with Reactime credentials). Go to Build > Package > Upload new package, and when prompted, upload the build.zip file
+4. Update the Store Listing and that’s it! Click “Submit for review” and wait for the Chrome store to process your request
+
+# Past Medium Articles for Reference
+
+- [Reactime Reimagined: A Major Leap Forward in React Debugging](https://medium.com/@elliesimens/reactime-reimagined-a-major-leap-forward-in-react-debugging-7b76a0a66f42)
+- [Reactime v25: The Time to React is Now!](https://medium.com/@loganjnelsen/reactime-v25-the-time-to-react-is-now-ace90e45a9c7)
+- [Relaunching Reactime: Updates and a New Accessibility Feature!](https://medium.com/@evaury/relaunching-reactime-updates-and-a-new-accessibility-feature-1f0fd3a5bd8c)
+- [Reactime renovation: Updates Coming in Version 23.0!](https://medium.com/@liam.donaher/reactime-renovation-updates-coming-in-version-23-0-37b2ef2a2771)
+- [Reactime 22: Reactime: Real-time Debugging, Timless Results](https://medium.com/@kelvinmirhan/reactime-real-time-debugging-timeless-results-3f163b721d01)
+- [Reactime 21: Cheers to Reactime, Version 21!](https://medium.com/@brok3turtl3/cheers-to-reactime-version-21-fa4dafa4bc74)
+- [Reactime 20: Reactime just keeps getting better!](https://medium.com/@njhuemmer/reactime-just-keeps-getting-better-b37659ff8b71)
+- [Reactime 19: What time is it? It’s still Reactime!](https://medium.com/@minzo.kim/what-time-is-it-its-still-reactime-d496adfa908c)
+- [Reactime 18.0. Better than ever](https://medium.com/@zdf2424/reactime-18-0-better-than-ever-148b81606257)
+- [Reactime v17.0.0: Now with support for the Context API, and a modern UI](https://medium.com/@reactime/reactime-v17-0-0-now-with-support-for-the-context-api-and-a-modern-ui-f0edf9e54dae)
+- [Reactime XVI: Clean-up Time](https://medium.com/@emintahirov1996/reactime-xvi-cleanup-time-a14ba3dcc8a6)
+- [Inter-Route Time Travel with Reactime](https://medium.com/@robbytiptontol/inter-route-time-travel-with-reactime-d84cd55ec73b)
+- [Time-Travel State with Reactime](https://medium.com/better-programming/time-traveling-state-with-reactime-6-0-53fdc3ae2a20)
+- [Reactime 4: React Fiber and Reactime](https://medium.com/@aquinojardim/react-fiber-reactime-4-0-f200f02e7fa8)
+- [Meet Reactime - a time-traveling State Debugger for React](https://medium.com/@yujinkay/meet-reactime-a-time-traveling-state-debugger-for-react-24f0fce96802)
+- [Deep in Weeds with Reactime, Concurrent React_fiberRoot, and Browser History Caching](https://itnext.io/deep-in-the-weeds-with-reactime-concurrent-react-fiberroot-and-browser-history-caching-7ce9d7300abb)
+- [Time-Traveling Through React State with Reactime 9.0](https://rxlina.medium.com/time-traveling-through-react-state-with-reactime-9-0-371dbdc99319)
+- [What time is it? Reactime!](https://medium.com/@liuedar/what-time-is-it-reactime-fd7267b9eb89)
diff --git a/src/README.md b/src/README.md
deleted file mode 100644
index e013353b0..000000000
--- a/src/README.md
+++ /dev/null
@@ -1,149 +0,0 @@
-# Developer README
-
-## Brief
-Our mission at Reactime is to maintain and iterate constantly, but never at the expense of future developers. We know how hard it is to quickly get up to speed and onboard in a new codebase. So, here are some helpful pointers to help you hit the ground running. 🏃🏾💨
-
-## Building from source
-
-1. If you have already installed Reactime from the Chrome Web Store, disable or uninstall it.
-2. Run `yarn` to install all dependencies.
-3. Run `yarn dev`. This will start a `webpack` process which watches for file changes and whenever it sees some, automatically rebuilds the webpack bundles used by the extension.
-4. Go to `chrome://extensions`
-5. Ensure Developer mode is enabled
-6. Click `Load unpacked`
-7. Select the `src/extension/build` directory
-
-Now you should be able to change Reactime code and see the changes instantly reflected in your browser!
-
-With release of Node v18.12.1 (LTS) on 11/4/22, the script has been updated to 'npm run dev' | 'npm run build' for backwards compatibility.
-For version Node v16.16.0, please use script 'npm run devlegacy' | 'npm run buildlegacy'
-
-## Quick Tips
-- _Before_ beginning development, especially on teams, make sure to configure your linter and code formatting to conform to one unified setting (We recommend [the Airbnb style guide](https://github.com/airbnb/javascript)!) This will make reviewing PRs much more readable and less error-prone.
-
-## File Structure
-
-In the *src* folder, there are three directories we care about: *app*, *backend*, and *extension*.
-```
-src/
-├── app/ # Frontend code
-│ ├── __tests__/ #
-│ ├── actions/ # Redux action creators
-│ ├── components/ # React components
-│ ├── constants/ #
-│ ├── containers/ # More React components
-│ ├── reducers/ # Redux mechanism for updating state
-│ ├── styles/ #
-│ ├── index.tsx # Starting point for root App component
-│ ├── module.d.ts #
-│ └── store.tsx #
-│
-├── backend/ # "Backend" code (injected into target app)
-│ │ # Focus especially on linkFiber, timeJump, tree, and helpers
-│ ├── __tests__/ #
-│ ├── types/ # Typescript interfaces
-│ ├── helpers.js #
-│ ├── index.ts # Starting point for backend functionality
-│ ├── index.d.ts #
-│ ├── linkFiber.ts #
-│ ├── masterState.js # Component action record interface
-│ ├── module.d.ts #
-│ ├── package.json #
-│ ├── puppeteerServer.js #
-│ ├── routes.ts # Interfaces with the browser history stack
-│ ├── timeJump.ts # Rerenders DOM based on snapshot from background script
-│ └── tree.ts # Custom structure to send to background
-│
-├── extension/ # Chrome Extension code
-│ ├── build/ # Destination for bundles and manifest.json (Chrome config file)
-│ │ #
-│ ├── background.js # Chrome Background Script
-│ └── contentScript.ts # Chrome Content Script
-└──
-```
-
-1. The *app* folder is responsible for the Single Page Application that you see when you open the chrome dev tools under the Reactime tab.
-
-
-
-2. The *backend* folder contains the set of all scripts that we inject into our "target" application via `background.js`
- - In Reactime, its main role is to generate data and handle time-jump requests from the background script in our *extension* folder.
-
-
-
-3. The *extension* folder is where the `contentScript.js` and `background.js` are located.
- - Like regular web apps, Chrome Extensions are event-based. The background script is where one typically monitors for browser triggers (e.g. events like closing a tab, for example). The content script is what allows us to read or write to our target web application, usually as a result of [messages passed](https://developer.chrome.com/extensions/messaging) from the background script.
- - These two files help us handle requests both from the web browser and from the Reactime extension itself
-
-
-## Diagramming
-All the diagrams of data flows are avaliable on [MIRO](https://miro.com/app/board/o9J_lejUqLQ=/)
-## Data Flow Architecture
-
-The general flow of data is described in the following steps:
-
-
-
-1. When the background bundle is loaded by the browser, it executes a script injection into the dom. (see section on *backend*). This script uses a technique called [throttle](https://medium.com/@bitupon.211/debounce-and-throttle-160affa5457b) to send state data from the app to the content script every specified milliseconds (in our case, this interval is 70ms).
-
-
-
-2. The content script always listens for messages being passed from the extension's target application. Upon receiving data from the target app, the content script will immediately forward this data to the background script which then updates an object called `tabsObj`. Each time `tabsObj` is updated, its latest version will be passed to Reactime, where it is processed for displaying to the user by the *app* folder scripts.
-
-3. Likewise, when Reactime emits an action due to user interaction -- a "jump" request for example -- a message will be passed from Reactime via the background script to the content script. Then, the content script will pass a message to the target application containing a payload that represents the state the user wants the DOM to reflect or "jump" to.
- - One important thing to note here is that this jump action must be dispatched in the target application (i.e. *backend* land), because only there do we have direct access to the DOM.
-
-## Console.log
-
-Navigation between different console.log panels can be confusing when running Reactime. We created a short instruction where you can find the results for your console.log
-
-### /src/extension
-Console.logs from the Extension folder you can find here:
-- Chrome Extension (Developer mode)
-- Background page
-
-
-
-### /src/app
-Console.logs from the App folder you can find here:
-- Chrome Browser
-- Inspect
-
-
-
-### /src/backend
-Console.logs from the App folder you can find here:
-- Open the Reactime extension in Chrome
-- Click "Inspect" on Reactime
-
-
-
-## Chrome Developer Resources
-Still unsure about what content scripts and background scripts do for Reactime, or for a chrome extensions in general?
- - The implementation details [can be found](./extension/background.js) [in the source files](./extension/contentScript.ts) themselves.
- - We also encourage you to dive into [the official Chrome Developer Docs](https://developer.chrome.com/home).
-
- Some relevant sections are reproduced below:
-
-> Content scripts are files that run in the context of web pages.
->
-> By using the standard Document Object Model (DOM), they are able to **read** details of the web pages the browser visits, **make changes** to them and **pass information back** to their parent extension. ([Source](https://developer.chrome.com/extensions/content_scripts))
-
-- One helpful way to remember a content script's role in the Chrome ecosystem is to think: a *content* script is used to read and modify a target web page's rendered *content*.
-
->A background page is loaded when it is needed, and unloaded when it goes idle.
->
-> Some examples of events include:
->The extension is first installed or updated to a new version.
->The background page was listening for an event, and the event is dispatched.
->A content script or other extension sends a message.
->Another view in the extension, such as a popup, calls `runtime.getBackgroundPage`.
->
->Once it has been loaded, a background page will stay running as long as it is performing an action, such as calling a Chrome API or issuing a network request.
->
-> Additionally, the background page will not unload until all visible views and all message ports are closed. Note that opening a view does not cause the event page to load, but only prevents it from closing once loaded. ([Source](https://developer.chrome.com/extensions/background_pages))
-
-- You can think of background scripts serving a purpose analogous to that of a **server** in the client/server paradigm. Much like a server, our `background.js` listens constantly for messages (i.e. requests) from two main places:
- 1. The content script
- 2. The chrome extension "front-end" **(*NOT* the interface of the browser, this is an important distinction.)**
-- In other words, a background script works as a sort of middleman, directly maintaining connection with its parent extension, and acting as a proxy enabling communication between it and the content script.
diff --git a/src/app/App.tsx b/src/app/App.tsx
new file mode 100644
index 000000000..561a14322
--- /dev/null
+++ b/src/app/App.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import { MemoryRouter as Router } from 'react-router-dom';
+import MainContainer from './containers/MainContainer';
+import { Toaster } from 'react-hot-toast';
+import { ThemeProvider } from './ThemeProvider';
+
+function App(): JSX.Element {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default App;
diff --git a/src/app/FrontendTypes.ts b/src/app/FrontendTypes.ts
new file mode 100644
index 000000000..2fb4bb3b4
--- /dev/null
+++ b/src/app/FrontendTypes.ts
@@ -0,0 +1,414 @@
+import { SeriesPoint } from '@visx/shape/lib/types';
+import { Dispatch } from 'redux';
+
+export interface ActionObj {
+ name: string;
+ seriesName: string;
+ currentTab: string;
+}
+export interface Series {
+ data: {
+ barStack: ActionObj[];
+ };
+ name: string;
+}
+
+export interface PerfData {
+ barStack: BarStackProp[];
+ componentData?: Record;
+ maxTotalRender: number;
+}
+
+export interface PerformanceVisxProps {
+ width: number;
+ height: number;
+ snapshots: any[];
+ hierarchy: any;
+}
+
+export interface TreeProps {
+ snapshot: {
+ name?: string;
+ componentData?: object;
+ state?: string | object;
+ stateSnaphot?: object;
+ children?: any[];
+ };
+ snapshots?: [];
+ currLocation?: object;
+}
+
+export interface BarStackProp {
+ snapshotId: string;
+ route: string;
+ currentTab?: string;
+}
+
+export interface TooltipData {
+ bar: SeriesPoint;
+ key: string;
+ index: number;
+ height: number;
+ width: number;
+ x: number;
+ y: number;
+ color: string;
+ name?: string;
+}
+
+export interface snapshot {
+ snapshotId?: string;
+ children: [];
+ componentData: { actualDuration: number } | undefined;
+ name: string;
+ state: string;
+}
+
+export interface Margin {
+ top: number;
+ right: number;
+ bottom: number;
+ left: number;
+}
+
+export interface BarGraphBase {
+ width: number;
+ height: number;
+ data: PerfData;
+ comparison: Series[];
+}
+
+export interface BarGraphComparisonProps extends BarGraphBase {
+ setSeries: (e: boolean | string) => void;
+ series: number;
+ setAction: (e: boolean | string) => void;
+}
+
+export interface BarGraphProps extends BarGraphBase {
+ setRoute: () => void;
+ allRoutes: unknown;
+ filteredSnapshots: unknown;
+ snapshot: unknown;
+ setSnapshot: () => void;
+}
+
+export interface BarGraphComparisonAction {
+ action: ActionObj;
+ data: ActionObj[];
+ width: number;
+ height: number;
+ comparison: Series[];
+ setSeries: (e: boolean | string) => void;
+ series?: number;
+ setAction: (e: boolean | string) => void;
+}
+
+export interface ActionContainerProps {
+ snapshots?: any;
+ currLocation?: any;
+}
+
+export interface ProvConContainerProps {
+ currentSnapshot: any;
+}
+
+export interface StateContainerProps {
+ snapshot: Record<
+ number,
+ {
+ name?: string;
+ componentData?: Record;
+ state?: Record;
+ stateSnaphot?: Record;
+ children?: unknown[];
+ }
+ >;
+ toggleActionContainer?: any;
+ webMetrics?: object;
+ hierarchy: Record;
+ snapshots?: [];
+ viewIndex?: number;
+ currLocation?: object;
+}
+
+export interface TravelContainerProps {
+ snapshotsLength: number;
+}
+
+export interface Obj {
+ stateSnapshot: {
+ route: any;
+ children: any[];
+ };
+ name: number;
+ branch: number;
+ index: number;
+ children?: [];
+}
+
+export interface RootState {
+ main: MainState;
+}
+
+export interface InitialState {
+ port: null | chrome.runtime.Port;
+ currentTab: null | number;
+ currentTitle: null | string;
+ tabs: {} | { [k: string]: { [k: string]: unknown } };
+ currentTabInApp: null | string;
+ connectionStatus: boolean;
+ connectRequested: boolean;
+}
+
+export interface MainState {
+ port: null | chrome.runtime.Port;
+ currentTab: number;
+ currentTitle: string;
+ tabs: { [k: string]: { [k: string]: unknown } };
+ currentTabInApp: string;
+ connectionStatus: boolean;
+ connectRequested: boolean;
+}
+
+export interface CurrentTab {
+ currBranch: number;
+ currLocation: { [k: string]: any };
+ currParent: number;
+ hierarchy: {
+ stateSnapshot: {
+ route: any;
+ children: any[];
+ };
+ name: number;
+ branch: number;
+ index: number;
+ children?: [];
+ };
+ index: number;
+ intervalId: null | number;
+ mode: { paused: boolean };
+ playing: boolean;
+ seriesSavedStatus: boolean;
+ sliderIndex: number;
+ snapshots: { [k: string]: any }[];
+ status: { [k: string]: any };
+ title: string;
+ viewIndex: number;
+ webMetrics: {
+ LCP: undefined | number;
+ FID: undefined | number;
+ FCP: undefined | number;
+ TTFB: undefined | number;
+ CLS: undefined | number;
+ INP: undefined | number;
+ };
+}
+
+export interface DiffProps {
+ snapshot: { state?: Record };
+ show?: boolean | undefined;
+}
+
+/**
+ * @template ActionProps Props for the action component
+ */
+
+export interface ActionProps {
+ key: string;
+ selected: boolean;
+ last: boolean;
+ index: number;
+ sliderIndex: number;
+ displayName: string;
+ componentName: string;
+ componentData: { actualDuration: number } | undefined;
+ routePath: unknown;
+ state?: Record;
+ viewIndex: number | undefined;
+ isCurrIndex: boolean;
+}
+
+export interface DiffRouteProps {
+ snapshot: Record<
+ string,
+ {
+ name?: string;
+ componentData?: Record;
+ state?: string | unknown;
+ stateSnaphot?: Record;
+ children?: unknown[];
+ }
+ >;
+}
+
+export interface HandleProps {
+ value: number;
+ dragging: boolean;
+ index: number;
+}
+
+export interface MainSliderProps {
+ className?: string;
+ snapshots?: any[];
+}
+
+export interface DefaultMargin {
+ top: number;
+ left: number;
+ right: number;
+ bottom: number;
+}
+
+export interface StateRouteProps {
+ snapshot: {
+ name?: string;
+ componentData?: object;
+ state?: string | object;
+ stateSnaphot?: object;
+ children?: any[];
+ };
+ hierarchy: any;
+ snapshots: [];
+ viewIndex: number;
+ webMetrics: object;
+ currLocation: object;
+}
+
+export interface DropdownProps {
+ selectedSpeed: { value: number; label: string };
+ speeds: { value: number; label: string }[];
+ setSpeed: () => void;
+}
+
+export interface TutorialProps {
+ dispatch: Dispatch;
+ currentTabInApp: string;
+}
+
+export interface TutorialState {
+ stepsEnabled: boolean;
+}
+
+export interface StepsObj {
+ title: string;
+ element?: string | Element;
+ intro: string;
+ position: string;
+}
+
+export interface LinkControlProps {
+ orientation: string;
+ linkType: string;
+ stepPercent: number;
+ selectedNode: string;
+ setOrientation: (orientation: string) => void;
+ setLinkType: (linkType: string) => void;
+ setStepPercent: (percent: number) => void;
+ setSelectedNode: (selectedNode: string) => void;
+ snapShots: Record;
+}
+
+export interface ControlStyles {
+ padding: string;
+}
+
+export interface DropDownStyle {
+ margin: string;
+ fontFamily: string;
+ borderRadius: string;
+ borderStyle: string;
+ borderWidth: string;
+ backgroundColor: string;
+ color: string;
+ padding: string;
+}
+
+export interface Node {
+ children?: Node[];
+ name?: string;
+}
+
+export interface LinkComponent {
+ linkType: string;
+ orientation: string;
+}
+
+export interface LinkTypesProps {
+ width: number;
+ height: number;
+ margin?: { top: number; right: number; bottom: number; left: number };
+ snapshots: Record;
+ currentSnapshot?: Record;
+}
+
+export interface ToolTipStyles {
+ defaultStyles: React.CSSProperties;
+ minWidth: number;
+ maxWidth: number;
+ backgroundColor: string;
+ color: string;
+ fontSize: string;
+ lineHeight: string;
+ fontFamily: string;
+ zIndex: number;
+ pointerEvents: string;
+}
+
+export interface OptionsCursorTrueWithMargin {
+ followCursor: boolean;
+ shiftX: number;
+ shiftY: number;
+}
+
+export interface StatelessCleaning {
+ name?: string;
+ componentData?: Record;
+ state?: string | {};
+ stateSnaphot?: Record;
+ children?: StatelessCleaning[];
+}
+
+export interface Snapshots {
+ snapshot: number;
+ component1: number;
+ component2: number;
+ component3: number;
+ 'all others': number;
+}
+
+export interface ErrorContainerProps {
+ port: chrome.runtime.Port | null;
+}
+
+export interface AxContainer {
+ axSnapshots: [];
+ snapshot: {
+ name?: string;
+ componentData?: object;
+ state?: string | object;
+ stateSnaphot?: object;
+ children?: any[];
+ };
+ snapshots: [];
+ currLocation: object;
+ setShowTree: any;
+ setShowParagraph: any;
+}
+
+export interface FilteredNode {
+ name?: string;
+ state?: any;
+ hooksState?: any;
+ props?: any;
+ componentData?: {
+ context?: any;
+ hooksState?: any;
+ props?: any;
+ };
+ children?: FilteredNode[];
+ context?: any;
+}
+
+export interface FilteredNodeChildren {
+ [key: string]: FilteredNode;
+}
diff --git a/src/app/ThemeProvider.tsx b/src/app/ThemeProvider.tsx
new file mode 100644
index 000000000..3d435faac
--- /dev/null
+++ b/src/app/ThemeProvider.tsx
@@ -0,0 +1,39 @@
+import React, { createContext, useContext, useState, useEffect } from 'react';
+
+const ThemeContext = createContext({
+ isDark: false,
+ toggleTheme: () => {},
+});
+
+export const ThemeProvider = ({ children }) => {
+ const [isDark, setIsDark] = useState(false);
+
+ // Check for system preference on mount
+ useEffect(() => {
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
+ setIsDark(prefersDark);
+ }, []);
+
+ // Update body class when theme changes
+ useEffect(() => {
+ if (isDark) {
+ document.documentElement.classList.add('dark');
+ } else {
+ document.documentElement.classList.remove('dark');
+ }
+ }, [isDark]);
+
+ const toggleTheme = () => {
+ setIsDark((prev) => !prev);
+ };
+
+ return {children} ;
+};
+
+export const useTheme = () => {
+ const context = useContext(ThemeContext);
+ if (context === undefined) {
+ throw new Error('useTheme must be used within a ThemeProvider');
+ }
+ return context;
+};
diff --git a/src/app/__tests__/ActionContainer.test.tsx b/src/app/__tests__/ActionContainer.test.tsx
deleted file mode 100644
index d74722cc9..000000000
--- a/src/app/__tests__/ActionContainer.test.tsx
+++ /dev/null
@@ -1,130 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable react/jsx-filename-extension */
-
-import { shallow, configure } from 'enzyme';
-import React from 'react';
-import Adapter from 'enzyme-adapter-react-16';
-import ActionContainer from '../containers/ActionContainer';
-import { useStoreContext } from '../store';
-import { emptySnapshots } from '../actions/actions';
-import Action from '../components/Action';
-import RouteDescription from '../components/RouteDescription';
-
-configure({ adapter: new (Adapter as any)() });
-
-const state = {
- tabs: {
- 87: {
- snapshots: [1, 2, 3, 4],
- hierarchy: {
- index: 0,
- name: 1,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- route: {
- id: 1,
- url: 'http://localhost:8080/',
- },
- },
- children: [{
- index: 1,
- name: 2,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- route: {
- id: 2,
- url: 'http://localhost:8080/',
- },
- },
- children: [{
- index: 2,
- name: 3,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- route: {
- id: 3,
- url: 'http://localhost:8080/',
- },
- },
- children: [{
- index: 3,
- name: 4,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- route: {
- id: 4,
- url: 'http://localhost:8080/test/',
- },
- },
- children: [],
- }],
- }],
- }],
- },
- currLocation: {
- index: 0,
- name: 1,
- branch: 0,
- },
- sliderIndex: 0,
- viewIndex: -1,
- },
- },
- currentTab: 87,
-};
-
-const dispatch = jest.fn();
-
-jest.mock('../store');
-useStoreContext.mockImplementation(() => [state, dispatch]);
-
-let wrapper;
-
-// actionView={true} must be passed in to in beforeEach() to deal with new
-// conditional rendering in ActionContainer that shows/hides time-travel functionality
-
-beforeEach(() => {
- wrapper = shallow( );
- // wrapper2 = shallow( );
- useStoreContext.mockClear();
- dispatch.mockClear();
-});
-
-describe('testing the emptySnapshot button', () => {
- test('emptySnapshot button should dispatch action upon click', () => {
- wrapper.find('.empty-button').simulate('click');
- expect(dispatch.mock.calls.length).toBe(1);
- });
- test('emptying snapshots should send emptySnapshot action to dispatch', () => {
- wrapper.find('.empty-button').simulate('click');
- expect(dispatch.mock.calls[0][0]).toEqual(emptySnapshots());
- });
-});
-
-test('number of RouteDescription components should reflect number of unique routes', () => {
- expect(wrapper.find(RouteDescription).length).toBe(2);
-});
diff --git a/src/app/__tests__/ActionsButtons.test.tsx b/src/app/__tests__/ActionsButtons.test.tsx
new file mode 100644
index 000000000..76213f702
--- /dev/null
+++ b/src/app/__tests__/ActionsButtons.test.tsx
@@ -0,0 +1,324 @@
+import React from 'react';
+import { render as rtlRender, screen, fireEvent } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import { Provider } from 'react-redux';
+import { store } from '../store';
+import { useDispatch } from 'react-redux';
+import { mainSlice, changeSlider, emptySnapshots } from '../slices/mainSlice';
+
+import { useTheme } from '../ThemeProvider';
+import { configureStore } from '@reduxjs/toolkit';
+
+import DropDown from '../components/Actions/DropDown';
+import RecordButton from '../components/Actions/RecordButton';
+import ThemeToggle from '../components/Actions/ThemeToggle';
+import ProvConContainer from '../containers/ProvConContainer';
+import ActionContainer from '../containers/ActionContainer';
+
+// @ts-ignore
+const useDispatchMock = useDispatch as jest.Mock;
+const dummyDispatch = jest.fn();
+
+// Mock ThemeToggle for RecordButton tests
+jest.mock('../components/Actions/ThemeToggle', () => {
+ return function MockThemeToggle() {
+ return Theme Toggle
;
+ };
+});
+
+// Mock useTheme hook
+jest.mock('../ThemeProvider', () => ({
+ useTheme: jest.fn(),
+}));
+
+// Mock react-redux
+jest.mock('react-redux', () => ({
+ ...jest.requireActual('react-redux'),
+ useDispatch: jest.fn(),
+}));
+
+window.HTMLElement.prototype.scrollIntoView = jest.fn();
+
+// Setup mock before tests
+beforeAll(() => {
+ useDispatchMock.mockReturnValue(dummyDispatch);
+});
+
+// Clear mocks after each test
+afterEach(() => {
+ dummyDispatch.mockClear();
+});
+
+// Helper function for redux wrapped renders
+const render = (component) => rtlRender({component} );
+
+// DropDown Component Tests
+describe('DropDown Component', () => {
+ const mockSetDropdownSelection = jest.fn();
+
+ beforeEach(() => {
+ mockSetDropdownSelection.mockClear();
+ });
+
+ test('renders with placeholder text', () => {
+ render( );
+ expect(screen.getByText('Select Hook')).toBeInTheDocument();
+ });
+
+ test('shows correct options when clicked', () => {
+ render( );
+ const dropdown = screen.getByText('Select Hook');
+ fireEvent.mouseDown(dropdown);
+ expect(screen.getByText('Time Jump')).toBeInTheDocument();
+ expect(screen.getByText('Providers / Consumers')).toBeInTheDocument();
+ });
+
+ test('displays selected value', () => {
+ render(
+ ,
+ );
+ expect(screen.getByText('Time Jump')).toBeInTheDocument();
+ });
+});
+
+// RecordButton Component Tests
+describe('RecordButton Component', () => {
+ const mockOnToggle = jest.fn();
+
+ beforeEach(() => {
+ mockOnToggle.mockClear();
+ });
+
+ test('renders record button with initial state', () => {
+ render( );
+ expect(screen.getByText('Record')).toBeInTheDocument();
+ });
+
+ test('calls onToggle when switch is clicked', () => {
+ render( );
+ const switchElement = screen.getByRole('checkbox');
+ fireEvent.click(switchElement);
+ expect(mockOnToggle).toHaveBeenCalled();
+ });
+
+ test('renders ThemeToggle component', () => {
+ render( );
+ expect(screen.getByTestId('mock-theme-toggle')).toBeInTheDocument();
+ });
+});
+
+// // ThemeToggle Component Tests
+describe('ThemeToggle Component', () => {
+ const mockToggleTheme = jest.fn();
+
+ beforeEach(() => {
+ mockToggleTheme.mockClear();
+ (useTheme as jest.Mock).mockImplementation(() => ({
+ isDark: false,
+ toggleTheme: mockToggleTheme,
+ }));
+ });
+
+ test('renders theme toggle', () => {
+ render( );
+
+ // Check if mock theme toggle exists
+ const themeToggle = screen.getByTestId('mock-theme-toggle');
+ expect(themeToggle).toBeInTheDocument();
+ expect(themeToggle).toHaveTextContent('Theme Toggle');
+ });
+
+ test('renders with correct text', () => {
+ render( );
+ expect(screen.getByTestId('mock-theme-toggle')).toHaveTextContent('Theme Toggle');
+ });
+
+ test('toggles between light and dark mode classes', () => {
+ // First render in light mode
+ (useTheme as jest.Mock).mockImplementation(() => ({
+ isDark: false,
+ toggleTheme: mockToggleTheme,
+ }));
+
+ const { rerender } = render( );
+ const toggle = screen.getByTestId('mock-theme-toggle');
+ expect(toggle).toBeInTheDocument();
+
+ // Since isDark is false, verify the content
+ expect(toggle).toHaveTextContent('Theme Toggle');
+
+ // Rerender in dark mode
+ (useTheme as jest.Mock).mockImplementation(() => ({
+ isDark: true,
+ toggleTheme: mockToggleTheme,
+ }));
+ rerender( );
+
+ // Verify it's still rendered with the same content in dark mode
+ expect(toggle).toBeInTheDocument();
+ expect(toggle).toHaveTextContent('Theme Toggle');
+ });
+});
+
+// ProvConContainer Component Tests
+describe('ProvConContainer Component', () => {
+ const mockSnapshot = {
+ componentData: {
+ context: {
+ theme: { dark: true },
+ user: { id: 1, name: 'Test' },
+ },
+ hooksState: {
+ useState: [{ value: 'test' }],
+ },
+ },
+ children: [
+ {
+ name: 'ThemeProvider',
+ componentData: {
+ context: { theme: 'dark' },
+ },
+ children: [],
+ },
+ ],
+ };
+
+ test('renders empty state message when no providers/consumers found', () => {
+ render( );
+ expect(screen.getByText(/No providers or consumers found/)).toBeInTheDocument();
+ });
+
+ test('renders context data correctly', () => {
+ render( );
+
+ // Use getAllByText to get all theme spans and verify at least one exists
+ const themeElements = screen.getAllByText((content, element) => {
+ return element?.tagName.toLowerCase() === 'span' && element?.textContent === 'theme:';
+ });
+ expect(themeElements.length).toBeGreaterThan(0);
+
+ // Do the same for user spans
+ const userElements = screen.getAllByText((content, element) => {
+ return element?.tagName.toLowerCase() === 'span' && element?.textContent === 'user:';
+ });
+ expect(userElements.length).toBeGreaterThan(0);
+ });
+
+ test('renders provider components correctly', () => {
+ render( );
+
+ // Get all theme elements and use the first one to find its parent
+ const themeElements = screen.getAllByText((content, element) => {
+ return element?.tagName.toLowerCase() === 'span' && element?.textContent === 'theme:';
+ });
+ const parentElement = themeElements[0].closest('div');
+
+ expect(parentElement).toBeInTheDocument();
+ });
+
+ test('correctly parses stringified JSON values', () => {
+ const snapshotWithStringifiedJSON = {
+ componentData: {
+ context: {
+ data: JSON.stringify({ key: 'value' }),
+ },
+ },
+ };
+ render( );
+
+ // Look for the key-value pair in the rendered structure
+ expect(
+ screen.getByText((content, element) => {
+ return element?.tagName.toLowerCase() === 'span' && element?.textContent === 'key:';
+ }),
+ ).toBeInTheDocument();
+
+ expect(
+ screen.getByText((content, element) => {
+ return element?.tagName.toLowerCase() === 'span' && element?.textContent === '"value"';
+ }),
+ ).toBeInTheDocument();
+ });
+});
+
+// Clear Button Tests
+describe('Clear Button', () => {
+ // Create mock store
+ const mockStore = configureStore({
+ reducer: {
+ main: mainSlice.reducer,
+ },
+ preloadedState: {
+ main: {
+ port: null,
+ currentTab: 0,
+ currentTitle: 'No Target',
+ tabs: {
+ 0: {
+ currLocation: {
+ index: 0,
+ stateSnapshot: {
+ children: [],
+ route: {
+ url: '/test',
+ },
+ },
+ },
+ hierarchy: {
+ index: 0,
+ stateSnapshot: {
+ children: [],
+ route: {
+ url: '/test',
+ },
+ },
+ children: [],
+ },
+ sliderIndex: 0,
+ viewIndex: 0,
+ snapshots: [],
+ playing: false,
+ intervalId: null,
+ mode: { paused: false },
+ status: {
+ reactDevToolsInstalled: true,
+ targetPageisaReactApp: true,
+ },
+ },
+ },
+ currentTabInApp: null,
+ connectionStatus: true,
+ connectRequested: true,
+ },
+ },
+ });
+
+ // @ts-ignore
+ const useDispatchMock = useDispatch as jest.Mock;
+ const dummyDispatch = jest.fn();
+
+ beforeEach(() => {
+ useDispatchMock.mockReturnValue(dummyDispatch);
+ dummyDispatch.mockClear();
+ });
+
+ test('renders clear button with correct text', () => {
+ render(
+
+
+ ,
+ );
+ expect(screen.getByText('Clear')).toBeInTheDocument();
+ });
+
+ test('dispatches both emptySnapshots and changeSlider actions when clicked', () => {
+ render(
+
+
+ ,
+ );
+ fireEvent.click(screen.getByText('Clear'));
+ expect(dummyDispatch).toHaveBeenCalledWith(emptySnapshots());
+ expect(dummyDispatch).toHaveBeenCalledWith(changeSlider(0));
+ });
+});
diff --git a/src/app/__tests__/ButtonContainer.test.tsx b/src/app/__tests__/ButtonContainer.test.tsx
new file mode 100644
index 000000000..2b6b13bf1
--- /dev/null
+++ b/src/app/__tests__/ButtonContainer.test.tsx
@@ -0,0 +1,203 @@
+import React from 'react';
+import { render as rtlRender, screen, fireEvent } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import { TextEncoder } from 'util';
+global.TextEncoder = TextEncoder;
+import ButtonsContainer from '../containers/ButtonsContainer';
+import userEvent from '@testing-library/user-event';
+import { toggleMode, mainSlice } from '../slices/mainSlice';
+import { useDispatch, Provider } from 'react-redux';
+import { configureStore } from '@reduxjs/toolkit';
+
+const customTabs = {
+ 87: {
+ snapshots: [1, 2, 3, 4],
+ hierarchy: {
+ index: 0,
+ name: 1,
+ branch: 0,
+ stateSnapshot: {
+ state: {},
+ children: [
+ {
+ state: { test: 'test' },
+ name: 'App',
+ componentData: { actualDuration: 3.5 },
+ },
+ ],
+ route: {
+ id: 1,
+ url: 'http://localhost:8080/',
+ },
+ },
+ children: [
+ {
+ index: 1,
+ name: 2,
+ branch: 0,
+ stateSnapshot: {
+ state: {},
+ children: [
+ {
+ state: { test: 'test' },
+ name: 'App',
+ componentData: { actualDuration: 3.5 },
+ },
+ ],
+ route: {
+ id: 2,
+ url: 'http://localhost:8080/',
+ },
+ },
+ children: [
+ {
+ index: 2,
+ name: 3,
+ branch: 0,
+ stateSnapshot: {
+ state: {},
+ children: [
+ {
+ state: { test: 'test' },
+ name: 'App',
+ componentData: { actualDuration: 3.5 },
+ },
+ ],
+ route: {
+ id: 3,
+ url: 'http://localhost:8080/',
+ },
+ },
+ children: [
+ {
+ index: 3,
+ name: 4,
+ branch: 0,
+ stateSnapshot: {
+ state: {},
+ children: [
+ {
+ state: { test: 'test' },
+ name: 'App',
+ componentData: { actualDuration: 3.5 },
+ },
+ ],
+ route: {
+ id: 4,
+ url: 'http://localhost:8080/test/',
+ },
+ },
+ children: [],
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ currLocation: {
+ index: 0,
+ name: 1,
+ branch: 0,
+ },
+ sliderIndex: 0,
+ viewIndex: -1,
+ },
+};
+
+const customInitialState = {
+ main: {
+ port: null,
+ currentTab: 87, // Update with your desired value
+ currentTitle: 'test string',
+ tabs: customTabs, // Replace with the actual (testing) tab data
+ currentTabInApp: 'test string',
+ connectionStatus: false,
+ connectRequested: true,
+ },
+};
+
+const customStore = configureStore({
+ reducer: {
+ main: mainSlice.reducer,
+ },
+ preloadedState: customInitialState, // Provide custom initial state
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }),
+});
+
+const render = (component) => rtlRender({component} );
+
+jest.mock('react-redux', () => ({
+ ...jest.requireActual('react-redux'), // Use the actual react-redux module except for the functions you want to mock
+ useDispatch: jest.fn(), // set up a mock function for useDispatch
+}));
+
+//these are needed for the Clicking pause-button toggles locked/unlocked test, as the onClick triggers the exportHandler, which uses the .creatObjectURL and .revokeObjectURL methods, so we declare them as jest functions here
+global.URL.createObjectURL = jest.fn(() => 'https://pdf.com');
+global.URL.revokeObjectURL = jest.fn();
+
+describe('Unit testing for ButtonContainer', () => {
+ const useDispatchMock = (useDispatch as unknown) as jest.Mock; // make the test run
+ const dummyDispatch = jest.fn(); //separate mock function created because we need to explicitly define on line 30 what
+ useDispatchMock.mockReturnValue(dummyDispatch); //exactly useDispatchMock returns (which is a jest.fn())
+ beforeEach;
+
+ const currentTab = customInitialState.main.tabs[customInitialState.main.currentTab];
+
+ beforeEach(() => {
+
+ currentTab.mode = {
+ paused: true,
+ };
+ });
+
+ describe('When button container is loaded', () => {
+ test('it should have 5 buttons', () => {
+ customInitialState.main.connectionStatus = true;
+ render( );
+ expect(screen.getAllByRole('button')).toHaveLength(5);
+ expect(screen.getAllByRole('button')[0]).toHaveTextContent('Locked');
+ expect(screen.getAllByRole('button')[1]).toHaveTextContent('Download');
+ expect(screen.getAllByRole('button')[2]).toHaveTextContent('Upload');
+ expect(screen.getAllByRole('button')[3]).toHaveTextContent('Tutorial');
+ expect(screen.getAllByRole('button')[4]).toHaveTextContent('Reconnect');
+ });
+ });
+
+ describe('When view is unlock', () => {
+ test('Button should show as unlocked', () => {
+ customInitialState.main.connectionStatus = true;
+ currentTab.mode.paused = false;
+ render( );
+ expect(screen.getAllByRole('button')[0]).toHaveTextContent('Unlocked');
+ });
+ });
+
+ describe('When view is lock', () => {
+ test('Button should show as locked', () => {
+ customInitialState.main.connectionStatus = true;
+ currentTab.mode.paused = true;
+ render( );
+ expect(screen.getAllByRole('button')[0]).toHaveTextContent('Locked');
+ });
+ });
+
+ describe('Clicking pause-button toggles locked/unlocked', () => {
+ test('When button is unlocked and it is clicked', async () => {
+ render( );
+ const button = screen.getAllByRole('button')[0];
+ await userEvent.click(button);
+ expect(dummyDispatch).toHaveBeenCalledWith(toggleMode('paused'));
+ });
+ });
+
+ describe('Upload/Download', () => {
+ test('Clicking upload and download buttons', async () => {
+ render( );
+ fireEvent.click(screen.getAllByRole('button')[1]);
+ fireEvent.click(screen.getAllByRole('button')[2]);
+ expect(screen.getAllByRole('button')[1]).toBeInTheDocument();
+ expect(screen.getAllByRole('button')[2]).toBeInTheDocument();
+ });
+ });
+});
diff --git a/src/app/__tests__/ButtonsContainer.test.tsx b/src/app/__tests__/ButtonsContainer.test.tsx
deleted file mode 100644
index f8675e26a..000000000
--- a/src/app/__tests__/ButtonsContainer.test.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable react/jsx-filename-extension */
-import { shallow, configure } from 'enzyme';
-import React from 'react';
-import Adapter from 'enzyme-adapter-react-16';
-import ButtonsContainer from '../containers/ButtonsContainer';
-import { useStoreContext } from '../store';
-import { toggleMode } from '../actions/actions';
-
-configure({ adapter: new (Adapter as any)() });
-
-const state = {
- tabs: {
- 87: {
- snapshots: [1, 2, 3, 4],
- sliderIndex: 0,
- viewIndex: -1,
- mode: {
- paused: false,
- locked: false,
- persist: false,
- },
- },
- },
- currentTab: 87,
-};
-
-const currentTab = state.tabs[state.currentTab];
-
-const dispatch = jest.fn();
-
-jest.mock('../../../node_modules/intro.js/introjs.css', () => jest.fn());
-jest.mock('../store');
-useStoreContext.mockImplementation(() => [state, dispatch]);
-
-let wrapper;
-
-describe('testing the bottom buttons', () => {
- beforeEach(() => {
- wrapper = shallow( );
- dispatch.mockClear();
- useStoreContext.mockClear();
- currentTab.mode = {
- paused: false,
- persist: false,
- };
- });
-
- describe('pause button testing', () => {
- beforeEach(() => {
- wrapper.find('.pause-button').simulate('click');
- });
- test('pause button dispatches upon click', () => {
- expect(dispatch.mock.calls.length).toBe(1);
- });
-
- test('pause button dispatches toggleMode action', () => {
- expect(dispatch.mock.calls[0][0]).toEqual(toggleMode('paused'));
- });
-
- test('pause button displays state', () => {
- expect(wrapper.find('.pause-button').text()).toBe(' Lock');
- state.tabs[state.currentTab].mode.paused = true;
- wrapper = shallow( );
- expect(wrapper.find('.pause-button').text()).toBe(' Unlock');
- });
- });
-
- describe.skip('persist button testing', () => {
- beforeEach(() => {
- wrapper.find('.persist-button').simulate('click');
- });
-
- test('persist button dispatches upon click', () => {
- expect(dispatch.mock.calls.length).toBe(1);
- });
-
- test('persist button dispatches toggleMode action', () => {
- expect(dispatch.mock.calls[0][0]).toEqual(toggleMode('persist'));
- });
-
- test('persist button displays state', () => {
- expect(wrapper.find('.persist-button').text()).toBe(' Persist');
- state.tabs[state.currentTab].mode.persist = true;
- wrapper = shallow( );
- expect(wrapper.find('.persist-button').text()).toBe(' Unpersist');
- });
- });
-});
diff --git a/src/app/__tests__/ComponentMap.test.tsx b/src/app/__tests__/ComponentMap.test.tsx
deleted file mode 100644
index 8123731ad..000000000
--- a/src/app/__tests__/ComponentMap.test.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-/* eslint:disable */
-
-import * as d3 from 'd3'
-
-describe('D3Canvas Testing', ()=> {
- const getCanvas = () => {
- return d3.select('#canvas')
- }
-
- it ('should exist', ()=>{
- expect(getCanvas()).not.toBeNull();
- })
-
-})
-
-describe('D3 Node Testing', ()=> {
- const getNodes = () => {
- return d3.select('g')
- }
-
- it ('should exist', () => {
- expect(getNodes()).not.toBeNull();
- })
-
-
-})
\ No newline at end of file
diff --git a/src/app/__tests__/Diff.test.tsx b/src/app/__tests__/Diff.test.tsx
deleted file mode 100644
index e25218662..000000000
--- a/src/app/__tests__/Diff.test.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/no-var-requires */
-import React from 'react';
-import { configure, shallow } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-import { useStoreContext } from '../store';
-
-const Diff = require('../components/Diff').default;
-
-configure({ adapter: new (Adapter as any)() });
-
-jest.mock('../store');
-
-describe('Unit testing for Diff.jsx', () => {
- let wrapper;
- const props = {
- show: false,
- snapshot: [{
- children: [{
- state: { total: 12, next: 5, operation: null },
- }],
-
- }],
- };
-
- const state = {
- currentTab: 100,
- tabs: { 100: { snapshots: [1, 2, 3, 4], viewIndex: 1, sliderIndex: 1 } },
- };
-
- useStoreContext.mockImplementation(() => [state]);
-
- const delta = { children: {} }; // expect delta to be an obj
- const html = 'html'; // expect html to be a string
- const previous = { state: 'string', children: {} }; // expect previous to be an obj
-
- beforeEach(() => {
- // eslint-disable-next-line react/jsx-props-no-spreading
- wrapper = shallow( );
- });
-
- describe('delta', () => {
- it('delta variable should be an object, with a property children', () => {
- expect(typeof delta).toBe('object');
- expect(delta).toHaveProperty('children');
- });
- });
-
- describe('html', () => {
- it('html variable should be a string', () => {
- expect(typeof html).toBe('string');
- });
- });
-
- describe('previous', () => {
- it('previous variable should be a object', () => {
- expect(previous).toHaveProperty('state');
- expect(previous).toHaveProperty('children');
- expect(typeof previous).toBe('object');
- });
- });
-
- describe('Diff Component', () => {
- it('Check if Diff component is a div', () => {
- expect(wrapper.type()).toEqual('div');
- });
- it('Check if Diff component inner text value is a string', () => {
- expect(typeof wrapper.text()).toEqual('string');
- });
- it('Check if previous and delta is defined Diff should not have text content "No state change detected. Trigger an event to change state"', () => {
- expect(wrapper.textContent).not.toEqual('No state change detected. Trigger an event to change state');
- });
- });
-});
diff --git a/src/app/__tests__/DiffRoute.test.tsx b/src/app/__tests__/DiffRoute.test.tsx
deleted file mode 100644
index 33ac03ab0..000000000
--- a/src/app/__tests__/DiffRoute.test.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/no-var-requires */
-import React from 'react';
-import { configure, shallow } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-import { MemoryRouter as Router, Switch } from 'react-router-dom';
-
-const DiffRoute = require('../components/DiffRoute').default;
-
-const props = {
- snapshot: [{}],
-};
-
-configure({ adapter: new (Adapter as any)() });
-let wrapper;
-
-describe('DiffRoute props', () => {
- it('should have a property called snapshot', () => {
- expect(props).toHaveProperty('snapshot');
- });
- it('props snapshot value should be an array', () => {
- expect(Array.isArray(props.snapshot)).toBe(true);
- });
-});
-
-describe('DiffRoute component', () => {
- beforeEach(() => {
- wrapper = shallow( );
- });
- it('should contain a router component', () => {
- expect(wrapper.find(Router).type()).toEqual(Router);
- });
- it('div tag in Router should have a classname "navbar', () => {
- expect(wrapper.find('.navbar').type()).toBe('div');
- });
- it('router should have a switch component', () => {
- expect(wrapper.find(Switch).type()).toEqual(Switch);
- });
-});
-
-// remaining tests:
-// check if router component has a div with a navlik component
-// check if navlinks go to appropriate routes, and text shows Tree and Raw
-// check if routes in switch have appropriate props
diff --git a/src/app/__tests__/History.test.tsx b/src/app/__tests__/History.test.tsx
deleted file mode 100644
index 34e118c8d..000000000
--- a/src/app/__tests__/History.test.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-/* eslint:disable */
-
-import * as d3 from 'd3';
-
-describe('D3 Canvas Testing', () => {
- const getCanvas = () => d3.select('#canvas');
-
- it('should render', () => {
- expect(getCanvas()).not.toBeNull();
- });
-});
-
-describe('D3 Node Testing', () => {
- const getNodes = () => d3.select('g');
-
- it('should render', () => {
- expect(getNodes()).not.toBeNull();
- });
-});
diff --git a/src/app/__tests__/MainContainer.test.tsx b/src/app/__tests__/MainContainer.test.tsx
index 8a0982ae0..b17bab830 100644
--- a/src/app/__tests__/MainContainer.test.tsx
+++ b/src/app/__tests__/MainContainer.test.tsx
@@ -1,73 +1,227 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/no-empty-function */
-/* eslint-disable @typescript-eslint/no-var-requires */
-/* eslint-disable react/jsx-filename-extension */
-import { shallow, configure } from 'enzyme';
import React from 'react';
-import Adapter from 'enzyme-adapter-react-16';
+import { render, screen } from '@testing-library/react';
+import { Provider } from 'react-redux';
+import { configureStore } from '@reduxjs/toolkit';
+import { MemoryRouter } from 'react-router-dom';
+import '@testing-library/jest-dom';
+
import MainContainer from '../containers/MainContainer';
-import { useStoreContext } from '../store';
+import { mainSlice } from '../slices/mainSlice';
+
+// Mock ResizeObserver
+class ResizeObserverMock {
+ observe() {}
+ unobserve() {}
+ disconnect() {}
+}
-import ActionContainer from '../containers/ActionContainer';
-import StateContainer from '../containers/StateContainer';
-import TravelContainer from '../containers/TravelContainer';
-import ButtonsContainer from '../containers/ButtonsContainer';
-import ErrorContainer from '../containers/ErrorContainer';
+global.ResizeObserver = ResizeObserverMock;
+
+// Mock components that use visx/tooltips
+jest.mock('../components/StateRoute/ComponentMap/ComponentMap', () => {
+ return function MockComponentMap() {
+ return
;
+ };
+});
-const chrome = require('sinon-chrome');
+jest.mock('../containers/ActionContainer', () => {
+ return function MockActionContainer({ snapshots, currLocation }) {
+ return
;
+ };
+});
-configure({ adapter: new (Adapter as any)() });
+jest.mock('../components/StateRoute/StateRoute', () => {
+ return function MockStateRoute() {
+ return
;
+ };
+});
-const state = {
- tabs: {},
- currentTab: null,
+// Mock chrome API
+const mockChrome = {
+ runtime: {
+ connect: jest.fn(() => ({
+ onMessage: {
+ addListener: jest.fn(),
+ hasListener: jest.fn(() => false),
+ removeListener: jest.fn(),
+ },
+ postMessage: jest.fn(),
+ })),
+ onMessage: {
+ addListener: jest.fn(),
+ hasListener: jest.fn(() => false),
+ removeListener: jest.fn(),
+ },
+ },
};
-const dispatch = jest.fn();
-jest.mock('../../../node_modules/intro.js/introjs.css', () => jest.fn());
-jest.mock('../store');
-useStoreContext.mockImplementation(() => [state, dispatch]);
+global.chrome = mockChrome as any;
-let wrapper;
-global.chrome = chrome;
-const port = {
- onMessage: {
- addListener: () => {},
+// Mock proper state hierarchy structure
+const mockStateTree = {
+ index: 0,
+ stateSnapshot: {
+ name: 'Root',
+ children: [
+ {
+ name: 'TestComponent',
+ state: { testData: 'value' },
+ componentData: {
+ props: {},
+ state: null,
+ },
+ children: [],
+ },
+ ],
+ route: {
+ url: '/test',
+ },
},
- onDisconnect: {
- addListener: () => {},
+ children: [],
+};
+
+const mockSnapshots = [
+ {
+ index: 0,
+ stateSnapshot: {
+ name: 'Root',
+ children: [
+ {
+ name: 'TestComponent',
+ state: { testData: 'value' },
+ componentData: {},
+ children: [],
+ },
+ ],
+ route: {
+ url: '/test',
+ },
+ },
},
+];
+
+// Create a mock store with complete structure
+const createMockStore = (initialState = {}) => {
+ return configureStore({
+ reducer: {
+ // @ts-ignore
+ main: mainSlice.reducer,
+ },
+ preloadedState: {
+ main: {
+ currentTab: 1,
+ port: null,
+ connectionStatus: true,
+ currentTitle: 'Test Tab',
+ tabs: {
+ 1: {
+ status: {
+ reactDevToolsInstalled: true,
+ targetPageisaReactApp: true,
+ },
+ axSnapshots: [],
+ currLocation: {
+ index: 0,
+ stateSnapshot: mockStateTree.stateSnapshot,
+ },
+ viewIndex: -1,
+ sliderIndex: 0,
+ snapshots: mockSnapshots,
+ hierarchy: mockStateTree,
+ webMetrics: {},
+ mode: {
+ paused: false,
+ },
+ snapshotDisplay: mockSnapshots,
+ playing: false,
+ intervalId: null,
+ },
+ },
+ ...initialState,
+ },
+ },
+ });
};
-chrome.runtime.connect.returns(port);
-beforeEach(() => {
- wrapper = shallow( );
- useStoreContext.mockClear();
- dispatch.mockClear();
-});
+// Helper function to render with store and router
+const renderWithProvider = (ui: JSX.Element, store = createMockStore()) => {
+ return render(
+
+ {ui}
+ ,
+ );
+};
+
+describe('MainContainer', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
-describe('MainContainer rendering', () => {
- test('With no snapshots, should not render any containers', () => {
- expect(wrapper.find(ErrorContainer).length).toBe(1);
- expect(wrapper.find(ActionContainer).length).toBe(0);
- expect(wrapper.find(StateContainer).length).toBe(0);
- expect(wrapper.find(TravelContainer).length).toBe(0);
- expect(wrapper.find(ButtonsContainer).length).toBe(0);
+ it('renders without crashing', () => {
+ const { container } = renderWithProvider( );
+ expect(container.querySelector('.main-container')).toBeInTheDocument();
});
- test('With snapshots, should render all containers', () => {
- state.currentTab = 87;
- state.tabs[87] = {
- snapshots: [{}],
- status: { contentScriptLaunched: true, reactDevToolsInstalled: true, targetPageisaReactApp: true },
- viewIndex: -1,
- sliderIndex: 0,
- mode: {},
- };
-
- wrapper = shallow( );
- expect(wrapper.find(ActionContainer).length).toBe(1);
- expect(wrapper.find(StateContainer).length).toBe(1);
- expect(wrapper.find(TravelContainer).length).toBe(1);
- expect(wrapper.find(ButtonsContainer).length).toBe(1);
+
+ it('establishes connection with chrome runtime on mount', () => {
+ renderWithProvider( );
+ expect(chrome.runtime.connect).toHaveBeenCalledWith({ name: 'panel' });
+ });
+
+ it('renders ErrorContainer when React DevTools are not installed', () => {
+ const store = createMockStore({
+ tabs: {
+ 1: {
+ status: {
+ reactDevToolsInstalled: false,
+ targetPageisaReactApp: true,
+ },
+ },
+ },
+ });
+
+ renderWithProvider( , store);
+ expect(screen.getByText(/Welcome to Reactime/i)).toBeInTheDocument();
+ });
+
+ it('renders ErrorContainer when page is not a React app', () => {
+ const store = createMockStore({
+ tabs: {
+ 1: {
+ status: {
+ reactDevToolsInstalled: true,
+ targetPageisaReactApp: false,
+ },
+ },
+ },
+ });
+
+ renderWithProvider( , store);
+ expect(screen.getByText(/Welcome to Reactime/i)).toBeInTheDocument();
+ });
+
+ it('renders main content when all conditions are met', () => {
+ const { container } = renderWithProvider( );
+ expect(container.querySelector('.main-container')).toBeInTheDocument();
+ expect(container.querySelector('.bottom-controls')).toBeInTheDocument();
+ });
+
+ it('handles port disconnection', () => {
+ const store = createMockStore();
+ renderWithProvider( , store);
+
+ // Verify that onMessage.addListener was called
+ expect(chrome.runtime.onMessage.addListener).toHaveBeenCalled();
+
+ // Get the last registered listener
+ const lastCall = (chrome.runtime.onMessage.addListener as jest.Mock).mock.calls.length - 1;
+ const handleDisconnect = (chrome.runtime.onMessage.addListener as jest.Mock).mock.calls[
+ lastCall
+ ][0];
+
+ // Call the disconnect handler directly
+ handleDisconnect('portDisconnect');
+
+ // Check if store was updated correctly
+ expect(store.getState().main.connectionStatus).toBeFalsy();
});
});
diff --git a/src/app/__tests__/MainSlider.test.tsx b/src/app/__tests__/MainSlider.test.tsx
deleted file mode 100644
index 3f365f730..000000000
--- a/src/app/__tests__/MainSlider.test.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable react/jsx-props-no-spreading */
-import { shallow, configure } from 'enzyme';
-import React from 'react';
-import Adapter from 'enzyme-adapter-react-16';
-import Slider from 'rc-slider';
-import Tooltip from 'rc-tooltip';
-import MainSlider from '../components/MainSlider';
-
-import { useStoreContext } from '../store';
-
-configure({ adapter: new (Adapter as any)() });
-
-jest.mock('../store');
-// the handle function in MainSlider returns out a Tooltip Component
-const handle = Tooltip;
-
-describe('Unit testing for MainSlider.jsx', () => {
- let wrapper;
- const props = {
- snapshotsLength: 1,
- };
-
- const state = {
- tabs: {
- 100: {
- sliderIndex: 1,
- },
- },
- currentTab: 100,
- };
-
- const dispatch = jest.fn();
- useStoreContext.mockImplementation(() => [state, dispatch]);
-
- beforeEach(() => {
- wrapper = shallow( );
- dispatch.mockClear();
- });
- it('Component should return component from rc-slider library', () => {
- expect(wrapper.type()).toEqual(Slider);
- });
- it('Component should have min, max, value, and handle props', () => {
- expect(wrapper.props()).toHaveProperty('min');
- expect(wrapper.props()).toHaveProperty('max');
- expect(wrapper.props()).toHaveProperty('value');
- expect(wrapper.props()).toHaveProperty('handle');
- });
- it('Prop type tests on component', () => {
- expect(typeof wrapper.prop('min')).toEqual('number');
- expect(typeof wrapper.prop('max')).toEqual('number');
- expect(typeof wrapper.prop('value')).toEqual('number');
- expect(typeof wrapper.prop('handle')).toEqual('function');
- });
-
- describe('Testing for handle functional component', () => {
- // this doesnt work, not sure how to implement yet
- // the handle function should return a Tooltip component
- // eslint-disable-next-line jest/no-test-prefixes
- // eslint-disable-next-line jest/no-disabled-tests
- it.skip('handle prop should return component from rc-tooltip library', () => {
- expect(wrapper.prop('handle')()).toEqual(handle);
- });
- });
-});
diff --git a/src/app/__tests__/Performance.test.tsx b/src/app/__tests__/Performance.test.tsx
new file mode 100644
index 000000000..3daa0c4a7
--- /dev/null
+++ b/src/app/__tests__/Performance.test.tsx
@@ -0,0 +1,264 @@
+import '@testing-library/jest-dom';
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+import { Provider } from 'react-redux';
+import { MemoryRouter } from 'react-router-dom';
+import configureStore from 'redux-mock-store';
+
+import BarGraph from '../components/StateRoute/PerformanceVisx/BarGraph';
+import PerformanceVisx from '../components/StateRoute/PerformanceVisx/PerformanceVisx';
+
+// Mock ResizeObserver
+class ResizeObserver {
+ observe() {}
+ unobserve() {}
+ disconnect() {}
+}
+
+// Mock VisxTooltip Portal
+jest.mock('@visx/tooltip', () => ({
+ ...jest.requireActual('@visx/tooltip'),
+ useTooltipInPortal: () => ({
+ tooltipLeft: 0,
+ tooltipTop: 0,
+ tooltipData: null,
+ TooltipInPortal: ({ children }) => children,
+ containerRef: { current: null },
+ }),
+}));
+
+// Mock window.ResizeObserver
+window.ResizeObserver = ResizeObserver;
+
+// Mock createPortal since JSDOM doesn't support it
+jest.mock('react-dom', () => ({
+ ...jest.requireActual('react-dom'),
+ createPortal: (node) => node,
+}));
+
+// Mock SVG elements that JSDOM doesn't support
+const createElementNSOrig = global.document.createElementNS;
+global.document.createElementNS = function (namespaceURI, qualifiedName) {
+ if (namespaceURI === 'http://www.w3.org/2000/svg' && qualifiedName === 'svg') {
+ const element = createElementNSOrig.apply(this, arguments);
+ element.createSVGRect = function () {};
+ return element;
+ }
+ return createElementNSOrig.apply(this, arguments);
+};
+
+// Mock getComputedStyle for SVG elements
+window.getComputedStyle = (element) => {
+ // Create an object with string index signatures
+ const cssProperties = Array.from({ length: 1000 }).reduce<{ [key: string]: string }>(
+ (acc, _, index) => {
+ acc[index.toString()] = '';
+ return acc;
+ },
+ {},
+ );
+
+ const cssStyleDeclaration: CSSStyleDeclaration = {
+ getPropertyValue: (prop: string) => '',
+ item: (index: number) => '',
+ removeProperty: (property: string) => '',
+ setProperty: (property: string, value: string) => {},
+ parentRule: null,
+ length: 0,
+ [Symbol.iterator]: function* () {},
+ ...cssProperties,
+ } as CSSStyleDeclaration;
+
+ return cssStyleDeclaration;
+};
+
+// Suppress specific console warnings
+const originalError = console.error;
+console.error = (...args) => {
+ if (args[0].includes('Warning: ReactDOM.render is no longer supported')) {
+ return;
+ }
+ originalError.call(console, ...args);
+};
+
+const mockStore = configureStore([]);
+
+// Test fixtures
+const mockBarGraphProps = {
+ width: 800,
+ height: 600,
+ data: {
+ barStack: [
+ {
+ snapshotId: 'snapshot1',
+ 'Component-1': 100,
+ 'Component-2': 150,
+ },
+ {
+ snapshotId: 'snapshot2',
+ 'Component-1': 120,
+ 'Component-2': 140,
+ },
+ ],
+ componentData: {
+ 'Component-1': {
+ stateType: 'stateless',
+ renderFrequency: 2,
+ totalRenderTime: 220,
+ rtid: 'rt1',
+ information: {},
+ },
+ 'Component-2': {
+ stateType: 'stateful',
+ renderFrequency: 2,
+ totalRenderTime: 290,
+ rtid: 'rt2',
+ information: {},
+ },
+ },
+ maxTotalRender: 290,
+ },
+ comparison: [],
+ setRoute: jest.fn(),
+ allRoutes: ['/home', '/about'],
+ filteredSnapshots: [
+ {
+ snapshotId: 'snapshot1',
+ 'Component-1': 100,
+ 'Component-2': 150,
+ },
+ {
+ snapshotId: 'snapshot2',
+ 'Component-1': 120,
+ 'Component-2': 140,
+ },
+ ],
+ setSnapshot: jest.fn(),
+ snapshot: 'All Snapshots',
+};
+
+const mockPerformanceVisxProps = {
+ width: 800,
+ height: 600,
+ snapshots: [
+ {
+ name: 'Root',
+ branch: '1',
+ route: { url: 'http://localhost:3000/home' },
+ children: [
+ {
+ name: 'Component1',
+ componentData: {
+ actualDuration: '100.5',
+ props: { test: 'prop' },
+ },
+ children: [],
+ rtid: 'rt1',
+ state: 'stateless',
+ },
+ ],
+ },
+ ],
+ hierarchy: {
+ name: 'Root',
+ branch: '1',
+ children: [],
+ },
+};
+
+const mockReduxState = {
+ main: {
+ tabs: {
+ 0: { title: 'Test Tab' },
+ },
+ currentTab: 0,
+ currentTabInApp: 'performance',
+ },
+};
+
+describe('Performance Components', () => {
+ let store;
+
+ beforeEach(() => {
+ store = mockStore(mockReduxState);
+ Storage.prototype.getItem = jest.fn(() => null);
+ Storage.prototype.setItem = jest.fn();
+ // Clear mock calls before each test
+ mockBarGraphProps.setSnapshot.mockClear();
+ mockBarGraphProps.setRoute.mockClear();
+ });
+
+ describe('BarGraph Component', () => {
+ const renderBarGraph = () => {
+ return render(
+
+ {/* @ts-ignore */}
+
+ ,
+ );
+ };
+
+ it('renders without crashing', () => {
+ const { container } = renderBarGraph();
+ expect(screen.getByText('Route:')).toBeInTheDocument();
+ expect(screen.getByText('Snapshot:')).toBeInTheDocument();
+ expect(container.querySelector('svg')).toBeInTheDocument();
+ });
+
+ it('displays correct axis labels', () => {
+ renderBarGraph();
+ expect(screen.getByText('Rendering Time (ms)')).toBeInTheDocument();
+ expect(screen.getByText('Snapshot ID')).toBeInTheDocument();
+ });
+
+ it('handles route selection', () => {
+ renderBarGraph();
+ const routeSelect = screen.getByLabelText('Route:');
+ fireEvent.change(routeSelect, { target: { value: '/home' } });
+ expect(mockBarGraphProps.setRoute).toHaveBeenCalledWith('/home');
+ });
+
+ it('handles snapshot selection', () => {
+ renderBarGraph();
+ const snapshotSelect = screen.getByLabelText('Snapshot:');
+ fireEvent.change(snapshotSelect, { target: { value: 'snapshot1' } });
+ expect(mockBarGraphProps.setSnapshot).toHaveBeenCalledWith('snapshot1');
+ expect(mockBarGraphProps.setSnapshot).toHaveBeenCalledTimes(1);
+ });
+
+ it('renders correct number of bars', () => {
+ const { container } = renderBarGraph();
+ const bars = container.querySelectorAll('rect[width]');
+ // Each snapshot has 2 components, so we expect 4 bars total
+ expect(bars.length).toBe(5);
+ });
+ });
+
+ describe('PerformanceVisx Component', () => {
+ const renderPerformanceVisx = () => {
+ return render(
+
+
+
+
+ ,
+ );
+ };
+
+ it('renders without crashing', () => {
+ const { container } = renderPerformanceVisx();
+ expect(container.querySelector('svg')).toBeInTheDocument();
+ });
+
+ it('dispatches setCurrentTabInApp on mount', () => {
+ renderPerformanceVisx();
+ const actions = store.getActions();
+ expect(actions).toEqual([{ type: 'main/setCurrentTabInApp', payload: 'performance' }]);
+ });
+
+ it('processes route data correctly', () => {
+ renderPerformanceVisx();
+ expect(screen.getByText('/home')).toBeInTheDocument();
+ });
+ });
+});
diff --git a/src/app/__tests__/RouteDescription.test.tsx b/src/app/__tests__/RouteDescription.test.tsx
deleted file mode 100644
index 9e2b7711b..000000000
--- a/src/app/__tests__/RouteDescription.test.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable react/jsx-filename-extension */
-
-import React from 'react';
-import { shallow, configure, render } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-import Action from '../components/Action';
-import RouteDescription from '../components/RouteDescription';
-
-configure({ adapter: new (Adapter as any)() });
-
-describe('Unit testing RouteDescription', () => {
- const actionsArr: JSX.Element[] = [];
-
- actionsArr.push(
- null}
- sliderIndex={0}
- handleOnkeyDown={(e, i) => null}
- viewIndex={undefined}
- isCurrIndex={false}
- routePath="http://localhost:3000/home"
- />,
- );
-
- actionsArr.push(
- null}
- sliderIndex={0}
- handleOnkeyDown={(e, i) => null}
- viewIndex={undefined}
- isCurrIndex={false}
- routePath="http://localhost:3000/home"
- />,
- );
-
- const wrapper = shallow( );
-
- test('Renders the correct number of Action components', () => {
- expect(wrapper.find(Action).length).toBe(2);
- });
-
- test('Renders a single ".route" class', () => {
- expect(wrapper.find('.route').length).toBe(1);
- });
-
- test('Renders an h3 tag with the correct pathname "Route: "', () => {
- expect(wrapper.find('h3').text()).toBe('Route: /home');
- });
-});
diff --git a/src/app/__tests__/StateContainer.test.tsx b/src/app/__tests__/StateContainer.test.tsx
new file mode 100644
index 000000000..ca91d5b9d
--- /dev/null
+++ b/src/app/__tests__/StateContainer.test.tsx
@@ -0,0 +1,265 @@
+// State.test.tsx
+import React from 'react';
+import { render, screen, fireEvent } from '@testing-library/react';
+import { Provider } from 'react-redux';
+import { configureStore } from '@reduxjs/toolkit';
+import { MemoryRouter, Route, Routes } from 'react-router-dom';
+import '@testing-library/jest-dom';
+
+import StateRoute from '../components/StateRoute/StateRoute';
+import StateContainer from '../containers/StateContainer';
+import { mainSlice } from '../slices/mainSlice';
+
+// Mock ResizeObserver
+class ResizeObserverMock {
+ observe() {}
+ unobserve() {}
+ disconnect() {}
+}
+
+global.ResizeObserver = ResizeObserverMock;
+
+// Mock child components
+jest.mock('../components/StateRoute/Tree', () => () => (
+ Tree Component
+));
+
+jest.mock('../components/StateRoute/ComponentMap/ComponentMap', () => () => (
+ Component Map
+));
+
+jest.mock('../components/StateRoute/PerformanceVisx/PerformanceVisx', () => () => (
+ Performance Component
+));
+
+jest.mock('../components/StateRoute/WebMetrics/WebMetricsContainer', () => () => (
+ Web Metrics Component
+));
+
+jest.mock('../components/StateRoute/AxMap/AxContainer', () => () => (
+ Ax Container
+));
+
+jest.mock('../components/StateRoute/History', () => ({
+ default: () => History Component
,
+}));
+
+// Mock StateRoute with proper routing and navigation
+jest.mock('../components/StateRoute/StateRoute', () => {
+ const { Link, useLocation } = require('react-router-dom');
+
+ return function MockStateRoute({ hierarchy }) {
+ const location = useLocation();
+
+ return (
+
+
+
+ Map
+
+
+ History
+
+
+ Performance
+
+
+ Web Metrics
+
+
+ Tree
+
+
+ Accessibility
+
+
+
+
+ {location.pathname === '/accessibility' && (
+ <>
+
+ A Note to Developers: Reactime is using the Chrome Debugger API in order to grab the
+ Accessibility Tree. Enabling this option will allow you to record Accessibility Tree
+ snapshots, but will result in the Chrome browser notifying you that the Chrome
+ Debugger has started.
+
+
+
+ Enable
+
+
Ax Container
+ >
+ )}
+ {location.pathname === '/' && hierarchy && (
+
Component Map
+ )}
+ {location.pathname === '/history' && (
+
History Component
+ )}
+ {location.pathname === '/performance' && (
+
Performance Component
+ )}
+
+
+ );
+ };
+});
+
+// Mock ParentSize component
+jest.mock('@visx/responsive', () => ({
+ ParentSize: ({ children }) => children({ width: 100, height: 100 }),
+}));
+
+const createMockStore = (initialState = {}) => {
+ return configureStore({
+ reducer: {
+ main: mainSlice.reducer,
+ },
+ preloadedState: {
+ main: {
+ tabs: [
+ {
+ hierarchy: {},
+ sliderIndex: 0,
+ viewIndex: 0,
+ },
+ ],
+ currentTab: 0,
+ // @ts-ignore
+ port: {
+ postMessage: jest.fn(),
+ },
+ ...initialState,
+ },
+ },
+ });
+};
+
+afterEach(() => {
+ jest.clearAllMocks();
+});
+
+describe('State Components', () => {
+ const defaultProps = {
+ axSnapshots: [],
+ snapshot: {},
+ hierarchy: {},
+ snapshots: [],
+ viewIndex: 0,
+ webMetrics: {},
+ currLocation: { stateSnapshot: {} },
+ };
+
+ describe('StateRoute Component', () => {
+ const renderStateRoute = (props = {}, initialState = {}, initialPath = '/') => {
+ const store = createMockStore(initialState);
+ return render(
+
+
+
+ {/* @ts-ignore */}
+ } />
+
+
+ ,
+ );
+ };
+
+ it('renders navigation links correctly', () => {
+ renderStateRoute();
+ expect(screen.getByRole('link', { name: /map/i })).toBeInTheDocument();
+ expect(screen.getByRole('link', { name: /history/i })).toBeInTheDocument();
+ expect(screen.getByRole('link', { name: /performance/i })).toBeInTheDocument();
+ expect(screen.getByRole('link', { name: /web metrics/i })).toBeInTheDocument();
+ expect(screen.getByRole('link', { name: /tree/i })).toBeInTheDocument();
+ expect(screen.getByRole('link', { name: /accessibility/i })).toBeInTheDocument();
+ });
+
+ it('toggles accessibility tree view when enable radio is clicked', () => {
+ renderStateRoute({}, { port: { postMessage: jest.fn() } }, '/accessibility');
+
+ // Check initial state
+ expect(screen.getByText(/a note to developers/i)).toBeInTheDocument();
+
+ // Find and click enable radio button
+ const enableRadio = screen.getByRole('radio', { name: /enable/i });
+ fireEvent.click(enableRadio);
+
+ // Verify the accessibility container is shown
+ expect(screen.getByTestId('mock-ax-container')).toBeInTheDocument();
+ });
+
+ it('renders component map when hierarchy is provided', () => {
+ renderStateRoute({
+ hierarchy: { some: 'data' },
+ currLocation: { stateSnapshot: { some: 'data' } },
+ });
+
+ expect(screen.getByTestId('mock-component-map')).toBeInTheDocument();
+ });
+
+ it('handles route changes correctly', () => {
+ renderStateRoute({
+ hierarchy: { some: 'data' },
+ });
+
+ const historyLink = screen.getByRole('link', { name: /history/i });
+ fireEvent.click(historyLink);
+ expect(screen.getByTestId('mock-history')).toBeInTheDocument();
+
+ const performanceLink = screen.getByRole('link', { name: /performance/i });
+ fireEvent.click(performanceLink);
+ expect(screen.getByTestId('mock-performance')).toBeInTheDocument();
+ });
+ });
+
+ describe('StateContainer Component', () => {
+ const renderStateContainer = (props = {}) => {
+ const store = createMockStore();
+ return render(
+
+
+ {/* @ts-ignore */}
+
+
+ ,
+ );
+ };
+
+ it('renders without crashing', () => {
+ renderStateContainer();
+ expect(screen.getByTestId('mock-state-route')).toBeInTheDocument();
+ });
+
+ it('renders structural navbar container', () => {
+ renderStateContainer();
+ expect(document.querySelector('.main-navbar-container--structural')).toBeInTheDocument();
+ });
+
+ it('passes props correctly to StateRoute', () => {
+ const testProps = {
+ snapshot: { test: 'snapshot' },
+ hierarchy: { test: 'hierarchy' },
+ snapshots: [{ test: 'snapshots' }],
+ viewIndex: 1,
+ webMetrics: { test: 'metrics' },
+ currLocation: { test: 'location' },
+ axSnapshots: [{ test: 'ax' }],
+ };
+
+ renderStateContainer(testProps);
+ expect(screen.getByTestId('mock-state-route')).toBeInTheDocument();
+ });
+
+ it('handles nested routes correctly', () => {
+ renderStateContainer();
+ expect(screen.getByTestId('mock-state-route')).toBeInTheDocument();
+ });
+ });
+});
diff --git a/src/app/__tests__/SwitchApp.test.tsx b/src/app/__tests__/SwitchApp.test.tsx
deleted file mode 100644
index 98564ea9d..000000000
--- a/src/app/__tests__/SwitchApp.test.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import React from 'react';
-import Select from 'react-select';
-import { configure, shallow } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-import SwitchApp from '../components/SwitchApp';
-
-import { useStoreContext } from '../store';
-
-configure({ adapter: new (Adapter as any)() });
-
-jest.mock('../store');
-
-describe('Unit testing for SwitchApp.jsx', () => {
- let wrapper;
-
- const state = {
- currentTab: 100,
- tabs: {
- 100: {
- snapshots: [1, 2, 3, 4], viewIndex: 1, sliderIndex: 1, title: 'component',
- },
- },
- };
- const dropdownCurrTabLabel = {
- value: 100,
- label: 'component',
- };
- // mockImplementation creates a mock function call
- const dispatch = jest.fn();
-
- // mockImplementation creates a mock state
- useStoreContext.mockImplementation(() => [state, dispatch]);
-
- beforeEach(() => {
- wrapper = shallow( );
- dispatch.mockClear();
- });
-
- describe('SwitchApp Component', () => {
- beforeEach(() => {
- wrapper.find('.tab-select-container').simulate('change', {});
- });
- it('SwitchApp component returns from react-select library', () => {
- expect(wrapper.find('.tab-select-container').type()).toEqual(Select);
- expect(wrapper.find('.tab-select-container').props().className).toBe('tab-select-container');
- expect(wrapper.find('.tab-select-container').props().value).toEqual(dropdownCurrTabLabel);
- });
- it('OnChange should run dispatch function', () => {
- expect(dispatch.mock.calls.length).toBe(1);
- });
- it('options prop should be an array', () => {
- expect(Array.isArray(wrapper.find('.tab-select-container').props().options)).toBeTruthy();
- expect(wrapper.find('.tab-select-container').props().options[0]).toHaveProperty('value');
- expect(wrapper.find('.tab-select-container').props().options[0]).toHaveProperty('label');
- });
- });
-
- describe('dropdownCurrTabLabel', () => {
- it('should have properties value and label', () => {
- expect(dropdownCurrTabLabel).toHaveProperty('value');
- expect(dropdownCurrTabLabel).toHaveProperty('label');
- });
- });
-
- describe('state', () => {
- it('currentTab value should be a number', () => {
- expect(typeof state.currentTab).toEqual('number');
- });
- it('tabs value should be an object', () => {
- expect(typeof state.tabs).toEqual('object');
- });
- });
-});
diff --git a/src/app/__tests__/TimeTravel.test.tsx b/src/app/__tests__/TimeTravel.test.tsx
new file mode 100644
index 000000000..145e86aeb
--- /dev/null
+++ b/src/app/__tests__/TimeTravel.test.tsx
@@ -0,0 +1,382 @@
+import React from 'react';
+import { render as rtlRender, screen, fireEvent } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import { Provider } from 'react-redux';
+import { store } from '../store';
+import { useDispatch } from 'react-redux';
+import { changeView, changeSlider } from '../slices/mainSlice';
+import { configureStore } from '@reduxjs/toolkit';
+import { mainSlice } from '../slices/mainSlice';
+
+import Action from '../components/Actions/Action';
+import RouteDescription from '../components/Actions/RouteDescription';
+import VerticalSlider from '../components/TimeTravel/VerticalSlider';
+
+
+// Mock react-redux
+jest.mock('react-redux', () => ({
+ ...jest.requireActual('react-redux'),
+ useDispatch: jest.fn(),
+}));
+
+// Helper function for redux wrapped renders
+const render = (component) => rtlRender({component} );
+
+// RouteDescription Component Tests
+describe('RouteDescription Component', () => {
+ // Mock the vertical slider component
+ jest.mock('../components/TimeTravel/VerticalSlider.tsx', () => {
+ return function MockVerticalSlider({ snapshots }) {
+ return {snapshots.length} snapshots
;
+ };
+ });
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test('renders route path correctly', () => {
+ const mockActions = [
+ ,
+ ];
+
+ // Create store with initial state
+ const mockStore = configureStore({
+ reducer: {
+ main: mainSlice.reducer,
+ },
+ preloadedState: {
+ main: {
+ port: null,
+ currentTab: 0,
+ currentTitle: 'No Target',
+ tabs: {
+ 0: {
+ currLocation: {
+ index: 0,
+ stateSnapshot: {},
+ },
+ hierarchy: {},
+ sliderIndex: 0,
+ viewIndex: 0,
+ snapshots: [],
+ playing: false,
+ intervalId: null,
+ mode: { paused: false },
+ status: {
+ reactDevToolsInstalled: true,
+ targetPageisaReactApp: true,
+ },
+ },
+ },
+ currentTabInApp: null,
+ connectionStatus: true,
+ connectRequested: true,
+ },
+ },
+ });
+
+ render(
+
+
+ ,
+ );
+
+ // Check if the route path is displayed correctly
+ expect(screen.getByText('Route: /test-route')).toBeInTheDocument();
+ });
+
+ test('renders actions container with correct height', () => {
+ // Create multiple actions to test height calculation
+ const mockActions = [
+ ,
+ ,
+ ];
+
+ // Create store with initial state
+ const mockStore = configureStore({
+ reducer: {
+ main: mainSlice.reducer,
+ },
+ preloadedState: {
+ main: {
+ port: null,
+ currentTab: 0,
+ currentTitle: 'No Target',
+ tabs: {
+ 0: {
+ currLocation: {
+ index: 0,
+ stateSnapshot: {},
+ },
+ hierarchy: {},
+ sliderIndex: 0,
+ viewIndex: 0,
+ snapshots: [],
+ playing: false,
+ intervalId: null,
+ mode: { paused: false },
+ status: {
+ reactDevToolsInstalled: true,
+ targetPageisaReactApp: true,
+ },
+ },
+ },
+ currentTabInApp: null,
+ connectionStatus: true,
+ connectRequested: true,
+ },
+ },
+ });
+
+ render(
+
+
+ ,
+ );
+
+ // Get the route content container
+ const routeContent = document.querySelector('.route-content');
+
+ // Check if height is calculated correctly (40.5px * number of actions)
+ expect(routeContent).toHaveStyle({ height: '81px' }); // 40.5 * 2 = 81
+ });
+});
+
+// Action Component Tests
+describe('Action Component', () => {
+ // @ts-ignore
+ const useDispatchMock = useDispatch as jest.Mock;
+ const dummyDispatch = jest.fn();
+ useDispatchMock.mockReturnValue(dummyDispatch);
+
+ const props = {
+ key: 'actions2',
+ selected: true,
+ last: false,
+ index: 2,
+ sliderIndex: 2,
+ isCurrIndex: false,
+ routePath: '',
+ displayName: '3.0',
+ componentName: 'App',
+ logChangedState: jest.fn(),
+ componentData: {
+ actualDuration: 3.5,
+ },
+ state: { test: 'test' },
+ viewIndex: 2,
+ handleOnkeyDown: jest.fn(),
+ };
+
+ beforeEach(() => {
+ props.isCurrIndex = false;
+ props.componentData = { actualDuration: 3.5 };
+ });
+
+ test('Action snapshot should be shown as Snapshot: 3.0', () => {
+ render( );
+ expect(screen.getByPlaceholderText('Snapshot: 3.0')).toBeInTheDocument();
+ });
+
+ test('Two buttons with Time and Jump when not at current snapshot', () => {
+ props.isCurrIndex = false;
+ render( );
+ expect(screen.getAllByRole('button')).toHaveLength(2);
+ expect(screen.getAllByRole('button')[0]).toHaveTextContent('+00:03.50');
+ expect(screen.getAllByRole('button')[1]).toHaveTextContent('Jump');
+ });
+
+ test('Two buttons with Time and Current when at current snapshot', () => {
+ props.isCurrIndex = true;
+ render( );
+ expect(screen.getAllByRole('button')).toHaveLength(1);
+ expect(screen.getAllByRole('button')[0]).toHaveTextContent('Current');
+ });
+
+ test('When there is no duration data', () => {
+ // @ts-ignore
+ props.componentData = undefined;
+ render( );
+ expect(screen.getAllByRole('button')[0]).toHaveTextContent('NO TIME');
+ });
+
+ test('When actualDuration exceeds 60, time should be formatted correctly', () => {
+ props.componentData.actualDuration = 75;
+ render( );
+ expect(screen.getAllByRole('button')[0]).toHaveTextContent('+01:15.00');
+ });
+
+ test('Clicking the snapshot should trigger onClick', () => {
+ render( );
+ fireEvent.click(screen.getByRole('presentation'));
+ expect(dummyDispatch).toHaveBeenCalledWith(changeView(props.index));
+ });
+
+ test('Clicking Jump button should trigger changeSlider and changeView', () => {
+ render( );
+ fireEvent.click(screen.getAllByRole('button')[1]);
+ expect(dummyDispatch).toHaveBeenCalledWith(changeSlider(props.index));
+ expect(dummyDispatch).toHaveBeenCalledWith(changeView(props.index));
+ });
+});
+
+// VerticalSlider Component Tests
+describe('VerticalSlider Component', () => {
+ const useDispatchMock = jest.fn();
+ const dummyDispatch = jest.fn();
+
+ // Define the mock state
+ const mockState = {
+ main: {
+ tabs: {
+ 0: {
+ currLocation: { index: 1 },
+ },
+ },
+ currentTab: 0,
+ },
+ };
+
+ const mockStore = configureStore({
+ reducer: {
+ // @ts-ignore
+ main: mainSlice.reducer,
+ },
+ preloadedState: mockState,
+ });
+
+ // Helper function to create store with custom state
+ const createMockStore = (state: any) =>
+ configureStore({
+ reducer: {
+ // @ts-ignore
+ main: mainSlice.reducer,
+ },
+ preloadedState: state,
+ });
+
+ const mockSnapshots = [{ props: { index: 0 } }, { props: { index: 1 } }, { props: { index: 2 } }];
+
+ beforeEach(() => {
+ useDispatchMock.mockClear();
+ useDispatchMock.mockReturnValue(dummyDispatch);
+ });
+
+ test('renders slider with correct min and max values', () => {
+ render(
+
+
+ ,
+ );
+
+ const slider = screen.getByRole('slider');
+ expect(slider).toHaveAttribute('aria-valuemin', '0');
+ expect(slider).toHaveAttribute('aria-valuemax', '2');
+ });
+
+ test('updates slider index when currLocation changes', () => {
+ const { rerender } = render(
+
+
+ ,
+ );
+
+ const updatedState = {
+ ...mockState,
+ main: {
+ ...mockState.main,
+ tabs: {
+ 0: {
+ currLocation: { index: 2 },
+ },
+ },
+ },
+ };
+
+ rerender(
+
+
+ ,
+ );
+
+ const slider = screen.getByRole('slider');
+ expect(slider).toHaveAttribute('aria-valuenow', '2');
+ });
+
+ test('handles empty snapshots array', () => {
+ render(
+
+
+ ,
+ );
+
+ const slider = screen.getByRole('slider');
+ expect(slider).toHaveAttribute('aria-valuemin', '0');
+ expect(slider).toHaveAttribute('aria-valuemax', '-1');
+ expect(slider).not.toHaveAttribute('aria-valuenow');
+ });
+
+ test('maintains slider position within bounds', () => {
+ const outOfBoundsState = {
+ ...mockState,
+ main: {
+ ...mockState.main,
+ tabs: {
+ 0: {
+ currLocation: { index: 999 }, // intentionally out of bounds
+ },
+ },
+ },
+ };
+
+ render(
+
+
+ ,
+ );
+
+ const slider = screen.getByRole('slider');
+ // It seems the component defaults to 0 for out-of-bounds values
+ expect(slider).toHaveAttribute('aria-valuenow', '0');
+ });
+});
diff --git a/src/app/__tests__/TravelContainer.test.tsx b/src/app/__tests__/TravelContainer.test.tsx
index 14ac57eb4..6e5e791e2 100644
--- a/src/app/__tests__/TravelContainer.test.tsx
+++ b/src/app/__tests__/TravelContainer.test.tsx
@@ -1,85 +1,167 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable react/jsx-filename-extension */
-import { shallow, configure } from 'enzyme';
import React from 'react';
-import Adapter from 'enzyme-adapter-react-16';
+import { render, screen, fireEvent } from '@testing-library/react';
+import { Provider } from 'react-redux';
+import '@testing-library/jest-dom';
+
+import configureStore from 'redux-mock-store';
import TravelContainer from '../containers/TravelContainer';
-import MainSlider from '../components/MainSlider';
-import Dropdown from '../components/Dropdown';
-import { useStoreContext } from '../store';
-import { moveBackward, moveForward } from '../actions/actions';
-
-configure({ adapter: new (Adapter as any)() });
-
-const state = {
- tabs: {
- 87: {
- snapshots: [1, 2, 3, 4],
- sliderIndex: 2,
- playing: true,
- },
- },
- currentTab: 87,
-};
-
-const dispatch = jest.fn();
-jest.mock('../store');
-useStoreContext.mockImplementation(() => [state, dispatch]);
-
-let wrapper;
-
-beforeEach(() => {
- wrapper = shallow( );
- useStoreContext.mockClear();
- dispatch.mockClear();
-});
+import { playForward, pause, startPlaying, resetSlider, changeSlider } from '../slices/mainSlice';
-describe(' rendering', () => {
- test('should render three buttons', () => {
- expect(wrapper.find('button')).toHaveLength(3);
- });
- test('should render one MainSlider', () => {
- expect(wrapper.find(MainSlider)).toHaveLength(1);
- });
- test('should render one Dropdown', () => {
- expect(wrapper.find(Dropdown)).toHaveLength(1);
+const mockStore = configureStore([]);
+
+describe('TravelContainer', () => {
+ let store;
+
+ beforeEach(() => {
+ store = mockStore({
+ main: {
+ tabs: {
+ tab1: {
+ sliderIndex: 0,
+ playing: false,
+ currLocation: null,
+ },
+ },
+ currentTab: 'tab1',
+ },
+ });
+
+ store.dispatch = jest.fn();
});
-});
-describe('testing the backward-button', () => {
- test('should dispatch action upon click', () => {
- wrapper.find('.backward-button').simulate('click');
- expect(dispatch.mock.calls.length).toBe(1);
+ const renderComponent = (props = {}) => {
+ const defaultProps = {
+ snapshotsLength: 5,
+ };
+
+ return render(
+
+
+ ,
+ );
+ };
+
+ it('renders play button and dropdown', () => {
+ renderComponent();
+
+ expect(screen.getByRole('button')).toBeInTheDocument();
+ expect(screen.getByText('Play')).toBeInTheDocument();
});
- test('should send moveBackward action to dispatch', () => {
- wrapper.find('.backward-button').simulate('click');
- expect(dispatch.mock.calls[0][0]).toEqual(moveBackward());
+ it('changes play button text and icon when clicked', () => {
+ renderComponent();
+
+ const playButton = screen.getByRole('button');
+ fireEvent.click(playButton);
+
+ // Should dispatch startPlaying action
+ expect(store.dispatch).toHaveBeenCalledWith(
+ expect.objectContaining({
+ type: startPlaying.type,
+ }),
+ );
});
-});
-describe('testing the forward-button', () => {
- test('should dispatch action upon click', () => {
- wrapper.find('.forward-button').simulate('click');
- expect(dispatch.mock.calls.length).toBe(1);
+ it('resets slider when playing from last snapshot', () => {
+ store = mockStore({
+ main: {
+ tabs: {
+ tab1: {
+ sliderIndex: 4, // Last index (snapshotsLength - 1)
+ playing: false,
+ currLocation: null,
+ },
+ },
+ currentTab: 'tab1',
+ },
+ });
+ store.dispatch = jest.fn();
+
+ renderComponent();
+
+ const playButton = screen.getByRole('button');
+ fireEvent.click(playButton);
+
+ // Should dispatch resetSlider action
+ expect(store.dispatch).toHaveBeenCalledWith(
+ expect.objectContaining({
+ type: resetSlider.type,
+ }),
+ );
});
- test('should send moveforward action to dispatch', () => {
- wrapper.find('.forward-button').simulate('click');
- expect(dispatch.mock.calls[0][0]).toEqual(moveForward());
+ it('pauses playback when play button is clicked while playing', () => {
+ store = mockStore({
+ main: {
+ tabs: {
+ tab1: {
+ sliderIndex: 2,
+ playing: true,
+ currLocation: null,
+ },
+ },
+ currentTab: 'tab1',
+ },
+ });
+ store.dispatch = jest.fn();
+
+ renderComponent();
+
+ const pauseButton = screen.getByRole('button');
+ fireEvent.click(pauseButton);
+
+ // Should dispatch pause action
+ expect(store.dispatch).toHaveBeenCalledWith(
+ expect.objectContaining({
+ type: pause.type,
+ }),
+ );
});
-});
-describe('testing the play-button', () => {
- test("should display 'pause' if playing is true", () => {
- state.tabs[87].playing = true;
- wrapper = shallow( );
- expect(wrapper.find('.play-button').text()).toBe('Pause');
+ it('handles speed change from dropdown', () => {
+ renderComponent();
+
+ // Find and click the dropdown
+ const dropdown = screen.getByRole('combobox');
+ fireEvent.keyDown(dropdown, { key: 'ArrowDown' });
+
+ // Select a different speed
+ const speedOption = screen.getByText('0.5x');
+ fireEvent.click(speedOption);
+
+ // The selected speed should be updated in the component state
+ expect(screen.getByText('0.5x')).toBeInTheDocument();
});
- test('should display play if playing is false', () => {
- state.tabs[87].playing = false;
- wrapper = shallow( );
- expect(wrapper.find('.play-button').text()).toBe('Play');
+ it('updates slider index when playing forward', () => {
+ const { rerender } = renderComponent();
+
+ // Simulate playing forward
+ store.dispatch(playForward(true));
+ store.dispatch(changeSlider(1));
+
+ // Update store state
+ store = mockStore({
+ main: {
+ tabs: {
+ tab1: {
+ sliderIndex: 1,
+ playing: true,
+ currLocation: null,
+ },
+ },
+ currentTab: 'tab1',
+ },
+ });
+
+ // Rerender with new store state
+ rerender(
+
+
+ ,
+ );
+
+ // Verify the slider index was updated
+ expect(store.getState().main.tabs.tab1.sliderIndex).toBe(1);
});
});
diff --git a/src/app/__tests__/Tutorial.test.tsx b/src/app/__tests__/Tutorial.test.tsx
new file mode 100644
index 000000000..662e2f938
--- /dev/null
+++ b/src/app/__tests__/Tutorial.test.tsx
@@ -0,0 +1,175 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import * as React from 'react';
+
+import Tutorial from '../components/Buttons/Tutorial';
+import { setCurrentTabInApp, tutorialSaveSeriesToggle } from '../slices/mainSlice';
+
+// Create a mock for updateStepElement
+const mockUpdateStepElement = jest.fn();
+
+// Keep track of the latest Steps instance
+let currentStepsInstance: any = null;
+
+// Mock the intro.js-react package
+jest.mock('intro.js-react', () => {
+ return {
+ Steps: class MockSteps extends React.Component {
+ constructor(props: any) {
+ super(props);
+ // @ts-ignore
+ this.updateStepElement = mockUpdateStepElement;
+ // Store the instance so we can access it in tests
+ currentStepsInstance = this;
+ // Call the ref with this instance if provided
+ if (props.ref) {
+ props.ref(this);
+ }
+ }
+
+ render() {
+ const { enabled, steps, onExit, onBeforeChange } = this.props;
+ return enabled ? (
+
+ {steps.map((step: any, index: number) => (
+
+
{step.title}
+
{step.intro}
+
+ ))}
+
onExit()}>Exit
+
onBeforeChange && onBeforeChange(1)}>Next
+
+ ) : null;
+ }
+ },
+ };
+});
+
+// Mock the dispatch function
+const mockDispatch = jest.fn();
+
+describe('Tutorial Component', () => {
+ const defaultProps = {
+ currentTabInApp: 'map',
+ dispatch: mockDispatch,
+ };
+
+ beforeEach(() => {
+ // Clear mock function calls before each test
+ jest.clearAllMocks();
+ currentStepsInstance = null;
+ });
+
+ it('renders without crashing', () => {
+ render( );
+ expect(screen.getByRole('button', { name: /tutorial/i })).toBeInTheDocument();
+ });
+
+ it('starts tutorial when Tutorial button is clicked', () => {
+ render( );
+ const tutorialButton = screen.getByRole('button', { name: /tutorial/i });
+
+ fireEvent.click(tutorialButton);
+
+ expect(screen.getByTestId('mock-steps')).toBeInTheDocument();
+ });
+
+ it('navigates to performance tab before starting tutorial when in performance views', () => {
+ const performanceProps = {
+ ...defaultProps,
+ currentTabInApp: 'performance-comparison',
+ };
+
+ render( );
+ const tutorialButton = screen.getByRole('button', { name: /tutorial/i });
+
+ fireEvent.click(tutorialButton);
+
+ expect(mockDispatch).toHaveBeenCalledWith(setCurrentTabInApp('performance'));
+ });
+
+ describe('Step Navigation', () => {
+ it('handles performance tab tutorial steps correctly', () => {
+ const performanceProps = {
+ ...defaultProps,
+ currentTabInApp: 'performance',
+ };
+
+ render( );
+ const tutorialButton = screen.getByRole('button', { name: /tutorial/i });
+
+ // Start the tutorial
+ fireEvent.click(tutorialButton);
+
+ // Simulate step change by clicking the Next button
+ const nextButton = screen.getByText('Next');
+ fireEvent.click(nextButton);
+
+ // Verify the dispatch was called
+ expect(mockDispatch).toHaveBeenCalledWith(tutorialSaveSeriesToggle('inputBoxOpen'));
+
+ // Verify updateStepElement was called
+ expect(mockUpdateStepElement).toHaveBeenCalledWith(1);
+ });
+ });
+
+ describe('Tutorial Steps Content', () => {
+ it('loads correct steps for map tab', () => {
+ render( );
+ const tutorialButton = screen.getByRole('button', { name: /tutorial/i });
+
+ fireEvent.click(tutorialButton);
+
+ const firstStep = screen.getByTestId('step-0');
+ expect(firstStep).toHaveTextContent('Reactime Tutorial');
+ });
+
+ it('loads correct steps for performance tab', () => {
+ const performanceProps = {
+ ...defaultProps,
+ currentTabInApp: 'performance',
+ };
+
+ render( );
+ const tutorialButton = screen.getByRole('button', { name: /tutorial/i });
+
+ fireEvent.click(tutorialButton);
+
+ const firstStep = screen.getByTestId('step-0');
+ expect(firstStep).toHaveTextContent('Performance Tab');
+ });
+
+ it('shows default message for undefined tabs', () => {
+ const undefinedTabProps = {
+ ...defaultProps,
+ currentTabInApp: 'undefined-tab',
+ };
+
+ render( );
+ const tutorialButton = screen.getByRole('button', { name: /tutorial/i });
+
+ fireEvent.click(tutorialButton);
+
+ const firstStep = screen.getByTestId('step-0');
+ expect(firstStep).toHaveTextContent('No Tutorial For This Tab');
+ });
+ });
+
+ describe('Tutorial Exit', () => {
+ it('handles tutorial exit correctly', () => {
+ render( );
+ const tutorialButton = screen.getByRole('button', { name: /tutorial/i });
+
+ // Start tutorial
+ fireEvent.click(tutorialButton);
+
+ // Find and click the exit button
+ const exitButton = screen.getByText('Exit');
+ fireEvent.click(exitButton);
+
+ // Check that the steps are no longer visible
+ expect(screen.queryByTestId('mock-steps')).not.toBeInTheDocument();
+ });
+ });
+});
diff --git a/src/app/__tests__/WebMetrics.test.tsx b/src/app/__tests__/WebMetrics.test.tsx
index a1ffd6656..9775135b6 100644
--- a/src/app/__tests__/WebMetrics.test.tsx
+++ b/src/app/__tests__/WebMetrics.test.tsx
@@ -1,27 +1,123 @@
-/* eslint:disable */
import React from 'react';
-import { shallow, configure } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-import WebMetrics from '../components/WebMetrics';
-import { expect } from 'chai';
+import { render, screen } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import WebMetrics from '../components/StateRoute/WebMetrics/WebMetrics';
+import { Provider } from 'react-redux';
+import { configureStore } from '@reduxjs/toolkit';
+import { mainSlice } from '../slices/mainSlice';
+// Mock react-redux hooks
+const mockDispatch = jest.fn();
+jest.mock('react-redux', () => ({
+ ...jest.requireActual('react-redux'),
+ useDispatch: () => mockDispatch,
+}));
-//the WebMetrics container should render 4
elements, each with id="card"
-//the WebMetrics container is itself
-configure({ adapter: new (Adapter as any)() });
+// Mock ApexCharts
+jest.mock('react-apexcharts', () => ({
+ __esModule: true,
+ default: () =>
,
+}));
-let wrapper = shallow( );
+// Mock react-hover
+jest.mock('react-hover', () => ({
+ __esModule: true,
+ default: ({ children }) => {children}
,
+ Trigger: ({ children }) => {children}
,
+ Hover: ({ children }) => {children}
,
+}));
+describe('WebMetrics Component', () => {
+ // Clear all mocks before each test
+ beforeEach(() => {
+ mockDispatch.mockClear();
+ });
-describe('WebMetrics graph testing', ()=> {
- it ('should have 1 div with class name "metric" ', () => {
- expect(wrapper.find('.metric')).to.have.lengthOf(1);
- })
+ // Setup function to create consistent test environment
+ const setupTest = (customProps = {}) => {
+ const defaultProps = {
+ color: '#0bce6b',
+ series: [75],
+ formatted: (value) => `${value} ms`,
+ score: ['100 ms', '300 ms'],
+ overLimit: false,
+ label: 'Test Metric',
+ name: 'Test Metric Name',
+ description: 'Test metric description',
+ };
- it ('should have 1 div with id "chart" ', () => {
- expect(wrapper.find('#chart')).to.have.lengthOf(1);
- })
-
+ const props = { ...defaultProps, ...customProps };
-})
+ const store = configureStore({
+ reducer: {
+ main: mainSlice.reducer,
+ },
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }),
+ });
+ return render(
+
+
+ ,
+ );
+ };
+
+ test('renders chart container', () => {
+ const { container } = setupTest();
+ expect(container.getElementsByClassName('chart-container').length).toBe(1);
+ });
+
+ test('renders ApexCharts component', () => {
+ setupTest();
+ expect(screen.getByTestId('apex-chart')).toBeInTheDocument();
+ });
+
+ test('applies correct color prop to chart options', () => {
+ const testColor = '#ff0000';
+ const { container } = setupTest({ color: testColor });
+ const chartContainer = container.querySelector('.chart-container');
+ expect(chartContainer).toBeInTheDocument();
+ });
+
+ test('handles overLimit prop correctly', () => {
+ const { container } = setupTest({ overLimit: true });
+ const chartContainer = container.querySelector('.chart-container');
+ expect(chartContainer).toBeInTheDocument();
+ });
+
+ test('renders hover content with correct information', () => {
+ const testProps = {
+ name: 'Custom Test Metric',
+ description: 'Custom Test Description',
+ score: ['100 ms', '300 ms'],
+ };
+ const { container } = setupTest(testProps);
+ const hoverBox = container.querySelector('.hover-box');
+ expect(hoverBox).toBeInTheDocument();
+ expect(hoverBox).toHaveTextContent('Custom Test Metric');
+ expect(hoverBox).toHaveTextContent('Custom Test Description');
+ });
+
+ test('displays correct threshold colors in hover box', () => {
+ const { container } = setupTest();
+ const hoverBox = container.querySelector('.hover-box');
+ expect(hoverBox).toBeInTheDocument();
+ });
+
+ test('formats values correctly using formatted prop', () => {
+ const customFormatted = jest.fn((value) => `Custom ${value}`);
+ setupTest({ formatted: customFormatted });
+ expect(screen.getByTestId('apex-chart')).toBeInTheDocument();
+ });
+
+ test('dispatches setCurrentTabInApp on mount', () => {
+ setupTest();
+ expect(mockDispatch).toHaveBeenCalledWith(expect.any(Object));
+ expect(mockDispatch).toHaveBeenCalledTimes(1);
+ });
+
+ test('handles empty series data gracefully', () => {
+ const { container } = setupTest({ series: [] });
+ expect(container.getElementsByClassName('chart-container').length).toBe(1);
+ });
+});
diff --git a/src/app/__tests__/action.test.tsx b/src/app/__tests__/action.test.tsx
deleted file mode 100644
index 5c1d439a2..000000000
--- a/src/app/__tests__/action.test.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/no-empty-function */
-/* eslint-disable @typescript-eslint/no-var-requires */
-/* eslint-disable react/jsx-props-no-spreading */
-import React from 'react';
-import { configure, shallow } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-import { changeView, changeSlider } from '../actions/actions';
-
-const Action = require('../components/Action').default;
-
-configure({ adapter: new (Adapter as any)() });
-
-describe('unit testing for Action.tsx', () => {
- let wrapper;
- const props = {
- key: 'actions2',
- selected: true,
- last: false,
- index: 2,
- sliderIndex: 2,
- dispatch: jest.fn(),
- displayName: '3.0',
- componentName: 'App',
- logChangedState: jest.fn(),
- componentData: {
- actualDuration: 3.5,
- },
- state: { test: 'test' },
- viewIndex: 2,
- handleOnkeyDown: jest.fn(),
- };
- beforeEach(() => {
- wrapper = shallow( );
- props.dispatch.mockClear();
- });
-
- describe('Component', () => {
- test.skip("should have a className 'action-component selected' if props.selected is true", () => {
- wrapper.setProps({ selected: true });
- expect(wrapper.hasClass('action-component selected')).toEqual(true);
- });
-
- test("shouldn't have a className 'action-component selected' if props.selected is false", () => {
- wrapper.setProps({ selected: false });
- expect(wrapper.hasClass('action-component selected')).toEqual(false);
- });
-
- test('should invoke dispatch method when clicked', () => {
- wrapper.find('.action-component').simulate('click');
- expect(props.dispatch).toHaveBeenCalled();
- });
-
- test('dispatch should send a changeView action', () => {
- wrapper.find('.action-component').simulate('click');
- expect(props.dispatch.mock.calls[0][0]).toEqual(changeView(props.index));
- });
- });
-
- describe('Jump Button', () => {
- test("should render a div with a className 'jump-button' inside action-component", () => {
- expect(
- wrapper
- .find('.action-component')
- .children()
- .find('.jump-button'),
- ).toHaveLength(1);
- });
-
- test('should invoke dispatch method when clicked', () => {
- wrapper.find('.jump-button').simulate('click', { stopPropagation() {} });
- expect(props.dispatch).toHaveBeenCalled();
- });
-
- test('dispatch should send a changeSlider action', () => {
- wrapper.find('.jump-button').simulate('click', { stopPropagation() {} });
- expect(props.dispatch.mock.calls[0][0]).toEqual(changeSlider(props.index));
- });
- });
-});
diff --git a/src/app/__tests__/dropdown.test.tsx b/src/app/__tests__/dropdown.test.tsx
deleted file mode 100644
index 6eb3563ed..000000000
--- a/src/app/__tests__/dropdown.test.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/no-var-requires */
-/* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable react/jsx-filename-extension */
-import React from 'react';
-import { configure, shallow } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-
-const Dropdown = require('../components/Dropdown').default;
-
-configure({ adapter: new (Adapter as any)() });
-
-describe('unit testing for Dropdown.jsx', () => {
- let wrapper;
- const props = {
- speeds: [
- { value: 1234, label: '0.5x' },
- { value: 312, label: '1.0x' },
- { value: 23, label: '2.0x' },
- ],
- setSpeed: jest.fn(),
- selectedSpeed: { value: 312, label: '1.0x' },
- };
- beforeEach(() => {
- wrapper = shallow( );
- });
-
- describe('Component', () => {
- test('array of objects that have value and label should be options props', () => {
- expect(wrapper.props().options).toEqual(props.speeds);
- });
- test('selectedOption should be value property', () => {
- expect(wrapper.props().value).toEqual(props.selectedSpeed);
- });
- });
-
- describe('setSpeed', () => {
- test('should invoke setSpeed on change', () => {
- wrapper.simulate('change', { value: 2000, label: '0.5x' });
- expect(props.setSpeed).toHaveBeenCalled();
- });
- });
-});
diff --git a/src/app/__tests__/index.test.tsx b/src/app/__tests__/index.test.tsx
deleted file mode 100644
index 8f63502fe..000000000
--- a/src/app/__tests__/index.test.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-/* eslint-disable @typescript-eslint/no-var-requires */
-import React from 'react';
-import ReactDOM from 'react-dom';
-
-const App = require('../components/App').default;
-
-jest.mock('../../../node_modules/intro.js/introjs.css', () => jest.fn());
-it('renders without crashing', () => {
- const root = document.createElement('root');
- ReactDOM.render( , root);
-});
diff --git a/src/app/__tests__/mainReducer.test.tsx b/src/app/__tests__/mainReducer.test.tsx
deleted file mode 100644
index 201a7488a..000000000
--- a/src/app/__tests__/mainReducer.test.tsx
+++ /dev/null
@@ -1,371 +0,0 @@
-/* eslint-disable @typescript-eslint/no-empty-function */
-/* eslint-disable max-len */
-import mainReducer from '../reducers/mainReducer';
-import {
- toggleMode, addNewSnapshots, initialConnect, setPort, emptySnapshots, changeView, changeSlider, moveBackward, moveForward, playForward, pause, startPlaying, importSnapshots, setTab, deleteTab,
-} from '../actions/actions';
-
-describe('mainReducer testing', () => {
- let state;
- let currentTab;
- beforeEach(() => {
- state = {
- tabs: {
- 87: {
- snapshots: [1, 2, 3, 4],
- sliderIndex: 2,
- viewIndex: -1,
- mode: {
- paused: false,
- locked: false,
- persist: false,
- },
- intervalId: 87,
- playing: true,
- index: 3,
- // should be a linked list with four nodes
- hierarchy: {
- index: 0,
- name: 1,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- },
- children: [{
- index: 1,
- name: 2,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- },
- children: [{
- index: 2,
- name: 3,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- },
- children: [{
- index: 3,
- name: 4,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- },
- children: [],
- }],
- }],
- }],
- },
- // currLocation: null,
- // should point to the last node in hierarchy
- currLocation: 4,
- },
- 75: {
- snapshots: [1, 2, 3, 4],
- sliderIndex: 3,
- viewIndex: -1,
- mode: {
- paused: false,
- locked: false,
- persist: false,
- },
- intervalId: 75,
- playing: false,
- // should be a linked list with four nodes
- hierarchy: {
- index: 0,
- name: 1,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- },
- children: [{
- index: 1,
- name: 2,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- },
- children: [{
- index: 2,
- name: 3,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- },
- children: [{
- index: 3,
- name: 4,
- branch: 0,
- stateSnapshot: {
- state: {},
- children: [{
- state: { test: 'test' },
- name: 'App',
- componentData: { actualDuration: 3.5 },
- }],
- },
- children: [],
- }],
- }],
- }],
- },
- // currLocation: null,
- // should point to the last node in hierarchy
- currLocation: 4,
- },
- },
- currentTab: 87,
- port: {
- postMessage: () => {},
- },
- };
-
- // eslint-disable-next-line prefer-destructuring
- currentTab = state.currentTab;
- });
-
- describe('moveBackward', () => {
- it('should decrement sliderIndex by 1', () => {
- expect(mainReducer(state, moveBackward()).tabs[currentTab].sliderIndex).toEqual(1);
- expect(mainReducer(state, moveBackward()).tabs[currentTab].playing).toEqual(false);
- });
- it('should not decrement if sliderIndex is zero', () => {
- state.tabs[currentTab].sliderIndex = 0;
- const { sliderIndex } = mainReducer(state, moveBackward()).tabs[currentTab];
- expect(sliderIndex).toBe(0);
- });
- });
-
- describe('moveForward', () => {
- it('should increment sliderIndex by 1', () => {
- expect(mainReducer(state, moveForward()).tabs[currentTab].sliderIndex).toEqual(3);
- expect(mainReducer(state, moveForward()).tabs[currentTab].playing).toEqual(false);
- });
- it('should not increment past end value if sliderIndex at end', () => {
- state.tabs[currentTab].sliderIndex = 3;
- const { sliderIndex } = mainReducer(state, moveForward()).tabs[currentTab];
- expect(sliderIndex).toBe(3);
- });
- it('should not change playing if not coming from user', () => {
- const { playing } = mainReducer(state, playForward()).tabs[currentTab];
- expect(playing).toBe(true);
- });
- });
-
- describe('changeView', () => {
- it('should unselect view if same index was selected', () => {
- state.tabs[currentTab].viewIndex = 1;
- expect(mainReducer(state, changeView(1)).tabs[currentTab].viewIndex).toEqual(-1);
- });
- it('change viewIndex when unselected', () => {
- expect(mainReducer(state, changeView(2)).tabs[currentTab].viewIndex).toEqual(2);
- });
- });
-
- describe('changeSlider', () => {
- it('should change sliderIndex', () => {
- expect(mainReducer(state, changeSlider(2)).tabs[currentTab].sliderIndex).toEqual(2);
- });
- // should also change view
- });
-
- describe('empty', () => {
- it('should empty snapshots except the first one', () => {
- expect(mainReducer(state, emptySnapshots()).tabs[currentTab].sliderIndex).toEqual(0);
- expect(mainReducer(state, emptySnapshots()).tabs[currentTab].viewIndex).toEqual(0);
- expect(mainReducer(state, emptySnapshots()).tabs[currentTab].playing).toEqual(false);
- expect(mainReducer(state, emptySnapshots()).tabs[currentTab]
- .snapshots).toEqual([state.tabs[currentTab].snapshots[state.tabs[currentTab].snapshots.length - 1]]);
- });
- // should push slider back to start position
- });
-
- describe('setPort', () => {
- it('should set port when connection', () => {
- expect(mainReducer(state, setPort('newPort')).port).toEqual('newPort');
- });
- });
-
- describe('Import', () => {
- it('importing file should replace snapshots of devtool', () => {
- expect(mainReducer(state, importSnapshots([100, 101])).tabs[currentTab].snapshots).toEqual([100, 101]);
- });
- });
-
- describe('Toggle Mode', () => {
- it('clicking pause button should only change pause mode', () => {
- const { mode } = mainReducer(state, toggleMode('paused')).tabs[currentTab];
- expect(mode.paused).toBe(true);
- expect(mode.locked).toBe(false);
- expect(mode.persist).toBe(false);
- });
- it('clicking lock button should only change lock mode', () => {
- const { mode } = mainReducer(state, toggleMode('locked')).tabs[currentTab];
- expect(mode.paused).toBe(false);
- expect(mode.locked).toBe(true);
- expect(mode.persist).toBe(false);
- });
- it('clicking persist button should only change persist mode', () => {
- const { mode } = mainReducer(state, toggleMode('persist')).tabs[currentTab];
- expect(mode.paused).toBe(false);
- expect(mode.locked).toBe(false);
- expect(mode.persist).toBe(true);
- });
- it('undefined payload does nothing', () => {
- const { mode } = mainReducer(state, toggleMode('undefined')).tabs[currentTab];
- expect(mode.paused).toBe(false);
- expect(mode.locked).toBe(false);
- expect(mode.persist).toBe(false);
- });
- });
-
- describe('slider pause', () => {
- it('should set playing to false and intervalId to null', () => {
- const playedTab = mainReducer(state, pause()).tabs[currentTab];
- expect(playedTab.playing).toBe(false);
- expect(playedTab.intervalId).toBe(null);
- });
- });
-
- describe('slider play', () => {
- it('should set playing to true and intervalId to payload', () => {
- const playedTab = mainReducer(state, startPlaying(333)).tabs[currentTab];
- expect(playedTab.playing).toBe(true);
- expect(playedTab.intervalId).toBe(333);
- });
- });
-
- describe('Initial Connect', () => {
- const newTab = {
- 104: {
- snapshots: [1, 2, 3, 8],
- sliderIndex: 3,
- viewIndex: -1,
- mode: {
- paused: false,
- locked: false,
- persist: false,
- },
- intervalId: 912,
- playing: true,
- },
- };
- it('should add new tab', () => {
- const addedTab = mainReducer(state, initialConnect(newTab)).tabs[104];
- expect(addedTab).not.toBe(undefined);
- });
- it('should force some values to default', () => {
- const addedTab = mainReducer(state, initialConnect(newTab)).tabs[104];
- expect(addedTab.sliderIndex).toBe(0);
- expect(addedTab.viewIndex).toBe(-1);
- expect(addedTab.intervalId).toBe(null);
- expect(addedTab.playing).toBe(false);
- });
- it('snapshots should match the payload', () => {
- const addedTab = mainReducer(state, initialConnect(newTab)).tabs[104];
- expect(addedTab.snapshots).toEqual(newTab[104].snapshots);
- });
- it('if currentTab undefined currentTab becomes firstTab', () => {
- state.currentTab = undefined;
- const addedTab = mainReducer(state, initialConnect(newTab));
- expect(addedTab.currentTab).toBe(104);
- });
- });
-
- // This test is breaking, please troubleshoot
- // describe('new snapshots', () => {
- // const newSnapshots = {
- // 87: {
- // snapshots: [1, 2, 3, 4, 5],
- // sliderIndex: 2,
- // viewIndex: -1,
- // mode: {
- // paused: false,
- // locked: false,
- // persist: false,
- // },
- // intervalId: 87,
- // playing: true,
- // },
- // };
- // it('update snapshots of corresponding tabId', () => {
- // const updated = mainReducer(state, addNewSnapshots(newSnapshots));
- // expect(updated.tabs[87].snapshots).toEqual(newSnapshots[87].snapshots);
- // });
- // it('should delete tabs that are deleted from background script', () => {
- // const updated = mainReducer(state, addNewSnapshots(newSnapshots));
- // expect(updated.tabs[75]).toBe(undefined);
- // });
- // it('if currentTab undefined currentTab becomes first Tab', () => {
- // state.currentTab = undefined;
- // const updated = mainReducer(state, addNewSnapshots(newSnapshots));
- // expect(updated.currentTab).toBe(87);
- // });
- // });
-
- describe('set_tab', () => {
- it('should set tab to payload', () => {
- const newCurrentTab = mainReducer(state, setTab(75)).currentTab;
- expect(newCurrentTab).toBe(75);
- });
- });
-
- describe('delete_tab', () => {
- it('should delete only payload tab from state', () => {
- const afterDelete = mainReducer(state, deleteTab(75));
- expect(afterDelete.tabs[75]).toBe(undefined);
- expect(afterDelete.tabs[87]).not.toBe(undefined);
- });
- });
-
- describe('default', () => {
- const action = {
- type: 'doesNotExist',
- payload: 'trigger',
- };
- it('if there are no match of action types, throw error', () => {
- try {
- mainReducer(state, action);
- } catch (err) {
- expect(err).toBeInstanceOf(Error);
- }
- });
- });
-});
diff --git a/src/app/actions/actions.ts b/src/app/actions/actions.ts
deleted file mode 100644
index 1c871eda1..000000000
--- a/src/app/actions/actions.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-import * as types from '../constants/actionTypes';
-
-export const save = (newSeries, newSeriesName) => ({
- type: types.SAVE,
- payload: { newSeries, newSeriesName },
-});
-export const deleteSeries = () => ({
- type: types.DELETE_SERIES,
-});
-export const toggleMode = (mode) => ({
- type: types.TOGGLE_MODE,
- payload: mode,
-});
-
-export const addNewSnapshots = (tabsObj) => ({
- type: types.NEW_SNAPSHOTS,
- payload: tabsObj,
-});
-
-export const initialConnect = (tabsObj) => ({
- type: types.INITIAL_CONNECT,
- payload: tabsObj,
-});
-
-export const setPort = (port) => ({
- type: types.SET_PORT,
- payload: port,
-});
-
-export const emptySnapshots = () => ({
- type: types.EMPTY,
-});
-
-export const changeView = (index) => ({
- type: types.CHANGE_VIEW,
- payload: index,
-});
-
-export const changeSlider = (index) => ({
- type: types.CHANGE_SLIDER,
- payload: index,
-});
-
-export const moveBackward = () => ({
- type: types.MOVE_BACKWARD,
- payload: false,
-});
-
-export const moveForward = () => ({
- type: types.MOVE_FORWARD,
- payload: false,
-});
-
-export const playForward = () => ({
- type: types.MOVE_FORWARD,
- payload: true,
-});
-
-export const pause = () => ({
- type: types.PAUSE,
-});
-
-export const startPlaying = (intervalId) => ({
- type: types.PLAY,
- payload: intervalId,
-});
-
-export const importSnapshots = (newSnaps) => ({
- type: types.IMPORT,
- payload: newSnaps,
-});
-
-export const setTab = (tab) => ({
- type: types.SET_TAB,
- payload: tab,
-});
-
-export const deleteTab = (tab) => ({
- type: types.DELETE_TAB,
- payload: tab,
-});
-
-export const noDev = (tab) => ({
- type: types.NO_DEV,
- payload: tab,
-});
-
-export const toggleSplit = () => ({
- type: types.TOGGLE_SPLIT,
-});
-
-export const toggleExpanded = (node) => ({
- type: types.TOGGLE_EXPANDED,
- payload: node,
-});
-
-export const launchContentScript = (tab) => ({
- type: types.LAUNCH_CONTENT,
- payload: tab,
-});
-
-export const resetSlider = () => ({
- type: types.SLIDER_ZERO,
-});
-
-export const onHover = (rtid) => ({
- type: types.ON_HOVER,
- //the payload should be something to relate the component we're hovering and highlight that component on the DOM
- payload: rtid,
-});
-
-export const onHoverExit = (rtid) => ({
- type: types.ON_HOVER_EXIT,
- payload: rtid,
-});
-
-export const setCurrentLocation = (tabsObj) => ({
- type: types.SET_CURRENT_LOCATION,
- payload: tabsObj,
-});
-
-export const setCurrentTabInApp = (currentTabInApp) => ({
- type: types.SET_CURRENT_TAB_IN_APP,
- payload: currentTabInApp,
-});
-
-export const tutorialSaveSeriesToggle = (toggleVal) => ({
- type: types.TUTORIAL_SAVE_SERIES_TOGGLE,
- payload: toggleVal,
-});
diff --git a/src/app/components/Action.tsx b/src/app/components/Action.tsx
deleted file mode 100644
index 9af1c853a..000000000
--- a/src/app/components/Action.tsx
+++ /dev/null
@@ -1,155 +0,0 @@
-/* eslint-disable react/require-default-props */
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable react/no-unused-prop-types */
-
-import React from 'react';
-import ReactHover, { Trigger, Hover } from 'react-hover';
-import { changeView, changeSlider } from '../actions/actions';
-
-/**
- * @template ActionProps Props for the action component
- */
-
-interface ActionProps {
- key: string;
- selected: boolean;
- last: boolean;
- index: number;
- sliderIndex: number;
- dispatch: (a: any) => void;
- displayName: string;
- componentName: string;
- componentData: { actualDuration: number } | undefined;
- routePath: any;
- state?: Record;
- viewIndex: number | undefined;
- isCurrIndex: boolean;
- handleOnkeyDown: (e: any, i: number) => any;
-}
-
-/**
- * @function Action
- * @param selected : The selected action in the array of state changes
- * @param displayName : Label showing sequence number of state change, reflects changes in Chart.tsx
- * @param componentName : Displays the name of compenent's state being changed
- * @param last : The last index in the array
- * @param sliderIndex: Index of the slider in the array of state changes
- * (clicking the block changes the slider, related to MainSlider.tsx slider)
- * @param componentData: Displays react fiber data
- * @param viewIndex: Index of the tab in the array when timejump is made
- * @method dispatch Executes actions that changes state in reactime
- * @method handleOnkeyDown Executes key commands
- *
- */
-// index and delta props were removed from Action.jsx */
-// viewIndex and handleonkeyDown added to props
-const Action = (props: ActionProps): JSX.Element => {
- const {
- selected,
- last,
- index,
- sliderIndex,
- dispatch,
- displayName,
- componentData,
- viewIndex,
- isCurrIndex,
- handleOnkeyDown,
- } = props;
-
- /**
- * @function cleanTime: Displays render times for state changes
- * @returns render display time in seconds in milliseconds
- */
- const cleanTime = () => {
- if (!componentData || !componentData.actualDuration) {
- return 'NO TIME';
- }
- let seconds: number | string;
- let milliseconds: any = componentData.actualDuration;
- if (Math.floor(componentData.actualDuration) > 60) {
- seconds = Math.floor(componentData.actualDuration / 60);
- seconds = JSON.stringify(seconds);
- if (seconds.length < 2) {
- seconds = '0'.concat(seconds);
- }
- milliseconds = Math.floor(componentData.actualDuration % 60);
- } else {
- seconds = '00';
- }
- milliseconds = Number.parseFloat(milliseconds).toFixed(2);
- const arrayMilliseconds = milliseconds.split('.');
- if (arrayMilliseconds[0].length < 2) {
- arrayMilliseconds[0] = '0'.concat(arrayMilliseconds[0]);
- }
- if (index === 0) {
- return `${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`;
- }
- return `+${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`;
- };
- const displayTime = cleanTime();
-
- const optionsCursorTrueWithMargin = {
- followCursor: true,
- shiftX: 20,
- shiftY: 0,
- };
-
- return (
-
-
handleOnkeyDown(e, viewIndex)}
- className={
- selected || last ? 'action-component selected' : 'action-component'
- }
- onClick={() => {
- dispatch(changeView(index));
- }}
- role="presentation"
- style={index > sliderIndex ? { color: '#5f6369' } : {}}
- tabIndex={index}
- >
-
-
- sliderIndex ? { color: '#5f6369' } : {}}>
-
-
-
-
- {displayTime}
-
- {
- isCurrIndex ? (
-
- Current
-
- )
- : (
-
{
- e.stopPropagation();
- dispatch(changeSlider(index));
- dispatch(changeView(index));
- }}
- tabIndex={index}
- type="button"
- >
- Jump
-
- )
- }
-
-
-
-
-
-
- );
-};
-
-export default Action;
diff --git a/src/app/components/Actions/Action.tsx b/src/app/components/Actions/Action.tsx
new file mode 100644
index 000000000..8aa49ba26
--- /dev/null
+++ b/src/app/components/Actions/Action.tsx
@@ -0,0 +1,119 @@
+import React from 'react';
+import ReactHover, { Trigger, Hover } from 'react-hover';
+import { changeView, changeSlider } from '../../slices/mainSlice';
+import { ActionProps, OptionsCursorTrueWithMargin } from '../../FrontendTypes';
+import { useDispatch } from 'react-redux';
+
+const Action = (props: ActionProps): JSX.Element => {
+ const dispatch = useDispatch();
+
+ const { selected, last, index, sliderIndex, displayName, componentData, viewIndex, isCurrIndex } =
+ props;
+
+ const cleanTime = (): string => {
+ if (!componentData || !componentData.actualDuration) {
+ return 'NO TIME';
+ }
+
+ let seconds: number | string;
+ let milliseconds: any = componentData.actualDuration;
+
+ if (Math.floor(componentData.actualDuration) > 60) {
+ seconds = Math.floor(componentData.actualDuration / 60);
+ seconds = JSON.stringify(seconds);
+
+ if (seconds.length < 2) {
+ seconds = '0'.concat(seconds);
+ }
+ milliseconds = Math.floor(componentData.actualDuration % 60);
+ } else {
+ seconds = '00';
+ }
+
+ milliseconds = Number.parseFloat(milliseconds as string).toFixed(2);
+ const arrayMilliseconds: [string, number] = milliseconds.split('.');
+
+ if (arrayMilliseconds[0].length < 2) {
+ arrayMilliseconds[0] = '0'.concat(arrayMilliseconds[0]);
+ }
+
+ if (index === 0) {
+ return `${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`;
+ }
+ return `+${seconds}:${arrayMilliseconds[0]}.${arrayMilliseconds[1]}`;
+ };
+
+ const displayTime: string = cleanTime();
+
+ const optionsCursorTrueWithMargin: OptionsCursorTrueWithMargin = {
+ followCursor: true,
+ shiftX: 20,
+ shiftY: 0,
+ };
+
+ return (
+
+
{
+ dispatch(changeView(index));
+ }}
+ role='presentation'
+ style={index > sliderIndex ? { color: '#5f6369' } : {}}
+ tabIndex={index}
+ >
+
+
+ sliderIndex ? { color: '#5f6369' } : {}}
+ >
+
+
+
+ {isCurrIndex ? (
+
+ ) : (
+
+ {displayTime}
+
+ )}
+ {isCurrIndex ? (
+
+ Current
+
+ ) : (
+
{
+ e.stopPropagation();
+ dispatch(changeSlider(index));
+ dispatch(changeView(index));
+ }}
+ tabIndex={index}
+ type='button'
+ >
+ Jump
+
+ )}
+
+
+
+
+
+
+ );
+};
+
+export default Action;
diff --git a/src/app/components/Actions/DropDown.tsx b/src/app/components/Actions/DropDown.tsx
new file mode 100644
index 000000000..b53320971
--- /dev/null
+++ b/src/app/components/Actions/DropDown.tsx
@@ -0,0 +1,33 @@
+import Select from 'react-select';
+import React from 'react';
+
+const DropDown = ({
+ dropdownSelection,
+ setDropdownSelection,
+}: {
+ dropdownSelection: string;
+ setDropdownSelection: (value: string) => void;
+}): JSX.Element => {
+ const handleChange = (selected: { value: string; label: string }) => {
+ setDropdownSelection(selected.value);
+ };
+
+ const options = [
+ { value: 'Time Jump', label: 'Time Jump' },
+ { value: 'Providers / Consumers', label: 'Providers / Consumers' },
+ ];
+
+ return (
+
+ option.value === dropdownSelection)}
+ />
+
+ );
+};
+
+export default DropDown;
diff --git a/src/app/components/Actions/RecordButton.tsx b/src/app/components/Actions/RecordButton.tsx
new file mode 100644
index 000000000..1f1446144
--- /dev/null
+++ b/src/app/components/Actions/RecordButton.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import { Switch } from '@mui/material';
+import ThemeToggle from './ThemeToggle';
+
+const RecordButton = ({ isRecording, onToggle }) => {
+ return (
+
+ );
+};
+
+export default RecordButton;
diff --git a/src/app/components/Actions/RouteDescription.tsx b/src/app/components/Actions/RouteDescription.tsx
new file mode 100644
index 000000000..aa1c75eea
--- /dev/null
+++ b/src/app/components/Actions/RouteDescription.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import VerticalSlider from '../TimeTravel/VerticalSlider';
+
+/*
+ Render's the red route description on app's left sided column between the clear button and the list of state snapshots. The route description is derived from the first state snapshot.
+*/
+
+type RouteProps = {
+ actions: JSX.Element[];
+};
+
+const RouteDescription = (props: RouteProps): JSX.Element => {
+ const { actions } = props;
+
+ const url: URL = new URL(actions[0].props.routePath); // Use new URL to use the url.pathname method.
+
+ return (
+
+
Route: {url.pathname}
+
+
+
+
+
+ {/* actual snapshots per route */}
+ {actions}
+
+
+
+ );
+};
+
+export default RouteDescription;
diff --git a/src/app/components/Actions/ThemeToggle.tsx b/src/app/components/Actions/ThemeToggle.tsx
new file mode 100644
index 000000000..c8288e757
--- /dev/null
+++ b/src/app/components/Actions/ThemeToggle.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import { Moon, Sun } from 'lucide-react';
+import { useTheme } from '../../ThemeProvider';
+
+const ThemeToggle = () => {
+ const { isDark, toggleTheme } = useTheme();
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default ThemeToggle;
diff --git a/src/app/components/App.tsx b/src/app/components/App.tsx
deleted file mode 100644
index f9a8c0510..000000000
--- a/src/app/components/App.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import React, { useReducer } from 'react';
-import {
- MemoryRouter as Router,
-} from 'react-router-dom';
-import MainContainer from '../containers/MainContainer';
-import { StoreContext } from '../store';
-import mainReducer from '../reducers/mainReducer.js';
-
-// currentTab is the current active tab within Google Chrome.
-// This is used to decide what tab Reactime should be monitoring. This can be "locked"
-// currentTabInApp is the current active tab within Reactime (Map, Performance, History, etc).
-// This is used to determine the proper tutorial to render when How To button is pressed.
-
-const initialState: {
- port: null | number,
- currentTab: null | number,
- currentTitle: null | string,
- split: null | boolean,
- tabs: unknown,
- currentTabInApp: null | string, } = {
- port: null,
- currentTab: null,
- currentTitle: 'No Target',
- split: false,
- tabs: {},
- currentTabInApp: null,
- };
-
-function App(): JSX.Element {
- return (
-
-
-
-
-
- );
-}
-
-export default App;
diff --git a/src/app/components/Buttons/StatusDot.tsx b/src/app/components/Buttons/StatusDot.tsx
new file mode 100644
index 000000000..1f427e5ed
--- /dev/null
+++ b/src/app/components/Buttons/StatusDot.tsx
@@ -0,0 +1,7 @@
+import React from 'react';
+
+const StatusDot = ({ status }) => {
+ return ;
+};
+
+export default StatusDot;
diff --git a/src/app/components/Buttons/Tutorial.tsx b/src/app/components/Buttons/Tutorial.tsx
new file mode 100644
index 000000000..29d526e90
--- /dev/null
+++ b/src/app/components/Buttons/Tutorial.tsx
@@ -0,0 +1,340 @@
+/* eslint-disable react/sort-comp */
+/* eslint-disable lines-between-class-members */
+/* eslint-disable react/static-property-placement */
+
+import * as React from 'react';
+import { Component } from 'react';
+import 'intro.js/introjs.css';
+import { TutorialProps, TutorialState, StepsObj } from '../../FrontendTypes';
+import { Button } from '@mui/material';
+const { Steps } = require('intro.js-react');
+import { setCurrentTabInApp, tutorialSaveSeriesToggle } from '../../slices/mainSlice';
+import { HelpCircle } from 'lucide-react';
+
+/*
+ This is the tutorial displayed when the "How to use" button is clicked
+ This needs to be a class component to be compatible with updateStepElement from intro.js
+
+ currently written as class components vs functional components.
+*/
+
+export default class Tutorial extends Component {
+ constructor(props: TutorialProps) {
+ super(props);
+ this.state = {
+ stepsEnabled: false,
+ };
+ }
+
+ //tutorial class needs these public variables to be a valid class component for ts when rendered in buttonscontainer.tsx
+ public context: any;
+ public setState: any;
+ public forceUpdate: any;
+ public props: any;
+ public state: any;
+ public refs: any;
+
+ render(): JSX.Element {
+ const {
+ currentTabInApp, // 'currentTabInApp' from 'ButtonsContainer' after useSelector()
+ dispatch, // 'dispatch' from 'ButtonsContainer' after useDispatch()
+ } = this.props;
+
+ // This updates the steps so that they can target dynamically rendered elements
+ const onChangeHandler = (currentStepIndex: number) => {
+ // takes in the current step and updates the tab[currentTab]'s seriesSavedStatus based on conditions and updates the element associated with the step.
+ if (currentTabInApp === 'performance' && currentStepIndex === 1) {
+ dispatch(tutorialSaveSeriesToggle('inputBoxOpen')); // sends a dispatch that update's tab[currentTab]'s 'seriesSavedStatus' to 'inputBoxOpen'
+ this.steps.updateStepElement(currentStepIndex); // Built in intro.js API that updates element associated with step
+ }
+
+ if (currentTabInApp === 'performance' && currentStepIndex === 2) {
+ this.steps.updateStepElement(currentStepIndex);
+ }
+
+ if (currentTabInApp === 'performance' && currentStepIndex === 4) {
+ dispatch(tutorialSaveSeriesToggle('saved')); // sends a dispatch that update's tab[currentTab]'s 'seriesSavedStatus' to 'saved'
+ this.steps.updateStepElement(currentStepIndex);
+ }
+
+ if (currentTabInApp === 'performance' && currentStepIndex === 5) {
+ this.steps.updateStepElement(currentStepIndex);
+ dispatch(setCurrentTabInApp('performance-comparison')); // dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'performance-comparison.' to facilitate render.
+ }
+
+ if (currentTabInApp === 'performance-comparison' && currentStepIndex === 6) {
+ dispatch(tutorialSaveSeriesToggle(false)); // sends a dispatch that update's tab[currentTab]'s 'seriesSavedStatus' to the boolean 'false'
+ }
+ };
+
+ const onExit = () => {
+ // This callback is called when the tutorial exits
+ this.setState({ stepsEnabled: false }); // sets stepsEnabled to false in this component's state
+ };
+
+ const startIntro = () => {
+ // If "How to use" is clicked while in the performance tab, we'll navigate to the snapshops view before starting the tutorial. This is because the tutorial steps are designed to begin on the snapshots sub-tab. Check out the 'PerformanceVisx' component to see the route redirect logic
+ if (
+ currentTabInApp === 'performance' ||
+ currentTabInApp === 'performance-comparison' ||
+ currentTabInApp === 'performance-component-details'
+ ) {
+ dispatch(setCurrentTabInApp('performance')); // dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'performance' to facilitate render.
+ }
+ this.setState({ stepsEnabled: true }); // sets stepsEnabled to false in this component's state
+ };
+
+ let steps: StepsObj[] = []; // the steps array will be populated with tutorial elements based on the 'currentTabInApp' case. This allows for specific tutorials based on the current page the user is viewing.
+
+ switch (currentTabInApp) {
+ case 'map':
+ steps = [
+ {
+ title: 'Reactime Tutorial',
+ intro:
+ 'A tool for time travel debugging and performance monitoring in React applications.',
+ position: 'top',
+ },
+ {
+ title: 'Actions',
+ element: '.action-container',
+ intro:
+ "Reactime records a snapshot whenever a target application's state is changed ",
+ position: 'right',
+ },
+ {
+ title: 'Toggles',
+ element: '.record-button-container',
+ intro:
+ 'Toggle record button to pause state changes on target application Toggle theme button to switch between light and dark themes ',
+ position: 'right',
+ },
+ {
+ title: 'Dropdown Menu',
+ element: '.css-13cymwt-control',
+ intro: 'Dropdown Menu for picking between Timejump and UseContext ',
+ position: 'right',
+ },
+ {
+ element: '.individual-action',
+ title: 'Snapshot',
+ intro:
+ 'Each snapshot allows the user to jump to any previously recorded state. It also detects the amount of renders of each component and average time of rendering .',
+ position: 'right',
+ },
+ {
+ title: 'Timejump',
+ element: '.rc-slider',
+ intro:
+ 'Use the slider to go back in time to a particular state change ',
+ position: 'top',
+ },
+ {
+ title: 'Play',
+ element: '.travel-container',
+ intro:
+ 'Click the Play button to run through each state change automatically Select playback speed from the dropdown menu (0.5x, 1.0x, or 2.0x) to control how fast states change during playback ',
+ position: 'top',
+ },
+ {
+ title: 'Lock Button',
+ element: '.pause-button',
+ intro:
+ "Use button to lock Reactime to the target application's tab in the Chrome Browser ",
+ position: 'top',
+ },
+ {
+ title: 'Download Button',
+ element: '.export-button',
+ intro: 'Use button to download a JSON file of all snapshots ',
+ position: 'top',
+ },
+ {
+ title: 'Upload Button',
+ element: '.import-button',
+ intro:
+ 'Use button to upload a previously downloaded JSON file for snapshot comparisons ',
+ position: 'top',
+ },
+ {
+ title: 'Reconnect button',
+ element: '.reconnect-button',
+ intro:
+ 'Click the Reconnect button if connection is lost to reestablish communication with your application. ',
+ position: 'top',
+ },
+ {
+ element: '.map-tab',
+ title: 'Map Tab',
+ intro:
+ 'This tab visually displays a component hierarchy tree for your app ',
+ position: 'bottom',
+ },
+ {
+ title: 'History Tab',
+ element: '.history-tab',
+ intro: 'This tab visually displays a history of each snapshot ',
+ position: 'bottom',
+ },
+ {
+ title: 'Performance Tab',
+ element: '.performance-tab',
+ intro:
+ 'User can save a series of state snapshots and use it to analyze changes in component, render performance between current, and previous series of snapshots. User can save a series of state snapshots and use it to analyze changes in component render performance between current and previous series of snapshots. TIP: Click the how to use button within the performance tab for more details. ',
+ position: 'bottom',
+ },
+
+ {
+ title: 'Web Metrics Tab',
+ element: '.web-metrics-tab',
+ intro:
+ ' This tab visually displays performance metrics and allows the user to gauge efficiency of their application ',
+ position: 'bottom',
+ },
+ {
+ title: 'Tree Tab',
+ element: '.tree-tab',
+ intro:
+ 'This tab visually displays a JSON Tree containing the different components and states ',
+ position: 'bottom',
+ },
+ {
+ title: 'Accessibility Tree',
+ element: '.accessibility-tab', //'This tab visually displays a Accessibility Tree '
+ intro:
+ 'Nodes from the accessibility tree have either a role or a internal role refers to ARIA roles, which indicate the purpose of the element to assistive technologies, like screen readers.All of the nodes rendered in this tree have a role of Role.InternalRole refers to browser-specific roles Chrome for its own accessibility processing. Each node is given a property labeled ignored . Nodes read by the screen reader have their ignored property evaluate to false .Nodes not read by the screen reader evaluate to true .
Nodes labeled as no name are visible to a screen reader, but were not given a name label.
',
+ position: 'bottom',
+ },
+ {
+ title: 'Tutorial Complete',
+ intro:
+ '',
+ position: 'top',
+ },
+ ];
+ break;
+ case 'performance':
+ steps = [
+ {
+ title: 'Performance Tab',
+ element: '.bargraph-position',
+ intro:
+ 'Here we can analyze the render times of our app This is the current series of state changes within our app Mouse over the bargraph elements for details on each specific component ',
+ position: 'top',
+ },
+ ];
+ break;
+ case 'accessibility': //'AxTree'
+ steps = [
+ {
+ title: 'Accessibility Tree',
+ element: '.display',
+ intro:
+ 'Nodes from the accessibility tree have either a role role or internalRole Role refers to ARIA roles, which indicate the purpose of the element to assistive technologies, like screen readers.All of the nodes rendered in this tree have a role of Role.internalRole refers to browser-specific roles Chrome for its own accessibility processing. Each node is given a property labeled ignored . Nodes read by the screen reader have their ignored property evaluate to false .Nodes not read by the screen reader evaluate to true .
Nodes labeled as no name are visible to a screen reader, but were not given a name label.
',
+ position: 'top',
+ },
+ ];
+ break;
+ case 'webmetrics':
+ steps = [
+ {
+ title: 'Webmetrics Tab',
+ element: '.web-metrics-container',
+ intro: 'Additional info can be found be hovering over desired metrics',
+ position: 'top',
+ },
+ ];
+ break;
+ case 'history':
+ steps = [
+ {
+ title: 'History Tab',
+ element: '.display',
+ intro:
+ 'The history tab shows all snapshots as a timeline and includes branches to represent divergent state history created from time traveling backwards and making new state changes.',
+ position: 'top',
+ },
+ {
+ title: 'Viewing History Snapshot',
+ element: '.display', //document.querySelectorAll('.snapshotNode')[0]
+ intro:
+ 'Each node will represent a snapshot in the page. A single snapshot will show as a node while multiple snapshots will be represented as a timeline. Highlighting over one will show any state changes compared to the previous snapshot. Clicking a node will set the snapshot as the current one. ',
+ position: 'top',
+ },
+ {
+ title: 'Navigating through Snapshots',
+ element: '.routedescription',
+ intro: 'All snapshots can also be seen and navigated here as well.',
+ position: 'right',
+ },
+
+ {
+ title: 'Clicking on Jump Button',
+ element: document.querySelectorAll('.individual-action')[0],
+ intro:
+ 'The button on the right of each snapshot can be used to jump to a given point in state to view the state history at that point.',
+ position: 'right',
+ },
+ {
+ title: 'Renaming The Snapshot',
+ element: document.querySelectorAll('.action-component-text')[0],
+ intro:
+ 'A snapshot can be renamed to provided more clarity or distinguish specific snapshots.',
+ position: 'left',
+ },
+ ];
+ break;
+ case 'tree':
+ steps = [
+ {
+ title: 'Tree Tab',
+ element: '.display',
+ intro:
+ 'The tree tab can be used to view a text display of the state snapshots in a JSON format.',
+ position: 'top',
+ },
+ ];
+ break;
+ default:
+ steps = [
+ {
+ title: 'No Tutorial For This Tab',
+ intro:
+ 'A tutorial for this tab has not yet been created Please visit our official Github Repo for more information Reactime Github ',
+ position: 'top',
+ },
+ ];
+ break;
+ }
+
+ return (
+ <>
+ onChangeHandler(currentStepIndex)} // Callback called before changing the current step.
+ ref={(steps) => (this.steps = steps)} // ref allows access to intro.js API
+ />
+ startIntro()}>
+ Tutorial
+
+ >
+ );
+ }
+}
diff --git a/src/app/components/Diff.tsx b/src/app/components/Diff.tsx
deleted file mode 100644
index 5009c1fc2..000000000
--- a/src/app/components/Diff.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React from 'react';
-import { diff, formatters } from 'jsondiffpatch';
-import ReactHtmlParser from 'react-html-parser';
-import { useStoreContext } from '../store';
-
-interface DiffProps {
- snapshot: {state?:Record};
- show?: boolean|undefined;
-}
-/**
- * Displays tree showing specific two versions of tree
- * one with specific state changes, the other the whole tree
- * @param props props from maincontainer
- * @returns a diff tree or a string stating no state changes have happened
- */
-function Diff(props: DiffProps) {
- const { snapshot, show } = props;
- const [mainState] = useStoreContext();
- const { currentTab, tabs } = mainState; // k/v pairs of mainstate store object being created
- const { snapshots, viewIndex, sliderIndex } = tabs[currentTab];
- let previous;
-
- // previous follows viewIndex or sliderIndex
- if (viewIndex !== -1) { // if tab isnt selected, view index is set to -1
- previous = snapshots[viewIndex - 1];
- } else {
- previous = snapshots[sliderIndex - 1];
- }
-
- // cleaning preview from stateless data
- const statelessCleanning = (obj:{name?:string; componentData?: Record; state?:string| any; stateSnaphot?: Record; children?: any[]}) => {
- const newObj = { ...obj };
- if (newObj.name === 'nameless') {
- delete newObj.name;
- }
- if (newObj.componentData) {
- delete newObj.componentData;
- }
- if (newObj.state === 'stateless') {
- delete newObj.state;
- }
- if (newObj.stateSnaphot) {
- newObj.stateSnaphot = statelessCleanning(obj.stateSnaphot);
- }
- if (newObj.children) {
- newObj.children = [];
- if (obj.children.length > 0) {
- obj.children.forEach((element:{state?: Record | string; children?:[]}) => {
- if (element.state !== 'stateless' || element.children.length > 0) {
- const clean = statelessCleanning(element);
- newObj.children.push(clean);
- }
- });
- }
- }
- return newObj;
- };
-
- // displays stateful data
- const previousDisplay = statelessCleanning(previous);
- // diff function returns a comparison of two objects, one has an updated change
- // just displays stateful data
- const delta = diff(previousDisplay, snapshot);
- // returns html in string
- // just displays stateful data
- const html = formatters.html.format(delta, previousDisplay);
- if (show) formatters.html.showUnchanged();
- else formatters.html.hideUnchanged();
-
- if (previous === undefined || delta === undefined) {
- return No state change detected. Trigger an event to change state.
;
- }
- return {ReactHtmlParser(html)}
;
-}
-
-export default Diff;
diff --git a/src/app/components/DiffRoute.tsx b/src/app/components/DiffRoute.tsx
deleted file mode 100644
index 0f5111dd8..000000000
--- a/src/app/components/DiffRoute.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import React from 'react';
-import {
- MemoryRouter as Router, Route, NavLink, Switch,
-} from 'react-router-dom';
-import Diff from './Diff';
-
-interface DiffRouteProps{
- snapshot: Record;
- state?: string | unknown
- stateSnaphot?: Record;
- children?: unknown[];
- }>;
-}
-
-const DiffRoute = (props: DiffRouteProps): JSX.Element => (
-
-
-
-
- Tree
-
-
- Raw
-
-
-
- } />
- } />
-
-
-);
-
-export default DiffRoute;
diff --git a/src/app/components/Dropdown.tsx b/src/app/components/Dropdown.tsx
deleted file mode 100644
index c27db6917..000000000
--- a/src/app/components/Dropdown.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-import Select from 'react-select';
-
-interface DropdownProps {
- selectedSpeed: { value: number; label: string },
- speeds: { value: number; label: string; }[];
- setSpeed: () => void;
-}
-
-const Dropdown = (props: DropdownProps): JSX.Element => {
- const { speeds, setSpeed, selectedSpeed } = props;
- return (
-
- );
-};
-
-export default Dropdown;
diff --git a/src/app/components/ErrorHandler.tsx b/src/app/components/ErrorHandler.tsx
deleted file mode 100644
index 197b252a2..000000000
--- a/src/app/components/ErrorHandler.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-
-class ErrorHandler extends React.Component {
- constructor(props:unknown) {
- super(props);
- this.state = { errorOccurred: false };
- }
-
- componentDidCatch(error: string, info: string): void {
- this.setState({ errorOccurred: true });
- }
-
- render(): JSX.Element {
- const { errorOccurred } = this.state;
- // eslint-disable-next-line react/prop-types
- const { children } = this.props;
- return errorOccurred ? Unexpected Error
: children;
- }
-}
-
-export default ErrorHandler;
diff --git a/src/app/components/ErrorMsg.tsx b/src/app/components/ErrorMsg.tsx
deleted file mode 100644
index 4fb80f367..000000000
--- a/src/app/components/ErrorMsg.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/* eslint-disable react/prop-types */
-import React from 'react';
-
-// parses loadingArray and status and returns the correct message
-function parseError(loadingArray: [], status: any): string {
- let stillLoading = true;
- loadingArray.forEach(e => { if (e === false) stillLoading = false; });
- // As long as everything is still loading dont diplay an error message
- if (stillLoading) return 'default';
- // Return first status that fails
- if (!status.contentScriptLaunched) return 'Content Script Error';
- if (!status.reactDevToolsInstalled) return 'RDT Error';
- if (!status.targetPageisaReactApp) return 'Not React App';
- return 'default';
-}
-
-function ErrorMsg({
- loadingArray, status, launchContent,
-}): JSX.Element {
- switch (parseError(loadingArray, status)) {
- case 'Content Script Error':
- return (
-
- Could not connect to the Target App. Try closing Reactime and reloading the page.
-
- NOTE: By default Reactime only launches the content script on URLS starting with localhost.
-
- If your target URL does not match, you can manually launch the content script below.
-
-
- Launch
-
- );
- case 'RDT Error':
- return (
-
- );
- case 'Not React App':
- return (
-
- The Target app is either not a React application or is not compatible with Reactime
-
- );
- default:
- return null;
- }
-}
-
-export default ErrorMsg;
diff --git a/src/app/components/FrontendTypes.ts b/src/app/components/FrontendTypes.ts
deleted file mode 100644
index 1deaf9269..000000000
--- a/src/app/components/FrontendTypes.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-import { SeriesPoint } from '@visx/shape/lib/types';
-
-// PerformanceVisx types
-
-export interface Series {
- data: {
- barStack: ActionObj[],
- }
- name: string
- }
-
-// interface Event {
-// target: EventTarget
-// }
-
-// interface EventTarget {
-// x: WithParentSizeProvidedProps,
-// y: OptionalKeys,
-// value?: idk
-// }
-
-export interface ActionObj {
- name: string,
- seriesName: string,
- currentTab: string,
- }
-
-export interface PerfData {
- barStack: BarStackProp[],
- componentData?: Record,
- maxTotalRender: number,
-}
-
-export interface BarStackProp {
- snapshotId: string,
- route: string,
- currentTab?: string,
-}
-
-// On-hover data for BarGraph/BarGraphComparison.tsx
-export interface TooltipData {
- bar: SeriesPoint;
- key: string;
- index: number;
- height: number;
- width: number;
- x: number;
- y: number;
- color: string;
-}
-
-export interface snapshot {
- snapshotId?: string;
- children: [];
- componentData: { actualDuration: number } | undefined;
- name: string;
- state: string;
-}
-
-export interface Margin {
- top: number;
- right: number;
- bottom: number;
- left: number;
-}
-
-export interface BarGraphBase {
- width: number,
- height: number,
- data: PerfData,
- comparison: Series[],
-}
-
-export interface BarGraphComparisonProps extends BarGraphBase {
- setSeries: (e: boolean | string) => void,
- series: number,
- setAction: (e: boolean | string) => void,
-}
-
-export interface BarGraphProps extends BarGraphBase{
- setRoute: () => void,
- allRoutes: unknown,
- filteredSnapshots: unknown,
- snapshot: unknown,
- setSnapshot: () => void
-}
-
-export interface BarGraphComparisonAction{
- action: ActionObj,
- data: ActionObj[],
- width: number,
- height: number,
- comparison: Series[],
- setSeries: (e: boolean | string) => void,
- series?: number,
- setAction: (e: boolean | string) => void,
-}
-
diff --git a/src/app/components/JsonSection/JsonSection.tsx b/src/app/components/JsonSection/JsonSection.tsx
new file mode 100644
index 000000000..56128a3e7
--- /dev/null
+++ b/src/app/components/JsonSection/JsonSection.tsx
@@ -0,0 +1,68 @@
+import React from 'react';
+import { JSONTree } from 'react-json-tree';
+import { jsonTheme, parseStringifiedValues } from '../../utils/providerUtils';
+
+interface JsonSectionProps {
+ title?: string | null;
+ content: any;
+ isReducer?: boolean;
+}
+
+const formatReducerData = (data: any) => {
+ const formattedData: Record = {};
+ if (typeof data === 'object' && data !== null) {
+ Object.entries(data).forEach(([key, value]) => {
+ if (value && typeof value === 'object') {
+ formattedData[key] = value;
+ }
+ });
+ }
+ return formattedData;
+};
+
+const JsonSection = ({ title, content, isReducer = false }: JsonSectionProps): JSX.Element | null => {
+ if (
+ !content ||
+ (Array.isArray(content) && content.length === 0) ||
+ Object.keys(content).length === 0
+ ) {
+ return null;
+ }
+
+ // Parse any stringified JSON before displaying
+ const parsedContent = parseStringifiedValues(content);
+
+ if (isReducer && parsedContent) {
+ // Only try to format if we have valid content
+ const formattedData = formatReducerData(parsedContent);
+
+ // Check if we have any formatted data to display
+ if (Object.keys(formattedData).length === 0) {
+ return null;
+ }
+
+ return (
+
+ {Object.entries(formattedData).map(([hookName, state]) => (
+
+
{hookName}
+
+ true} />
+
+
+ ))}
+
+ );
+ }
+
+ return (
+
+ {title &&
{title}
}
+
+ true} />
+
+
+ );
+};
+
+export default JsonSection;
\ No newline at end of file
diff --git a/src/app/components/Loader.tsx b/src/app/components/Loader.tsx
deleted file mode 100644
index ee24a3310..000000000
--- a/src/app/components/Loader.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-/* eslint-disable react/prop-types */
-
-import React from 'react';
-import { css } from '@emotion/react';
-import { ClipLoader } from 'react-spinners';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faCheck, faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
-
-const override = css`
- display: inline;
- margin: 0 auto;
-`;
-
-// Displays the result of the check when loading is done
-const handleResult = (result: boolean): JSX.Element => (result
- ?
- :
-);
-
-// Returns the Loader component
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
-const Loader = ({
- loading,
- result,
-}): JSX.Element => (loading ? (
-
-) : handleResult(result));
-
-export default Loader;
diff --git a/src/app/components/MainSlider.tsx b/src/app/components/MainSlider.tsx
deleted file mode 100644
index 2a4994ca2..000000000
--- a/src/app/components/MainSlider.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import Slider from 'rc-slider';
-import Tooltip from 'rc-tooltip';
-import { changeSlider, pause } from '../actions/actions';
-import { useStoreContext } from '../store';
-
-const { Handle } = Slider;
-
-interface handleProps {
- value: number,
- dragging: boolean,
- index: number
-}
-
-const handle = (props: handleProps) => {
- const {
- value, dragging, index, ...restProps
- } = props;
-
- return (
-
-
-
- );
-};
-
-interface MainSliderProps {
- snapshotsLength: number;
-}
-
-function MainSlider(props: MainSliderProps) {
- const { snapshotsLength } = props;
- const [{ tabs, currentTab }, dispatch] = useStoreContext();
- const { currLocation } = tabs[currentTab];
- const [sliderIndex, setSliderIndex] = useState(0);
-
- useEffect(() => {
- if (currLocation) {
- setSliderIndex(currLocation.index);
- } else {
- setSliderIndex(0);
- }
- }, [currLocation]);
-
- return (
- {
- setSliderIndex(index);
- }}
- onAfterChange={() => {
- dispatch(changeSlider(sliderIndex));
- dispatch(pause());
- }}
- handle={handle}
- />
- );
-}
-
-export default MainSlider;
diff --git a/src/app/components/RouteDescription.tsx b/src/app/components/RouteDescription.tsx
deleted file mode 100644
index afc318795..000000000
--- a/src/app/components/RouteDescription.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-
-type RouteProps = {
- actions: JSX.Element[],
-}
-
-const RouteDescription = (props: RouteProps): JSX.Element => {
- // Use new URL to use the url.pathname method.
- const { actions } = props;
- const url = new URL(actions[0].props.routePath);
- return (
-
-
- Route: {url.pathname}
-
- {actions}
-
- );
-};
-
-export default RouteDescription;
diff --git a/src/app/components/StateRoute/AxMap/Ax.tsx b/src/app/components/StateRoute/AxMap/Ax.tsx
new file mode 100644
index 000000000..9da91cea8
--- /dev/null
+++ b/src/app/components/StateRoute/AxMap/Ax.tsx
@@ -0,0 +1,425 @@
+import React, { useState, useRef, useEffect } from 'react';
+import { useDispatch } from 'react-redux';
+import { Group } from '@visx/group';
+import { hierarchy, Tree } from '@visx/hierarchy';
+import { LinearGradient } from '@visx/gradient';
+import LinkControls from './axLinkControls';
+import getLinkComponent from './getAxLinkComponents';
+import { useTooltip, useTooltipInPortal, defaultStyles } from '@visx/tooltip';
+import ToolTipDataDisplay from './ToolTipDataDisplay';
+import { ToolTipStyles } from '../../../FrontendTypes';
+import { localPoint } from '@visx/event';
+import { toggleExpanded, setCurrentTabInApp } from '../../../slices/mainSlice';
+
+const defaultMargin = {
+ top: 30,
+ left: 20,
+ right: 50,
+ bottom: 20,
+};
+
+const nodeCoords: object = {};
+let count: number = 0;
+let aspect: number = 1; // aspect resizes the component map container to accommodate large node trees on complex sites
+let nodeCoordTier = 0;
+let nodeOneLeft = 0;
+let nodeTwoLeft = 2;
+
+export type LinkTypesProps = {
+ width: number;
+ height: number;
+ margin?: { top: number; right: number; bottom: number; left: number };
+};
+
+export default function AxTree(props) {
+ const { currLocation, axSnapshots, width, height, setShowTree, setShowParagraph } = props;
+
+ let margin = defaultMargin;
+ let totalWidth = width;
+ let totalHeight = height;
+
+ if (axSnapshots[currLocation.index] === 'emptyAxSnap') return;
+
+ const toolTipTimeoutID = useRef(null); //useRef stores stateful data that’s not needed for rendering.
+ const {
+ tooltipData, // value/data that tooltip may need to render
+ tooltipLeft, // number used for tooltip positioning
+ tooltipTop, // number used for tooltip positioning
+ tooltipOpen, // boolean whether the tooltip state is open or closed
+ showTooltip, // function to set tooltip state
+ hideTooltip, // function to close a tooltip
+ } = useTooltip(); // returns an object with several properties that you can use to manage the tooltip state of your component
+
+ const {
+ containerRef, // Access to the container's bounding box. This will be empty on first render.
+ TooltipInPortal, // TooltipWithBounds in a Portal, outside of your component DOM tree
+ } = useTooltipInPortal({
+ // Visx hook
+ detectBounds: true, // use TooltipWithBounds
+ scroll: true, // when tooltip containers are scrolled, this will correctly update the Tooltip position
+ });
+
+ const tooltipStyles: ToolTipStyles = {
+ ...defaultStyles,
+ minWidth: 60,
+ maxWidth: 250,
+ maxHeight: '300px',
+ lineHeight: '18px',
+ pointerEvents: 'all !important',
+ margin: 0,
+ padding: 0,
+ borderRadius: '8px',
+ overflowY: 'auto',
+ overflowX: 'auto',
+ backgroundColor: 'transparent',
+ };
+
+ const [orientation, setOrientation] = useState('horizontal');
+ const [linkType, setLinkType] = useState('diagonal');
+ const [stepPercent, setStepPercent] = useState(0.0);
+
+ const innerWidth: number = totalWidth - margin.left - margin.right;
+ const innerHeight: number = totalHeight - margin.top - margin.bottom - 60;
+
+ let origin: { x: number; y: number };
+ let sizeWidth: number;
+ let sizeHeight: number;
+
+ origin = { x: 0, y: 0 };
+ if (orientation === 'vertical') {
+ sizeWidth = innerWidth;
+ sizeHeight = innerHeight;
+ } else {
+ sizeWidth = innerHeight;
+ sizeHeight = innerWidth;
+ }
+
+ const LinkComponent = getLinkComponent({ linkType, orientation });
+
+ const currAxSnapshot = JSON.parse(JSON.stringify(axSnapshots[currLocation.index]));
+
+ // root node of currAxSnapshot
+ const rootAxNode = JSON.parse(JSON.stringify(currAxSnapshot[0]));
+
+ // array that holds each ax tree node with children property
+ const nodeAxArr = [];
+
+ // populates ax nodes with children property; visx recognizes 'children' in order to properly render a nested tree
+ const organizeAxTree = (currNode, currAxSnapshot) => {
+ // checks if current ax node has children nodes through childId
+ if (currNode.childIds && currNode.childIds.length > 0) {
+ // if yes, add children property to current ax node
+ currNode.children = [];
+ for (let j = 0; j < currAxSnapshot.length; j++) {
+ // locate ax node associated with childId
+ for (const childEle of currNode.childIds) {
+ if (childEle === currAxSnapshot[j].nodeId) {
+ // store ax node in children array
+ currNode.children.push(currAxSnapshot[j]);
+ // recursively call organizeAxTree with child ax node passed in to check for further nested children nodes
+ organizeAxTree(currAxSnapshot[j], currAxSnapshot);
+ }
+ }
+ }
+ }
+ };
+
+ organizeAxTree(rootAxNode, currAxSnapshot);
+
+ // stores each individual ax node with populated children property in array
+ const populateNodeAxArr = (currNode) => {
+ nodeAxArr.splice(0, nodeAxArr.length);
+ nodeAxArr.push(currNode);
+ for (let i = 0; i < nodeAxArr.length; i += 1) {
+ // iterate through the nodeAxArr that contains the root ax node
+ const cur = nodeAxArr[i];
+ if (cur.children && cur.children.length > 0) {
+ // if the current ax node evaluated has non-zero children...
+ for (const child of cur.children) {
+ // iterate through each child ax node in the children array
+ nodeAxArr.push(child); // add the child to the nodeAxArr
+ }
+ }
+ }
+ };
+
+ populateNodeAxArr(rootAxNode);
+
+ // Conditionally render ax legend component (RTK)
+ const dispatch = useDispatch();
+
+ useEffect(() => {
+ dispatch(setCurrentTabInApp('Axtree')); // dispatch sent at initial page load allowing changing
+ }, [dispatch]);
+
+ return totalWidth < 10 ? null : (
+
+
+
+
+
+
+
+
+ {
+ hideTooltip();
+ }}
+ />
+
+ (d.isExpanded ? null : d.children))}
+ size={[sizeWidth / aspect, sizeHeight / aspect]}
+ separation={(a, b) => (a.parent === b.parent ? 0.5 : 0.5) / a.depth}
+ >
+ {(tree) => (
+
+ {tree.links().map((link, i) => (
+
+ ))}
+ {tree.descendants().map((node, key) => {
+ const widthFunc = (name): number => {
+ // returns a number that is related to the length of the name. Used for determining the node width.
+ const nodeLength = name.length;
+ if (nodeLength <= 5) return nodeLength + 60;
+ if (nodeLength <= 10) return nodeLength + 130;
+ return nodeLength + 160;
+ };
+
+ const width: number = widthFunc(node.data.name.value); // the width is determined by the length of the node.name
+ const height: number = 25;
+ let top: number;
+ let left: number;
+
+ if (orientation === 'vertical') {
+ top = node.y;
+ left = node.x;
+ } else {
+ top = node.x;
+ left = node.y;
+ }
+
+ //setup a nodeCoords Object that will have keys of unique y coordinates and value arrays of all the left and right x coordinates of the nodes on that level
+ count < nodeAxArr.length
+ ? !nodeCoords[top]
+ ? (nodeCoords[top] = [left - width / 2, left + width / 2])
+ : nodeCoords[top].push(left - width / 2, left + width / 2)
+ : null;
+ count++;
+
+ if (count === nodeAxArr.length) {
+ //check if there is still a tier of the node tree to collision check
+ while (Object.values(nodeCoords)[nodeCoordTier]) {
+ //check if there are atleast two nodes on the current tier
+ if (
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft] &&
+ Object.values(nodeCoords)[nodeCoordTier][nodeTwoLeft]
+ ) {
+ //check if the left side of the righthand node is to the right of the right side of the lefthand node (i.e. collision)
+ if (
+ Object.values(nodeCoords)[nodeCoordTier][nodeTwoLeft] <
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft + 1]
+ ) {
+ //check if the visible percentage of the left hand node is less than the current lowest (this will be used to resize and rescale the map)
+ if (
+ Math.abs(
+ Object.values(nodeCoords)[nodeCoordTier][nodeTwoLeft] -
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft],
+ ) /
+ Math.abs(
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft + 1] -
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft],
+ ) <
+ aspect
+ ) {
+ //assign a new lowest percentage if one is found
+ aspect =
+ Math.abs(
+ Object.values(nodeCoords)[nodeCoordTier][nodeTwoLeft] -
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft],
+ ) /
+ Math.abs(
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft + 1] -
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft],
+ );
+ }
+ //move the node pointers down the list after checking the current overlap percentage
+ else {
+ nodeOneLeft += 2;
+ nodeTwoLeft += 2;
+ }
+ }
+ //move the node pointers if no collision is found
+ else {
+ nodeOneLeft += 2;
+ nodeTwoLeft += 2;
+ }
+ }
+ //move to the next tier of the node tree if done checking the current one
+ else {
+ nodeOneLeft = 0;
+ nodeTwoLeft = 2;
+ nodeCoordTier++;
+ }
+ }
+ } else {
+ aspect = Math.max(aspect, 0.5);
+ }
+ const handleMouseAndClickOver = (event): void => {
+ const coords = localPoint(event.target.ownerSVGElement, event);
+ const tooltipObj = { ...node.data };
+
+ showTooltip({
+ tooltipLeft: coords.x,
+ tooltipTop: coords.y,
+ tooltipData: tooltipObj,
+ // this is where the data for state and render time is displayed
+ // but does not show props functions and etc
+ });
+ };
+
+ return (
+
+ {node.depth === 0 && (
+ {
+ dispatch(toggleExpanded(node.data));
+ hideTooltip();
+ }}
+ />
+ )}
+ {node.depth !== 0 && (
+ {
+ dispatch(toggleExpanded(node.data));
+ hideTooltip();
+ }}
+ // Mouse Enter Rect (Component Node) -----------------------------------------------------------------------
+ /** This onMouseEnter event fires when the mouse first moves/hovers over a component node.
+ * The supplied event listener callback produces a Tooltip element for the current node. */
+
+ onMouseEnter={(event) => {
+ /** This 'if' statement block checks to see if you've just left another component node
+ * by seeing if there's a current setTimeout waiting to close that component node's
+ * tooltip (see onMouseLeave immediately below). If so it clears the tooltip generated
+ * from that component node so a new tooltip for the node you've just entered can render. */
+ if (toolTipTimeoutID.current !== null) {
+ clearTimeout(toolTipTimeoutID.current);
+ hideTooltip();
+ }
+ // Removes the previous timeoutID to avoid errors
+ toolTipTimeoutID.current = null;
+ //This generates a tooltip for the component node the mouse has entered.
+ handleMouseAndClickOver(event);
+ }}
+ // Mouse Leave Rect (Component Node) --------------------------------------------------------------------------
+ /** This onMouseLeave event fires when the mouse leaves a component node.
+ * The supplied event listener callback generates a setTimeout call which gives the
+ * mouse a certain amount of time between leaving the current component node and
+ * closing the tooltip for that node.
+ * If the mouse enters the tooltip before the timeout delay has passed, the
+ * setTimeout event will be canceled. */
+ onMouseLeave={() => {
+ // Store setTimeout ID so timeout can be cleared if necessary
+ toolTipTimeoutID.current = setTimeout(() => {
+ // hideTooltip unmounts the tooltip
+ hideTooltip();
+ toolTipTimeoutID.current = null;
+ }, 300);
+ }}
+ />
+ )}
+
+ {node.data.name.value}
+
+
+ );
+ })}
+
+ )}
+
+
+
+ {tooltipOpen && tooltipData && (
+
{
+ clearTimeout(toolTipTimeoutID.current);
+ toolTipTimeoutID.current = null;
+ }}
+ //------------- Mouse Leave TooltipInPortal -----------------------------------------------------------------
+ /** When the mouse leaves the tooltip, the tooltip unmounts */
+ onMouseLeave={() => {
+ hideTooltip();
+ }}
+ >
+
+
+
{tooltipData['name'].value}
+
+
+ {/* Ax Node Info below names the tooltip title because of how its passed to the ToolTipDataDisplay container*/}
+
+
+
+
+ )}
+
+ );
+}
diff --git a/src/app/components/StateRoute/AxMap/AxContainer.tsx b/src/app/components/StateRoute/AxMap/AxContainer.tsx
new file mode 100644
index 000000000..1edbba476
--- /dev/null
+++ b/src/app/components/StateRoute/AxMap/AxContainer.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import { ParentSize } from '@visx/responsive';
+import AxTree from './Ax';
+import type { AxContainer } from '../../../FrontendTypes';
+
+// Container to hold AxTree. AxTree is conditionally rendered based on the state of the setter function "showTree" in StateRoute
+
+const AxContainer = (props: AxContainer) => {
+ const {
+ axSnapshots, // from 'tabs[currentTab]' object in 'MainContainer'
+ snapshot, // from 'tabs[currentTab]' object in 'MainContainer'
+ snapshots, // from 'tabs[currentTab].snapshotDisplay' object in 'MainContainer'
+ currLocation, // from 'tabs[currentTab]' object in 'MainContainer'
+ setShowTree,
+ setShowParagraph,
+ } = props;
+
+ return (
+
+
+ {({ width, height }) => {
+ // eslint-disable-next-line react/prop-types
+ const maxHeight: number = 1200;
+ const h = Math.min(height, maxHeight);
+ return (
+
+ );
+ }}
+
+
+ );
+};
+
+export default AxContainer;
diff --git a/src/app/components/StateRoute/AxMap/ToolTipDataDisplay.tsx b/src/app/components/StateRoute/AxMap/ToolTipDataDisplay.tsx
new file mode 100644
index 000000000..eb942dbd3
--- /dev/null
+++ b/src/app/components/StateRoute/AxMap/ToolTipDataDisplay.tsx
@@ -0,0 +1,81 @@
+import React from 'react';
+import { JSONTree } from 'react-json-tree';
+
+/*
+ Code that show's the tooltip of our JSON tree
+*/
+
+const colors = {
+ scheme: 'paraiso',
+ author: 'jan t. sott',
+ base00: '#2f1e2e',
+ base01: '#41323f',
+ base02: '#4f424c',
+ base03: '#776e71',
+ base04: '#8d8687',
+ base05: '#a39e9b',
+ base06: '#b9b6b0',
+ base07: '#e7e9db',
+ base08: '#ef6155',
+ base09: '#824508',
+ base0A: '#fec418',
+ base0B: '#48b685',
+ base0C: '#5bc4bf',
+ base0D: '#06b6ef',
+ base0E: '#815ba4',
+ base0F: '#e96ba8',
+};
+
+const ToolTipDataDisplay = ({ containerName, dataObj }) => {
+ const printableObject = {}; // The key:value properties of printableObject will be rendered in the JSON Tree
+
+ if (!dataObj) {
+ // If state is null rather than an object, print "State: null" in tooltip
+ printableObject[containerName] = dataObj;
+ } else {
+ /*
+ Props often contain circular references.
+ Messages from the backend must be sent as JSON objects (strings).
+ JSON objects can't contain circular ref's, so the backend filters out problematic values by stringifying the values of object properties and ignoring any values that fail the conversion due to a circular ref. The following logic converts these values back to JS so they display clearly and are collapsible.
+ */
+ const data = {};
+ //ignored false vs true
+ //ignored reasons here
+ //&& key = name? / order?
+ for (const key in dataObj) {
+ if (key === 'properties' || key === 'ignored' || key === 'ignoredReasons') {
+ // loop through properties, adding them to the data object
+
+ if (typeof dataObj[key] === 'string') {
+ //if 'key' is ignored, put the ignored key and its value on the data object
+ //if ignoredReasons has length it should loop through adding the reasons names to the data object
+ //actually might only need to give it the properties and ignored and ignored reasons and it'll take care of the rest
+ try {
+ data[key] = JSON.parse(dataObj[key]);
+ } catch {
+ data[key] = dataObj[key];
+ }
+ } else {
+ data[key] = dataObj[key];
+ }
+ }
+ }
+ /*
+ Adds container name (State, Props, future different names for hooks) at top of object so everything nested in it will collapse when you click on it.
+ */
+ printableObject[containerName] = data;
+ }
+
+ return (
+
+ ({ className: `tooltipData-JSONTree` }) }} // theme set to a base16 theme that has been extended to include "className: 'json-tree'"
+ shouldExpandNodeInitially={() => true} // determines if node should be expanded when it first renders (root is expanded by default)
+ hideRoot={true} // hides the root node
+ />
+
+ );
+};
+
+export default ToolTipDataDisplay;
diff --git a/src/app/components/StateRoute/AxMap/axLinkControls.tsx b/src/app/components/StateRoute/AxMap/axLinkControls.tsx
new file mode 100644
index 000000000..650e8e55e
--- /dev/null
+++ b/src/app/components/StateRoute/AxMap/axLinkControls.tsx
@@ -0,0 +1,83 @@
+import React from 'react';
+import { useDispatch } from 'react-redux';
+import { toggleAxTree, setCurrentTabInApp } from '../../../slices/mainSlice';
+
+const AxLinkControls = ({
+ orientation,
+ linkType,
+ stepPercent,
+ setOrientation,
+ setLinkType,
+ setStepPercent,
+ setShowTree,
+ setShowParagraph,
+}) => {
+ const dispatch = useDispatch();
+ const disableAxTree = () => {
+ dispatch(toggleAxTree('toggleAxRecord'));
+ setShowTree(false);
+ setShowParagraph(true);
+ };
+
+ return (
+
+
+
+ Disable
+
+
+
+ Orientation:
+ e.stopPropagation()}
+ onChange={(e) => setOrientation(e.target.value)}
+ value={orientation}
+ >
+ Vertical
+ Horizontal
+
+
+
+
+ Link:
+ e.stopPropagation()}
+ onChange={(e) => setLinkType(e.target.value)}
+ value={linkType}
+ >
+ Diagonal
+ Step
+ Curve
+ Line
+
+
+
+ {linkType === 'step' && (
+
+ Step:
+ e.stopPropagation()}
+ type='range'
+ min={0}
+ max={1}
+ step={0.1}
+ onChange={(e) => setStepPercent(Number(e.target.value))}
+ value={stepPercent}
+ disabled={linkType !== 'step'}
+ className='control-range'
+ />
+
+ )}
+
+ );
+};
+
+export default AxLinkControls;
diff --git a/src/app/components/StateRoute/AxMap/getAxLinkComponents.tsx b/src/app/components/StateRoute/AxMap/getAxLinkComponents.tsx
new file mode 100644
index 000000000..26ce0426f
--- /dev/null
+++ b/src/app/components/StateRoute/AxMap/getAxLinkComponents.tsx
@@ -0,0 +1,46 @@
+import { ComponentType } from 'react';
+import {
+ LinkHorizontal,
+ LinkVertical,
+ LinkRadial,
+ LinkHorizontalStep,
+ LinkVerticalStep,
+ LinkRadialStep,
+ LinkHorizontalCurve,
+ LinkVerticalCurve,
+ LinkRadialCurve,
+ LinkHorizontalLine,
+ LinkVerticalLine,
+ LinkRadialLine,
+} from '@visx/shape';
+
+export default function getLinkComponent({
+ linkType,
+ orientation,
+}: {
+ linkType: string;
+ orientation: string;
+}) {
+ let LinkComponent;
+
+ if (orientation === 'vertical') {
+ if (linkType === 'step') {
+ LinkComponent = LinkVerticalStep;
+ } else if (linkType === 'curve') {
+ LinkComponent = LinkVerticalCurve;
+ } else if (linkType === 'line') {
+ LinkComponent = LinkVerticalLine;
+ } else {
+ LinkComponent = LinkVertical;
+ }
+ } else if (linkType === 'step') {
+ LinkComponent = LinkHorizontalStep;
+ } else if (linkType === 'curve') {
+ LinkComponent = LinkHorizontalCurve;
+ } else if (linkType === 'line') {
+ LinkComponent = LinkHorizontalLine;
+ } else {
+ LinkComponent = LinkHorizontal;
+ }
+ return LinkComponent;
+}
diff --git a/src/app/components/StateRoute/ComponentMap/ComponentMap.tsx b/src/app/components/StateRoute/ComponentMap/ComponentMap.tsx
index 00d5ae110..140f04d35 100644
--- a/src/app/components/StateRoute/ComponentMap/ComponentMap.tsx
+++ b/src/app/components/StateRoute/ComponentMap/ComponentMap.tsx
@@ -8,56 +8,70 @@
/* eslint-disable guard-for-in */
// @ts-nocheck
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useRef } from 'react';
import { Group } from '@visx/group';
import { hierarchy, Tree } from '@visx/hierarchy';
import { LinearGradient } from '@visx/gradient';
import { pointRadial } from 'd3-shape';
import { localPoint } from '@visx/event';
-import {
- useTooltip,
- useTooltipInPortal,
- defaultStyles,
-} from '@visx/tooltip';
+import { useTooltip, useTooltipInPortal, defaultStyles } from '@visx/tooltip';
import LinkControls from './LinkControls';
import getLinkComponent from './getLinkComponent';
-import { toggleExpanded, setCurrentTabInApp } from '../../../actions/actions';
-import { useStoreContext } from '../../../store';
+import ToolTipDataDisplay from './ToolTipDataDisplay';
+import { toggleExpanded, setCurrentTabInApp } from '../../../slices/mainSlice';
+import { useDispatch } from 'react-redux';
+import { LinkTypesProps, DefaultMargin, ToolTipStyles } from '../../../FrontendTypes';
-const exclude = ['childExpirationTime', 'staticContext', '_debugSource', 'actualDuration', 'actualStartTime', 'treeBaseDuration', '_debugID', '_debugIsCurrentlyTiming', 'selfBaseDuration', 'expirationTime', 'effectTag', 'alternate', '_owner', '_store', 'get key', 'ref', '_self', '_source', 'firstBaseUpdate', 'updateQueue', 'lastBaseUpdate', 'shared', 'responders', 'pending', 'lanes', 'childLanes', 'effects', 'memoizedState', 'pendingProps', 'lastEffect', 'firstEffect', 'tag', 'baseState', 'baseQueue', 'dependencies', 'Consumer', 'context', '_currentRenderer', '_currentRenderer2', 'mode', 'flags', 'nextEffect', 'sibling', 'create', 'deps', 'next', 'destroy', 'parentSub', 'child', 'key', 'return', 'children', '$$typeof', '_threadCount', '_calculateChangedBits', '_currentValue', '_currentValue2', 'Provider', '_context', 'stateNode', 'elementType', 'type'];
+let stroke = '';
-const defaultMargin = {
- top: 30, left: 30, right: 55, bottom: 70,
-};
+const lightWeight = '#94a3b8'; // Lightest gray for minimal props
+const mediumWeight = '#64748b'; // Medium gray for light prop load
+const heavyWeight = '#556579';
+const veryHeavy = '#475569'; // Darker gray for medium load
-export type LinkTypesProps = {
- width: number;
- height: number;
- margin?: { top: number; right: number; bottom: number; left: number };
- snapshots: Record;
- currentSnapshot?: Record
+const defaultMargin: DefaultMargin = {
+ top: 30,
+ left: 20,
+ right: 50,
+ bottom: 20,
};
+const nodeCoords: object = {};
+let count: number = 0;
+let aspect: number = 1;
+let nodeCoordTier = 0;
+let nodeOneLeft = 0;
+let nodeTwoLeft = 2;
+
export default function ComponentMap({
// imported props to be used to display the dendrogram
width: totalWidth,
height: totalHeight,
margin = defaultMargin,
- currentSnapshot,
+ currentSnapshot, // from 'tabs[currentTab].stateSnapshot object in 'MainContainer'
}: LinkTypesProps): JSX.Element {
- // importing custom hooks for the selection tabs.
- const [layout, setLayout] = useState('cartesian');
- const [orientation, setOrientation] = useState('vertical');
- const [linkType, setLinkType] = useState('diagonal');
- const [stepPercent, setStepPercent] = useState(10);
- const [Tooltip, setTooltip] = useState(false);
- const [selectedNode, setSelectedNode] = useState('root');
- const [, dispatch] = useStoreContext();
+ const [orientation, setOrientation] = useState('vertical'); // We create a local state "orientation" and set it to a string 'vertical'.
+ const [linkType, setLinkType] = useState('step'); // We create a local state "linkType" and set it to a string 'step'.
+ const [stepPercent, setStepPercent] = useState(0.0); // We create a local state "stepPercent" and set it to a number '0.0'. This will be used to scale the Map component's link: Step to 0%
+ const [selectedNode, setSelectedNode] = useState('root'); // We create a local state "selectedNode" and set it to a string 'root'.
+ const [forceUpdate, setForceUpdate] = useState(false);
+
+ const dispatch = useDispatch();
+
+ const toolTipTimeoutID = useRef(null); //useRef stores stateful data that’s not needed for rendering.
useEffect(() => {
- dispatch(setCurrentTabInApp('map'));
+ dispatch(setCurrentTabInApp('map')); // dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'map' to facilitate render.
}, [dispatch]);
+ // force app to re-render to accurately calculate aspect ratio upon initial load
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ setForceUpdate((prev) => !prev);
+ }, 100);
+ return () => clearTimeout(timer);
+ }, []);
+
// setting the margins for the Map to render in the tab window.
const innerWidth: number = totalWidth - margin.left - margin.right;
const innerHeight: number = totalHeight - margin.top - margin.bottom - 60;
@@ -66,241 +80,421 @@ export default function ComponentMap({
let sizeWidth: number;
let sizeHeight: number;
- // This sets the starting position for the root node on the maps display.
- // the polar layout sets the root node to the relative center of the display box
- // based on the size of the browser window.
- // the else conditional statements determines the root nodes location either in the left middle
- // or top middle of the browser window relative to the size of the browser.
- if (layout === 'polar') {
- origin = {
- x: innerWidth / 2,
- y: innerHeight / 2,
- };
- sizeWidth = 2 * Math.PI;
- sizeHeight = Math.min(innerWidth, innerHeight) / 2;
+ /*
+ We begin setting the starting position for the root node on the maps display.
+ The default view sets the root nodes location either in the left middle *or top middle of the browser window relative to the size of the browser.
+ */
+
+ origin = { x: 0, y: 0 };
+ if (orientation === 'vertical') {
+ sizeWidth = innerWidth;
+ sizeHeight = innerHeight;
} else {
- origin = { x: 0, y: 0 };
- if (orientation === 'vertical') {
- sizeWidth = innerWidth;
- sizeHeight = innerHeight;
- } else {
- sizeWidth = innerHeight;
- sizeHeight = innerWidth;
- }
+ // if the orientation isn't vertical, swap the width and the height
+ sizeWidth = innerHeight;
+ sizeHeight = innerWidth;
}
+ //}
+ const {
+ tooltipData, // value/data that tooltip may need to render
+ tooltipLeft, // number used for tooltip positioning
+ tooltipTop, // number used for tooltip positioning
+ tooltipOpen, // boolean whether the tooltip state is open or closed
+ showTooltip, // function to set tooltip state
+ hideTooltip, // function to close a tooltip
+ } = useTooltip(); // returns an object with several properties that you can use to manage the tooltip state of your component
- // Tooltip stuff:
const {
- tooltipData,
- tooltipLeft,
- tooltipTop,
- tooltipOpen,
- showTooltip,
- hideTooltip,
- } = useTooltip();
-
- const { containerRef, TooltipInPortal } = useTooltipInPortal({
- detectBounds: true,
- scroll: true,
+ containerRef, // Access to the container's bounding box. This will be empty on first render.
+ TooltipInPortal, // TooltipWithBounds in a Portal, outside of your component DOM tree
+ } = useTooltipInPortal({
+ // Visx hook
+ detectBounds: true, // use TooltipWithBounds
+ scroll: true, // when tooltip containers are scrolled, this will correctly update the Tooltip position
});
- const tooltipStyles = {
+ const tooltipStyles: ToolTipStyles = {
...defaultStyles,
minWidth: 60,
- maxWidth: 300,
- backgroundColor: 'rgba(0,0,0,0.9)',
- color: 'white',
- fontSize: '14px',
+ maxWidth: 250,
+ maxHeight: '300px',
lineHeight: '18px',
- fontFamily: 'Roboto',
- zIndex: 100,
pointerEvents: 'all !important',
+ margin: 0,
+ padding: 0,
+ borderRadius: '8px',
+ overflowY: 'auto',
+ backgroundColor: 'transparent',
};
- const scrollStyle = {
- minWidth: '60',
- maxWidth: '300',
- minHeight: '20px',
- maxHeight: '200px',
- overflowY: 'scroll',
- overflowWrap: 'break-word',
- };
-
- const formatRenderTime = (time: number): string => {
- const renderTime = time.toFixed(3);
- return `${renderTime} ms `;
- };
+ const nodeList: [] = []; // create a nodeList array to store our nodes as a flat array
- const formatProps = data => {
- const propsFormat = [];
- const nestedObj = [];
- for (const key in data) {
- if (data[key] !== 'reactFiber' && typeof data[key] !== 'object' && exclude.includes(key) !== true) {
- propsFormat.push(
-
- {`${key}: ${data[key]}`}
-
,
- );
- } else if (data[key] !== 'reactFiber' && typeof data[key] === 'object' && exclude.includes(key) !== true) {
- const result = formatProps(data[key]);
- nestedObj.push(result);
+ const collectNodes: void = (node) => {
+ // function that takes in a node (snapshot) as it's argument and modifies 'nodeList' so that the node and it's children are all within the flattened 'nodeList'.
+ nodeList.splice(0, nodeList.length); // deletes all the nodes in nodelist
+ nodeList.push(node); // pushes the snapshot into nodeList
+ for (let i = 0; i < nodeList.length; i += 1) {
+ // iterate through the nodeList that contains our snapshot
+ const cur = nodeList[i];
+ if (cur.children && cur.children.length > 0) {
+ // if the currently itereated snapshot has non-zero children...
+ for (const child of cur.children) {
+ // iterate through each child in the children array
+ nodeList.push(child); // add the child to the nodeList
+ }
}
}
- if (nestedObj) {
- propsFormat.push(nestedObj);
- }
+ };
+
+ // check if any data should be displayed in tool tip display
+ const hasDisplayableData = (nodeData) => {
+ // Check if the node has props
+ const hasProps =
+ nodeData.componentData?.props && Object.keys(nodeData.componentData.props).length > 0;
+
+ // Check if the node has state
+ const hasState =
+ (nodeData.componentData?.state && Object.keys(nodeData.componentData.state).length > 0) ||
+ (nodeData.componentData?.hooksState &&
+ Object.keys(nodeData.componentData.hooksState).length > 0);
+
+ // Check if the node has reducer states
+ const hasReducers =
+ nodeData.componentData?.reducerStates && nodeData.componentData.reducerStates.length > 0;
- return propsFormat;
+ return hasProps || hasState || hasReducers;
};
- const formatContext = data => {
- const propsFormat = [];
- const nestedObj = [];
- for (const key in data) {
- propsFormat.push(
-
- {`${key}: ${data[key]}`}
-
,
- );
+ const shouldIncludeNode = (node) => {
+ // Return false if node has any context properties
+ if (node?.componentData?.context && Object.keys(node.componentData.context).length > 0) {
+ return false;
}
- return propsFormat;
+ // Return false if node name ends with 'Provider'
+ if (node?.name && node.name.endsWith('Provider')) {
+ return false;
+ }
+ return true;
};
- const formatState = state => {
- if (state === 'stateless') return ['stateless'];
- return ['stateful'];
- };
+ const processTreeData = (node) => {
+ if (!node) return null;
- // places all nodes into a flat array
- const nodeList = [];
+ // Create a new node
+ const newNode = { ...node };
- const collectNodes = node => {
- nodeList.splice(0, nodeList.length);
- nodeList.push(node);
- for (let i = 0; i < nodeList.length; i += 1) {
- const cur = nodeList[i];
- if (cur.children && cur.children.length > 0) {
- for (const child of cur.children) {
- nodeList.push(child);
+ if (node.children) {
+ // Process all children first
+ const processedChildren = node.children
+ .map((child) => processTreeData(child))
+ .filter(Boolean); // Remove null results
+
+ // For each child that shouldn't be included, replace it with its children
+ newNode.children = processedChildren.reduce((acc, child) => {
+ if (shouldIncludeNode(child)) {
+ // If child should be included, add it directly
+ acc.push(child);
+ } else {
+ // If child should be filtered out, add its children instead
+ if (child.children) {
+ acc.push(...child.children);
+ }
}
- }
+ return acc;
+ }, []);
}
+
+ return newNode;
};
- collectNodes(currentSnapshot);
+ // filter out Conext Providers
+ let filtered = processTreeData(currentSnapshot);
+ collectNodes(filtered);
+
// @ts
// find the node that has been selected and use it as the root
let startNode = null;
let rootNode;
+
const findSelectedNode = () => {
+ // iterates through each node of nodeList and sets the rootNode and startNode to a node with the name root
for (const node of nodeList) {
if (node.name === 'root') rootNode = node;
- if (node.name === selectedNode) startNode = node;
+ if (node.name === selectedNode) startNode = node; // selectedNode label initialized as 'root'
}
if (startNode === null) startNode = rootNode;
};
- findSelectedNode();
+
+ findSelectedNode(); // locates the rootNode
// controls for the map
- const LinkComponent = getLinkComponent({ layout, linkType, orientation });
+ const LinkComponent: React.ComponentType = getLinkComponent({
+ linkType,
+ orientation,
+ });
return totalWidth < 10 ? null : (
-
-
+
+
+
{
- setTooltip(false);
hideTooltip();
}}
- width={totalWidth}
- height={totalHeight}
+ width={sizeWidth / aspect}
+ height={sizeHeight / aspect + 0}
rx={14}
- fill="#242529"
/>
-
+
(d.isExpanded ? d.children : null))}
- size={[sizeWidth, sizeHeight]}
- separation={(a, b) => (a.parent === b.parent ? 1 : 0.5) / a.depth}
+ root={hierarchy(startNode, (d) => (d.isExpanded ? d.children : null))}
+ size={[sizeWidth / aspect, sizeHeight / aspect]}
+ separation={(a, b) => (a.parent === b.parent ? 0.5 : 0.5) / a.depth}
>
- {tree => (
-
- {tree.links().map((link, i) => (
-
- ))}
+ {(tree) => (
+
+ {tree.links().map((link, i) => {
+ const linkName = link.source.data.name;
+ const propsObj = link.source.data.componentData.props;
+ const childPropsObj = link.target.data.componentData.props;
+ let propsLength;
+ let childPropsLength;
+
+ if (propsObj) {
+ propsLength = Object.keys(propsObj).length;
+ }
+ if (childPropsObj) {
+ childPropsLength = Object.keys(childPropsObj).length;
+ }
+ // go to https://en.wikipedia.org/wiki/Logistic_function
+ // for an explanation of Logistic functions and parameters used
+ const yshift = -3;
+ const x0 = 5;
+ const L = 25;
+ const k = 0.4;
+ const strokeWidthIndex =
+ yshift + L / (1 + Math.exp(-k * (childPropsLength - x0)));
+
+ if (strokeWidthIndex <= 1) {
+ stroke = '#808080';
+ } else {
+ if (childPropsLength <= 1) {
+ stroke = lightWeight;
+ } else if (childPropsLength <= 2) {
+ stroke = mediumWeight;
+ } else if (childPropsLength <= 3) {
+ stroke = heavyWeight;
+ } else {
+ stroke = veryHeavy;
+ }
+ }
+
+ return (
+
+ );
+ })}
{tree.descendants().map((node, key) => {
- const widthFunc = name => {
- const nodeLength = name.length;
- if (nodeLength < 5) return nodeLength + 40;
- if (nodeLength < 10) return nodeLength + 60;
- return nodeLength + 70;
+ const calculateNodeWidth = (text: string): number => {
+ const nodeLength = text.length;
+ if (nodeLength <= 5) return nodeLength + 50;
+ if (nodeLength <= 10) return nodeLength + 120;
+ return nodeLength + 140;
};
- const width = widthFunc(node.data.name);
- const height = 25;
+ // Find the maximum width for any node
+ const findMaxNodeWidth = (nodeData: any): number => {
+ // If no children, return current node width
+ if (!nodeData.children) {
+ return calculateNodeWidth(nodeData.name);
+ }
+
+ // Get width of current node
+ const currentWidth = calculateNodeWidth(nodeData.name);
+
+ // Get max width from children
+ const childrenWidths = nodeData.children.map((child) =>
+ findMaxNodeWidth(child),
+ );
+
+ // Return the maximum width found
+ return Math.max(currentWidth, ...childrenWidths);
+ };
+
+ // Truncate text for nodes that exceed a certain length
+ const truncateText = (text: string, width: number, maxWidth: number): string => {
+ // Calculate approximate text width
+ const estimatedTextWidth = text.length * 8;
+
+ // If this node's width is close to the max width (within 10%), truncate it
+ if (width >= maxWidth * 0.9) {
+ const maxChars = Math.floor((width - 30) / 8); // -30 for padding + ellipsis
+ return `${text.slice(0, maxChars)}...`;
+ }
+
+ return text;
+ };
+
+ const getNodeDimensions = (
+ name: string,
+ rootNode: any,
+ ): { width: number; displayText: string } => {
+ const width = calculateNodeWidth(name);
+ const maxWidth = findMaxNodeWidth(rootNode);
+ const displayText = truncateText(name, width, maxWidth);
+
+ return { width, displayText };
+ };
+
+ // Usage in your render function:
+ const { width, displayText } = getNodeDimensions(node.data.name, startNode);
+
+ const height: number = 35;
let top: number;
let left: number;
- if (layout === 'polar') {
- const [radialX, radialY] = pointRadial(node.x, node.y);
- top = radialY;
- left = radialX;
- } else if (orientation === 'vertical') {
+
+ if (orientation === 'vertical') {
top = node.y;
left = node.x;
} else {
top = node.x;
left = node.y;
}
+ //setup a nodeCoords Object that will have keys of unique y coordinates and value arrays of all the left and right x coordinates of the nodes on that level
+ count < nodeList.length
+ ? !nodeCoords[top]
+ ? (nodeCoords[top] = [left - width / 2, left + width / 2])
+ : nodeCoords[top].push(left - width / 2, left + width / 2)
+ : null;
+ count++;
+
+ //check if the node coordinate object has been constructed
+ if (count === nodeList.length) {
+ //check if there is still a tier of the node tree to collision check
+ while (Object.values(nodeCoords)[nodeCoordTier]) {
+ //check if there are atleast two nodes on the current tier
+ if (
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft] &&
+ Object.values(nodeCoords)[nodeCoordTier][nodeTwoLeft]
+ ) {
+ //check if the left side of the righthand node is to the right of the right side of the lefthand node (i.e. collision)
+ if (
+ Object.values(nodeCoords)[nodeCoordTier][nodeTwoLeft] <
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft + 1]
+ ) {
+ //check if the visible percentage of the left hand node is less than the current lowest (this will be used to resize and rescale the map)
+ if (
+ Math.abs(
+ Object.values(nodeCoords)[nodeCoordTier][nodeTwoLeft] -
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft],
+ ) /
+ Math.abs(
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft + 1] -
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft],
+ ) <
+ aspect
+ ) {
+ //assign a new lowest percentage if one is found
+ aspect =
+ Math.abs(
+ Object.values(nodeCoords)[nodeCoordTier][nodeTwoLeft] -
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft],
+ ) /
+ Math.abs(
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft + 1] -
+ Object.values(nodeCoords)[nodeCoordTier][nodeOneLeft],
+ );
+ }
+ //move the node pointers down the list after checking the current overlap percentage
+ else {
+ nodeOneLeft += 2;
+ nodeTwoLeft += 2;
+ }
+ }
+ //move the node pointers if no collision is found
+ else {
+ nodeOneLeft += 2;
+ nodeTwoLeft += 2;
+ }
+ }
+ //move to the next tier of the node tree if done checking the current one
+ else {
+ nodeOneLeft = 0;
+ nodeTwoLeft = 2;
+ nodeCoordTier++;
+ }
+ }
+ } else {
+ aspect = Math.max(aspect, 1);
+ }
// mousing controls & Tooltip display logic
- const handleMouseAndClickOver = event => {
- const coords = localPoint(
- event.target.ownerSVGElement,
- event,
- );
- const tooltipObj = { ...node.data };
-
- showTooltip({
- tooltipLeft: coords.x,
- tooltipTop: coords.y,
- tooltipData: tooltipObj,
- // this is where the data for state and render time is displayed
- // but does not show props functions and etc
- });
+ const handleMouseAndClickOver = (event, nodeData) => {
+ // Only show tooltip if the node has data to display
+ if (hasDisplayableData(nodeData)) {
+ const coords = localPoint(event.target.ownerSVGElement, event);
+ const tooltipObj = { ...nodeData };
+
+ showTooltip({
+ tooltipLeft: coords.x,
+ tooltipTop: coords.y,
+ tooltipData: tooltipObj,
+ });
+ }
};
return (
-
+
+ // Replace the root node rect rendering block with this:
{node.depth === 0 && (
- {
dispatch(toggleExpanded(node.data));
hideTooltip();
- setTooltip(false);
+ }}
+ onMouseEnter={(event) => {
+ if (hasDisplayableData(node.data)) {
+ if (toolTipTimeoutID.current !== null) {
+ clearTimeout(toolTipTimeoutID.current);
+ hideTooltip();
+ }
+ toolTipTimeoutID.current = null;
+ handleMouseAndClickOver(event, node.data);
+ }
+ }}
+ onMouseLeave={() => {
+ if (hasDisplayableData(node.data)) {
+ toolTipTimeoutID.current = setTimeout(() => {
+ hideTooltip();
+ toolTipTimeoutID.current = null;
+ }, 300);
+ }
}}
/>
)}
@@ -308,49 +502,50 @@ export default function ComponentMap({
and sets it relative position to other parent nodes of the same level. */}
{node.depth !== 0 && (
0) ? '#ff6569' : '#4D4D4D'}
- strokeWidth={1.5}
- strokeOpacity="1"
- rx={node.children ? 4 : 10}
-
+ rx={10}
onClick={() => {
dispatch(toggleExpanded(node.data));
hideTooltip();
- setTooltip(false);
}}
-
- onMouseOver={event => {
- setTooltip(true);
- handleMouseAndClickOver(event);
+ onMouseEnter={(event) => {
+ if (hasDisplayableData(node.data)) {
+ if (toolTipTimeoutID.current !== null) {
+ clearTimeout(toolTipTimeoutID.current);
+ hideTooltip();
+ }
+ toolTipTimeoutID.current = null;
+ handleMouseAndClickOver(event, node.data);
+ }
}}
- // with onmouseOver, this produces a hover over effect for the Tooltip
- onMouseOut={() => {
- hideTooltip();
- setTooltip(false);
+ onMouseLeave={() => {
+ if (hasDisplayableData(node.data)) {
+ toolTipTimeoutID.current = setTimeout(() => {
+ hideTooltip();
+ toolTipTimeoutID.current = null;
+ }, 300);
+ }
}}
/>
)}
{/* Display text inside of each component node */}
- {node.data.name}
+ {displayText}
);
@@ -362,44 +557,24 @@ export default function ComponentMap({
{tooltipOpen && tooltipData && (
- {
- setTooltip(false);
+ onMouseEnter={() => {
+ clearTimeout(toolTipTimeoutID.current);
+ toolTipTimeoutID.current = null;
+ }}
+ onMouseLeave={() => {
hideTooltip();
}}
- >
-
- {' '}
-
{tooltipData.name}
- {' '}
+ >
+
+
+
{tooltipData.name}
- {' '}
- Render time:
- {' '}
- {formatRenderTime(tooltipData.componentData.actualDuration)}
- {' '}
-
-
- State:
- {formatState(tooltipData.state)}
-
-
-
-
Props:
- {formatProps(tooltipData.componentData.props)}
-
- {tooltipData.componentData.context &&
-
-
Context:
- {formatContext(tooltipData.componentData.context)}
- }
+
diff --git a/src/app/components/StateRoute/ComponentMap/LinkControls.tsx b/src/app/components/StateRoute/ComponentMap/LinkControls.tsx
index 344824c17..ceaa948fd 100644
--- a/src/app/components/StateRoute/ComponentMap/LinkControls.tsx
+++ b/src/app/components/StateRoute/ComponentMap/LinkControls.tsx
@@ -1,144 +1,133 @@
-/* eslint-disable jsx-a11y/label-has-associated-control */
import React from 'react';
-// Font size of the Controls label and Dropdowns
-const controlStyles = {
- fontSize: '12px',
- padding: '10px',
-};
-
-const dropDownStyle = {
- margin: '0.5em',
- fontSize: '12px',
- fontFamily: 'Roboto, sans-serif',
- borderRadius: '4px',
- borderStyle: 'solid',
- borderWidth: '1px',
- backgroundColor: '#242529',
- color: 'white',
- padding: '2px',
-};
-
-type Props = {
- layout: string;
- orientation: string;
- linkType: string;
- stepPercent: number;
- selectedNode: string;
- setLayout: (layout: string) => void;
- setOrientation: (orientation: string) => void;
- setLinkType: (linkType: string) => void;
- setStepPercent: (percent: number) => void;
- setSelectedNode: (selectedNode: string) => void;
- snapShots: Record
;
-};
-
-// use BFS to put all the nodes under snapShots(which is the tree node) into an array
-const nodeList = [];
-const collectNodes = node => {
- nodeList.splice(0, nodeList.length);
- /* We used the .splice method here to ensure that nodeList
- did not accumulate with page refreshes */
- nodeList.push(node);
- for (let i = 0; i < nodeList.length; i += 1) {
- const cur = nodeList[i];
- if (cur.children?.length > 0) {
- cur.children.forEach(child => nodeList.push(child));
- }
- }
-};
-
-export default function LinkControls({
- layout,
+const LinkControls = ({
linkType,
stepPercent,
- setLayout,
setOrientation,
setLinkType,
setStepPercent,
setSelectedNode,
snapShots,
-}: Props): JSX.Element {
- collectNodes(snapShots);
+}) => {
+ const collectNodes = (node) => {
+ const nodeList = [];
+ nodeList.push(node);
+ for (let i = 0; i < nodeList.length; i += 1) {
+ const cur = nodeList[i];
+ if (cur.children?.length > 0) {
+ cur.children.forEach((child) => nodeList.push(child));
+ }
+ }
+ return nodeList;
+ };
- return (
-
+ const shouldIncludeNode = (node) => {
+ // Return false if node has any context properties
+ if (node?.componentData?.context && Object.keys(node.componentData.context).length > 0) {
+ return false;
+ }
+ // Return false if node name ends with 'Provider'
+ if (node?.name && node.name.endsWith('Provider')) {
+ return false;
+ }
+ return true;
+ };
+
+ const processTreeData = (node) => {
+ if (!node) return null;
+
+ // Create a new node
+ const newNode = { ...node };
+
+ if (node.children) {
+ // Process all children first
+ const processedChildren = node.children
+ .map((child) => processTreeData(child))
+ .filter(Boolean); // Remove null results
- {/* Controls for the layout selection */}
-
Layout:
-
- {' '}
- {/* This is a non-breaking space - Prevents an automatic line break at this position */}
-
e.stopPropagation()}
- onChange={e => setLayout(e.target.value)}
- // value={layout}
- style={dropDownStyle}
- >
- Cartesian
- Polar
-
-
+ // For each child that shouldn't be included, replace it with its children
+ newNode.children = processedChildren.reduce((acc, child) => {
+ if (shouldIncludeNode(child)) {
+ // If child should be included, add it directly
+ acc.push(child);
+ } else {
+ // If child should be filtered out, add its children instead
+ if (child.children) {
+ acc.push(...child.children);
+ }
+ }
+ return acc;
+ }, []);
+ }
+
+ return newNode;
+ };
+ const filtered = processTreeData(snapShots);
+ const nodeList = collectNodes(filtered);
- {/* Controls for the Orientation selection, this dropdown will be disabled when the polar layout is selected as it is not needed */}
-
Orientation:
-
-
e.stopPropagation()}
- onChange={e => setOrientation(e.target.value)}
- disabled={layout === 'polar'}
- style={dropDownStyle}
- >
- Vertical
- Horizontal
-
-
+ return (
+
+
+ Orientation:
+ e.stopPropagation()}
+ onChange={(e) => setOrientation(e.target.value)}
+ className='control-select'
+ >
+ Vertical
+ Horizontal
+
+
- {/* Controls for the link selections. */}
-
Link:
-
-
e.stopPropagation()}
- onChange={e => setLinkType(e.target.value)}
- style={dropDownStyle}
- >
- Diagonal
- Step
- Line
-
+
+ Link:
+ e.stopPropagation()}
+ onChange={(e) => setLinkType(e.target.value)}
+ className='control-select'
+ >
+ Step
+ Diagonal
+ Line
+
+
- {/* Controls for the select selections. */}
-
Select:
-
-
setSelectedNode(e.target.value)}
- style={dropDownStyle}
- >
- {nodeList.map(node => (
- node.children.length > 0 && {node.name}
- ))}
-
+
+ Select:
+ setSelectedNode(e.target.value)}
+ className='control-select'
+ >
+ {nodeList.map((node) =>
+ node.children.length > 0 ? (
+
+ {node.name}
+
+ ) : null,
+ )}
+
+
- {/* This is the slider control for the step option */}
- {linkType === 'step' && layout !== 'polar' && (
- <>
-
-
Step:
-
+ {linkType === 'step' && (
+
+ Step:
e.stopPropagation()}
- type="range"
+ onClick={(e) => e.stopPropagation()}
+ type='range'
min={0}
max={1}
step={0.1}
- onChange={e => setStepPercent(Number(e.target.value))}
+ onChange={(e) => setStepPercent(Number(e.target.value))}
value={stepPercent}
- disabled={linkType !== 'step' || layout === 'polar'}
+ disabled={linkType !== 'step'}
+ className='control-range'
/>
- >
+
)}
);
-}
+};
+
+export default LinkControls;
diff --git a/src/app/components/StateRoute/ComponentMap/ToolTipDataDisplay.tsx b/src/app/components/StateRoute/ComponentMap/ToolTipDataDisplay.tsx
new file mode 100644
index 000000000..29bcfbfc7
--- /dev/null
+++ b/src/app/components/StateRoute/ComponentMap/ToolTipDataDisplay.tsx
@@ -0,0 +1,112 @@
+import React from 'react';
+import { JSONTree } from 'react-json-tree';
+
+const ToolTipDataDisplay = ({ data }) => {
+ if (!data) return null;
+
+ const jsonTheme = {
+ scheme: 'custom',
+ base00: 'transparent',
+ base0B: '#14b8a6', // dark navy for strings
+ base0D: '#60a5fa', // Keys
+ base09: '#f59e0b', // Numbers
+ base0C: '#EF4444', // Null values
+ };
+
+ // Helper function to parse stringified JSON in object values
+ const parseStringifiedValues = (obj) => {
+ if (!obj || typeof obj !== 'object') return obj;
+
+ const parsed = { ...obj };
+ for (const key in parsed) {
+ if (typeof parsed[key] === 'string') {
+ try {
+ // Check if the string looks like JSON
+ if (parsed[key].startsWith('{') || parsed[key].startsWith('[')) {
+ const parsedValue = JSON.parse(parsed[key]);
+ parsed[key] = parsedValue;
+ }
+ } catch (e) {
+ // If parsing fails, keep original value
+ continue;
+ }
+ } else if (typeof parsed[key] === 'object') {
+ parsed[key] = parseStringifiedValues(parsed[key]);
+ }
+ }
+ return parsed;
+ };
+
+ const formatReducerData = (reducerStates) => {
+ // Check if reducerStates exists and is an object
+ if (!reducerStates || typeof reducerStates !== 'object') {
+ return {};
+ }
+
+ // Handle both array and object formats
+ const statesArray = Array.isArray(reducerStates) ? reducerStates : Object.values(reducerStates);
+
+ return statesArray.reduce((acc, reducer) => {
+ // Add additional type checking for reducer object
+ if (reducer && typeof reducer === 'object') {
+ acc[reducer.hookName || 'Reducer'] = reducer.state;
+ }
+ return acc;
+ }, {});
+ };
+
+ const renderSection = (title, content, isReducer = false) => {
+ if (
+ !content ||
+ (Array.isArray(content) && content.length === 0) ||
+ Object.keys(content).length === 0
+ ) {
+ return null;
+ }
+
+ // Parse any stringified JSON before displaying
+ const parsedContent = parseStringifiedValues(content);
+
+ if (isReducer && parsedContent) {
+ // Only try to format if we have valid content
+ const formattedData = formatReducerData(parsedContent);
+
+ // Check if we have any formatted data to display
+ if (Object.keys(formattedData).length === 0) {
+ return null;
+ }
+
+ return (
+
+ {Object.entries(formattedData).map(([hookName, state]) => (
+
+
{hookName}
+
+ true} />
+
+
+ ))}
+
+ );
+ }
+
+ return (
+
+
{title}
+
+ true} />
+
+
+ );
+ };
+
+ return (
+
+ {renderSection('Props', data.componentData?.props)}
+ {renderSection('State', data.componentData?.state || data.componentData?.hooksState)}
+ {renderSection(null, data.componentData?.reducerStates, true)}
+
+ );
+};
+
+export default ToolTipDataDisplay;
diff --git a/src/app/components/StateRoute/ComponentMap/getLinkComponent.ts b/src/app/components/StateRoute/ComponentMap/getLinkComponent.ts
index d8eadbc76..600c884fa 100644
--- a/src/app/components/StateRoute/ComponentMap/getLinkComponent.ts
+++ b/src/app/components/StateRoute/ComponentMap/getLinkComponent.ts
@@ -12,29 +12,20 @@ import {
LinkVerticalLine,
LinkRadialLine,
} from '@visx/shape';
+import { LinkComponent } from '../../../FrontendTypes';
+
+/*
+ Changes the shape of the LinkComponent based on the linkType, and orientation
+*/
export default function getLinkComponent({
- layout,
linkType,
orientation,
-}: {
- layout: string;
- linkType: string;
- orientation: string;
-}): React.ComponentType
{
+}: LinkComponent): React.ComponentType {
let LinkComponent: React.ComponentType;
- if (layout === 'polar') {
- if (linkType === 'step') {
- LinkComponent = LinkRadialStep;
- } else if (linkType === 'curve') {
- LinkComponent = LinkRadialCurve;
- } else if (linkType === 'line') {
- LinkComponent = LinkRadialLine;
- } else {
- LinkComponent = LinkRadial;
- }
- } else if (orientation === 'vertical') {
+if (orientation === 'vertical') {
+ // if the orientation is vertical, linkType can be either step, curve, line, or a plain LinkVertical
if (linkType === 'step') {
LinkComponent = LinkVerticalStep;
} else if (linkType === 'curve') {
@@ -45,6 +36,7 @@ export default function getLinkComponent({
LinkComponent = LinkVertical;
}
} else if (linkType === 'step') {
+ // if orientation and layout still haven't matched, linkType will determine our linkComponent type based on if linkType is step, curve, line, or a plain LinkHorizontal
LinkComponent = LinkHorizontalStep;
} else if (linkType === 'curve') {
LinkComponent = LinkHorizontalCurve;
diff --git a/src/app/components/StateRoute/History.tsx b/src/app/components/StateRoute/History.tsx
index 9fa39d3a2..c83962d04 100644
--- a/src/app/components/StateRoute/History.tsx
+++ b/src/app/components/StateRoute/History.tsx
@@ -1,213 +1,249 @@
/* eslint-disable react-hooks/exhaustive-deps */
+/* eslint-disable */
// @ts-nocheck
-import React, { useEffect } from 'react';
+import React, { useEffect, useRef } from 'react';
// formatting findDiff return data to show the changes with colors, aligns with actions.tsx
import { diff, formatters } from 'jsondiffpatch';
import * as d3 from 'd3';
+import { DefaultMargin } from '../../FrontendTypes';
+import { useDispatch } from 'react-redux';
+import { changeView, changeSlider, setCurrentTabInApp } from '../../slices/mainSlice';
-import { changeView, changeSlider, setCurrentTabInApp } from '../../actions/actions';
-import { useStoreContext } from '../../store';
+/*
+ Render's history page after history button has been selected. Allows user to traverse state history and relevant state branches.
+*/
-interface defaultMargin {
- top: number,
- left: number,
- right: number,
- bottom: number,
-}
-
-const defaultMargin: defaultMargin = {
- top: 30, left: 30, right: 55, bottom: 70,
+const defaultMargin: DefaultMargin = {
+ top: 60,
+ left: 30,
+ right: 55,
+ bottom: 70,
};
+// Fixed node separation distances
+const FIXED_NODE_HEIGHT = 150; // Vertical distance between nodes
+const FIXED_NODE_WIDTH = 200; // Horizontal distance between nodes
+
// main function exported to StateRoute
// below we destructure the props
function History(props: Record): JSX.Element {
const {
- width: totalWidth,
- height: totalHeight,
- margin = defaultMargin,
- hierarchy,
- dispatch,
- currLocation,
- snapshots,
+ width: totalWidth, // from ParentSize provided in StateRoute
+ height: totalHeight, // from ParentSize provided in StateRoute
+ margin = defaultMargin, //default margin is used when margins aren't passed into props
+ hierarchy, // from 'tabs[currentTab]' object in 'MainContainer'
+ currLocation, // from 'tabs[currentTab]' object in 'MainContainer'
+ snapshots, // from 'tabs[currentTab].snapshotDisplay' object in 'MainContainer'
} = props;
- const [, dispatch] = useStoreContext();
+
+ //here we are adding useSelector and useDispatch for RTK state conversion
+ const dispatch = useDispatch();
const svgRef = React.useRef(null);
const root = JSON.parse(JSON.stringify(hierarchy));
+ const historyEndRef = useRef(null);
// setting the margins for the Map to render in the tab window.
const innerWidth: number = totalWidth - margin.left - margin.right;
const innerHeight: number = totalHeight - margin.top - margin.bottom - 60;
- function labelCurrentNode(d3root) {
- if (d3root.data.index === currLocation.index) {
- let currNode = d3root;
- while (currNode.parent) {
- currNode.color = '#999';
- currNode = currNode.parent;
- }
- currNode.color = '#999';
- return d3root;
- }
- let found;
- if (!d3root.children) {
- return found;
- }
- d3root.children.forEach(child => {
- if (!found) {
- found = labelCurrentNode(child);
- }
- });
- return found;
- }
-
- // findDiff function uses same logic as ActionContainer.tsx
function findDiff(index) {
- const statelessCleanning = (obj: {
+ const statelessCleaning = (obj: {
name?: string;
componentData?: object;
state?: string | any;
stateSnaphot?: object;
children?: any[];
}) => {
+ if (!obj) return {}; // Add null check
+
const newObj = { ...obj };
- if (newObj.name === 'nameless') {
- delete newObj.name;
- }
- if (newObj.componentData) {
- delete newObj.componentData;
- }
- if (newObj.state === 'stateless') {
- delete newObj.state;
- }
+ if (newObj.name === 'nameless') delete newObj.name;
+ if (newObj.componentData) delete newObj.componentData;
+ if (newObj.state === 'stateless') delete newObj.state;
if (newObj.stateSnaphot) {
- newObj.stateSnaphot = statelessCleanning(obj.stateSnaphot);
+ newObj.stateSnaphot = statelessCleaning(obj.stateSnaphot);
}
if (newObj.children) {
newObj.children = [];
- if (obj.children.length > 0) {
- obj.children.forEach(
- (element: { state?: object | string; children?: [] }) => {
- if (
- element.state !== 'stateless'
- || element.children.length > 0
- ) {
- const clean = statelessCleanning(element);
- newObj.children.push(clean);
- }
- },
- );
+ // Add null check for children array
+ if (Array.isArray(obj.children) && obj.children.length > 0) {
+ obj.children.forEach((element: { state?: object | string; children?: [] }) => {
+ // Add null check for element
+ if (
+ element &&
+ ((element.state && element.state !== 'stateless') ||
+ (element.children && element.children.length > 0))
+ ) {
+ const clean = statelessCleaning(element);
+ newObj.children.push(clean);
+ }
+ });
}
}
return newObj;
};
function findStateChangeObj(delta, changedState = []) {
- if (!delta.children && !delta.state) {
- return changedState;
- }
+ if (!delta) return changedState; // Add null check
+ if (!delta.children && !delta.state) return changedState;
if (delta.state && delta.state[0] !== 'stateless') {
changedState.push(delta.state);
}
- if (!delta.children) {
- return changedState;
- }
- Object.keys(delta.children).forEach(child => {
- // if (isNaN(child) === false) {
- changedState.push(...findStateChangeObj(delta.children[child]));
- // }
+ if (!delta.children) return changedState;
+ Object.keys(delta.children).forEach((child) => {
+ if (delta.children[child]) {
+ // Add null check
+ changedState.push(...findStateChangeObj(delta.children[child]));
+ }
});
return changedState;
}
- const delta = diff(statelessCleanning(snapshots[index - 1]), statelessCleanning(snapshots[index]));
- const changedState = findStateChangeObj(delta);
- // figured out the formatting for hover, applying diff.csss
- const html = formatters.html.format(changedState[0]);
- // uneeded, not returning a react component in SVG div
- // const output = ReactHtmlParser(html);
- return html;
+ if (index === 0) return 'Initial State ';
+
+ // Add null checks for snapshots
+ if (!snapshots || !snapshots[index] || !snapshots[index - 1]) {
+ return 'No state changes';
+ }
+
+ try {
+ const delta = diff(
+ statelessCleaning(snapshots[index - 1]),
+ statelessCleaning(snapshots[index]),
+ );
+
+ if (!delta) return 'No State Changes ';
+
+ const changedState = findStateChangeObj(delta);
+ return changedState.length > 0 ? formatters.html.format(changedState[0]) : 'No state changes';
+ } catch (error) {
+ console.error('Error in findDiff:', error);
+ return 'Error comparing states';
+ }
}
/**
- * @method makeD3Tree :Creates a new D3 Tree
- */
+ * @method makeD3Tree :Creates a new D3 Tree
+ */
+
const makeD3Tree = () => {
const svg = d3.select(svgRef.current);
- svg.selectAll('*').remove(); // Clear svg content before adding new elements
- const tree = data => {
- const treeRoot = d3.hierarchy(data);
- return d3.tree().size([innerWidth, innerHeight])(treeRoot);
- };
- // const hierarchy = d3.hierarchy(root);
- const d3root = tree(root);
+ svg.selectAll('*').remove();
+
+ // Create tree layout with fixed node size
+ const treeLayout = d3
+ .tree()
+ .nodeSize([FIXED_NODE_WIDTH, FIXED_NODE_HEIGHT])
+ .separation((a, b) => {
+ // Increase separation between unrelated subtrees
+ return a.parent === b.parent ? 1.2 : 2;
+ });
+
+ // Create hierarchy and compute initial layout
+ const d3root = d3.hierarchy(root);
+ treeLayout(d3root);
+
+ // Calculate the bounds of the tree
+ let minX = Infinity;
+ let maxX = -Infinity;
+ let minY = Infinity;
+ let maxY = -Infinity;
- const currNode = labelCurrentNode(d3root);
+ d3root.each((d) => {
+ minX = Math.min(minX, d.x);
+ maxX = Math.max(maxX, d.x);
+ minY = Math.min(minY, d.y);
+ maxY = Math.max(maxY, d.y);
+ });
+
+ // Calculate the actual dimensions needed
+ const actualWidth = maxX - minX + FIXED_NODE_WIDTH;
+ const actualHeight = maxY - minY + FIXED_NODE_HEIGHT;
+
+ // Set SVG dimensions to accommodate the tree
+ const svgWidth = Math.max(actualWidth + margin.left + margin.right, totalWidth);
+ svg
+ .attr('width', svgWidth)
+ .attr('height', Math.max(actualHeight + margin.top + margin.bottom, totalHeight));
- const g = svg.append('g')
- .attr('transform', `translate(${margin.left},${d3root.height === 0 ? (totalHeight / 2) : margin.top})`);
+ // Calculate center offset to keep root centered
+ const rootOffset = -d3root.x;
+ const horizontalCenter = svgWidth / 2;
- const link = g.selectAll('.link')
- // root.links() gets an array of all the links,
- // where each element is an object containing a
- // source property, which represents the link's source node,
- // and a target property, which represents the link's target node.
+ // Create container group and apply transforms
+ const g = svg
+ .append('g')
+ .attr('transform', `translate(${horizontalCenter + rootOffset},${margin.top})`);
+
+ // Draw links
+ const link = g
+ .selectAll('.link')
.data(d3root.descendants().slice(1))
.enter()
.append('path')
- .attr('class', 'link')
- .attr('d', d => `M${d.x},${d.y
- }C${d.x},${(d.y + d.parent.y) / 2
- } ${d.parent.x},${(d.y + d.parent.y) / 2
- } ${d.parent.x},${d.parent.y}`);
+ .attr('class', (d) => {
+ return d.data.index === currLocation.index ? 'link current-link' : 'link';
+ })
+ .attr('d', (d) => {
+ return `M${d.x},${d.y}
+ C${d.x},${(d.y + d.parent.y) / 2}
+ ${d.parent.x},${(d.y + d.parent.y) / 2}
+ ${d.parent.x},${d.parent.y}`;
+ });
- const node = g.selectAll('.node')
+ // Create node groups
+ const node = g
+ .selectAll('.node')
.data(d3root.descendants())
.enter()
.append('g')
- .style('cursor', 'pointer')
- .on('click', d => {
+ .attr('class', (d) => {
+ const baseClass = 'node';
+ const internalClass = d.children ? ' node--internal' : '';
+ const activeClass = d.data.index === currLocation.index ? ' active' : '';
+ return baseClass + internalClass + activeClass;
+ })
+ .attr('transform', (d) => `translate(${d.x},${d.y})`)
+ .on('click', (event, d) => {
dispatch(changeView(d.data.index));
dispatch(changeSlider(d.data.index));
- })
- // added to display state change information to node tree
- .on('mouseover', d => {
- // created popup div and appended it to display div(returned in this function)
- // D3 doesn't utilize z-index for priority,
- // rather decides on placement by order of rendering
- // needed to define the return div with a className to have a target to append to
- // with the correct level of priority
- const div = d3.select('.display').append('div')
- .attr('class', 'tooltip')
- .style('left', `${d3.event.pageX}px`)
- .style('top', `${d3.event.pageY}px`);
- d3.selectAll('.tooltip').html(findDiff(d.data.index));
- })
- .on('mouseout', d => {
- // when appending divs on mouseover the appended dives would not disappear
- // when using D3's 'transition' on mouseover/mouseout
- // solution: remove all tooltop divs on mouseout
- d3.selectAll('.tooltip').remove();
- })
- .attr('transform', d => `translate(${d.x},${d.y})`);
+ });
- node.append('circle')
- .attr('fill', d => {
- if (d.data.index === currLocation.index) {
- return 'red';
- }
- return d.color ? d.color : '#555';
- })
- .attr('r', 14);
+ // Add rectangles for nodes with consistent size
+ node
+ .append('rect')
+ .attr('width', 200)
+ .attr('height', 120)
+ .attr('x', -100)
+ .attr('y', -40)
+ .attr('rx', 8)
+ .attr('ry', 8);
- node.append('text')
- .attr('dy', '0.31em')
+ // Add snapshot titles
+ node
+ .append('text')
+ .attr('dy', '-20')
.attr('text-anchor', 'middle')
- .text(d => `${d.data.name}.${d.data.branch}`)
- .clone(true)
- .lower()
- .attr('stroke', 'white');
+ .attr('class', 'snapshot-title')
+ .text((d) => `Snapshot ${d.data.index + 1}`);
+
+ // Add state changes text
+ node
+ .append('foreignObject')
+ .attr('x', -85)
+ .attr('y', -15)
+ .attr('width', 170)
+ .attr('height', 90)
+ .append('xhtml:div')
+ .style('font-size', '12px')
+ .style('text-align', 'left')
+ .style('padding-left', '8px')
+ .html((d) => findDiff(d.data.index));
+
+ if (historyEndRef.current) {
+ historyEndRef.current.scrollIntoView({ behavior: 'smooth' });
+ }
return svg.node();
};
@@ -216,16 +252,15 @@ function History(props: Record): JSX.Element {
}, [root, currLocation]);
useEffect(() => {
- dispatch(setCurrentTabInApp('history'));
+ dispatch(setCurrentTabInApp('history')); // dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'webmetrics' to facilitate render.
}, []);
- // then rendering each node in History tab to render using D3, which will share area with LegendKey
+
return (
-
-
+
);
}
diff --git a/src/app/components/StateRoute/PerformanceVisx/BarGraph.tsx b/src/app/components/StateRoute/PerformanceVisx/BarGraph.tsx
index f6be8d321..de162650f 100644
--- a/src/app/components/StateRoute/PerformanceVisx/BarGraph.tsx
+++ b/src/app/components/StateRoute/PerformanceVisx/BarGraph.tsx
@@ -7,89 +7,111 @@ import { AxisBottom, AxisLeft } from '@visx/axis';
import { scaleBand, scaleLinear, scaleOrdinal } from '@visx/scale';
import { useTooltip, useTooltipInPortal, defaultStyles } from '@visx/tooltip';
import { Text } from '@visx/text';
-import { schemeSet3 } from 'd3-scale-chromatic';
-import { onHover, onHoverExit, save } from '../../../actions/actions';
-import { useStoreContext } from '../../../store';
+import { schemeSet1 } from 'd3-scale-chromatic';
+import { onHover, onHoverExit, save } from '../../../slices/mainSlice';
+import { useDispatch, useSelector } from 'react-redux';
import {
- snapshot, TooltipData, Margin, BarGraphProps,
-} from '../../FrontendTypes';
+ snapshot,
+ TooltipData,
+ Margin,
+ BarGraphProps,
+ RootState,
+ MainState,
+} from '../../../FrontendTypes';
/* DEFAULTS */
const margin = {
- top: 30, right: 30, bottom: 0, left: 50,
+ top: 30,
+ right: 30,
+ bottom: 0,
+ left: 70,
};
-const axisColor = '#FF6569';
-const background = '#242529';
+const axisColor = 'var(--text-primary)';
+const axisTickLabelColor = 'var(--text-secondary)';
+const axisLabelColor = 'var(--text-primary)';
const tooltipStyles = {
...defaultStyles,
minWidth: 60,
- backgroundColor: 'rgba(0,0,0,0.9)',
- color: 'white',
- fontSize: '14px',
lineHeight: '18px',
- fontFamily: 'Roboto',
+ pointerEvents: 'all !important',
+ padding: '8px',
+ borderRadius: '8px',
};
const BarGraph = (props: BarGraphProps): JSX.Element => {
- const [{ tabs, currentTab }, dispatch] = useStoreContext();
+ const dispatch = useDispatch();
+ const { tabs, currentTab }: MainState = useSelector((state: RootState) => state.main);
+
const {
- width,
- height,
- data,
- comparison,
- setRoute,
- allRoutes,
- filteredSnapshots,
- snapshot,
- setSnapshot,
+ width, // from stateRoute container
+ height, // from stateRoute container
+ data, // Acquired from getPerfMetrics(snapshots, getSnapshotIds(hierarchy)) in 'PerformanceVisx'
+ comparison, // result from invoking 'allStorage' in 'PerformanceVisx'
+ setRoute, // updates the 'route' state in 'PerformanceVisx'
+ allRoutes, // array containing urls from 'PerformanceVisx'
+ filteredSnapshots, // array containing url's that exist and with route === url.pathname
+ snapshot, // state that is initialized to 'All Snapshots' in 'PerformanceVisx'
+ setSnapshot, // updates the 'snapshot' state in 'PerformanceVisx'
} = props;
const [seriesNameInput, setSeriesNameInput] = useState(`Series ${comparison.length + 1}`);
const {
- tooltipOpen,
- tooltipLeft,
- tooltipTop,
- tooltipData,
- hideTooltip,
- showTooltip,
- } = useTooltip
();
+ tooltipOpen, // boolean whether the tooltip state is open or closed
+ tooltipLeft, // number used for tooltip positioning
+ tooltipTop, // number used for tooltip positioning
+ tooltipData, // value/data that tooltip may need to render
+ hideTooltip, // function to close a tooltip
+ showTooltip, // function to set tooltip state
+ } = useTooltip(); // returns an object with several properties that you can use to manage the tooltip state of your component
let tooltipTimeout: number;
- const { containerRef, TooltipInPortal } = useTooltipInPortal({
- detectBounds: true,
- scroll: true,
+ const {
+ containerRef, // Access to the container's bounding box. This will be empty on first render.
+ TooltipInPortal, // TooltipWithBounds in a Portal, outside of your component DOM tree
+ } = useTooltipInPortal({
+ // Visx hook
+ detectBounds: true, // use TooltipWithBounds
+ scroll: true, // when tooltip containers are scrolled, this will correctly update the Tooltip position
});
const keys = Object.keys(data.componentData);
+ const getSnapshotId = (d: snapshot) => d.snapshotId; // data accessor (used to generate scales) and formatter (add units for on hover box). d comes from data.barstack post filtered data
+ const formatSnapshotId = (id) => `ID: ${id}`; // returns snapshot id when invoked in tooltip section
+ const formatRenderTime = (time) => `${time} ms `; // returns render time when invoked in tooltip section
- // data accessor (used to generate scales) and formatter (add units for on hover box)
- // d coming from data.barstack post filtered data
- const getSnapshotId = (d: snapshot) => d.snapshotId;
-
- // returns snapshot id when invoked in tooltip section
- const formatSnapshotId = id => `Snapshot ID: ${id}`;
- // returns render time when invoked in tooltip section
- const formatRenderTime = time => `${time} ms `;
-
- // create visualization SCALES with cleaned data
const snapshotIdScale = scaleBand({
+ // create visualization SCALES with cleaned data
domain: data.barStack.map(getSnapshotId),
padding: 0.2,
});
- // Adjusts y axis to match/ bar height
const renderingScale = scaleLinear({
+ // Adjusts y axis to match/ bar height
domain: [0, data.maxTotalRender],
nice: true,
});
- // Gives each bar on the graph a color using schemeSet3 imported from D3
+
+ const LMcolorScale = [
+ '#14b8a6', // Teal (matching existing accent)
+ '#0d9488', // Darker teal (matching existing accent)
+ '#3c6e71', // Primary strong teal
+ '#284b63', // Primary blue
+ '#2c5282', // Deeper blue
+ '#1a365d', // Navy
+ '#2d3748', // Blue gray
+ '#4a5568', // Darker blue gray
+ '#718096', // Medium blue gray
+ '#a0aec0', // Light blue gray
+ ];
+
const colorScale = scaleOrdinal({
+ // Gives each bar on the graph a color using schemeSet1 imported from D3
domain: keys,
- range: schemeSet3,
+ range: LMcolorScale,
});
// setting max dimensions and scale ranges
const xMax = width - margin.left - margin.right;
snapshotIdScale.rangeRound([0, xMax]);
- const yMax = height - margin.top - 150;
+ const yMax = height - margin.top - 100;
renderingScale.range([yMax, 0]);
const toStorage = {
@@ -97,81 +119,49 @@ const BarGraph = (props: BarGraphProps): JSX.Element => {
title: tabs[currentTab].title,
data,
};
- // use this to animate the save series button. It
- useEffect(() => {
- const saveButtons = document.getElementsByClassName('save-series-button');
- for (let i = 0; i < saveButtons.length; i++) {
- if (tabs[currentTab].seriesSavedStatus === 'saved') {
- saveButtons[i].classList.add('animate');
- saveButtons[i].innerHTML = 'Saved!';
- } else {
- saveButtons[i].innerHTML = 'Save Series';
- saveButtons[i].classList.remove('animate');
- }
- }
- });
- // CURRENTLY DOES NOT SAVE
- const saveSeriesClickHandler = () => {
- if (tabs[currentTab].seriesSavedStatus === 'inputBoxOpen') {
- const actionNames = document.getElementsByClassName('actionname');
- for (let i = 0; i < actionNames.length; i += 1) {
- toStorage.data.barStack[i].name = actionNames[i].value;
- }
- dispatch(save(toStorage, seriesNameInput));
- setSeriesNameInput(`Series ${comparison.length}`);
- return;
- }
- dispatch(save(toStorage));
- };
-
- // Need to change so textbox isn't empty before saving
- const textbox = tabs[currentTab].seriesSavedStatus === 'inputBoxOpen' ? setSeriesNameInput(e.target.value)} /> : null;
return (
-
-
- {textbox}
-
- Save Series
-
-
+ ) : null
+ }
+ />
+
+ >
);
};
diff --git a/src/app/components/StateRoute/PerformanceVisx/RenderingFrequency.tsx b/src/app/components/StateRoute/PerformanceVisx/RenderingFrequency.tsx
deleted file mode 100644
index ce9fe50e9..000000000
--- a/src/app/components/StateRoute/PerformanceVisx/RenderingFrequency.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable react/prop-types */
-import React, { useState, useEffect } from 'react';
-import { onHover, onHoverExit, setCurrentTabInApp } from '../../../actions/actions';
-import { useStoreContext } from '../../../store';
-
-const RenderingFrequency = props => {
- const perfData = props.data;
- const [store, dispatch] = useStoreContext();
- useEffect(() => {
- dispatch(setCurrentTabInApp('performance-comparison'));
- }, []);
- return (
-
- {Object.keys(perfData).map(componentName => {
- const currentComponent = perfData[componentName];
- return (
-
- );
- })}
-
- );
-};
-
-const ComponentCard = (props): JSX.Element => {
- const {
- componentName,
- stateType,
- averageRenderTime,
- renderFrequency,
- information,
- } = props;
- const [{ tabs, currentTab }, dispatch] = useStoreContext();
- const [expand, setExpand] = useState(false);
-
- // render time for each component from each snapshot
- // differences in state change that happened prior;
-
- const dataComponentArray = [];
- for (let i = 0; i < information.length; i++) {
- dataComponentArray.push(
);
- }
-
- return (
-
-
-
-
- {componentName}
- {' '}
-
- {stateType}
-
- average time:
- {' '}
- {averageRenderTime}
- {' '}
- ms
-
-
-
{
- if (expand === true) {
- setExpand(false);
- } else {
- setExpand(true);
- }
- }}
- className="RenderRight"
- >
-
{renderFrequency}
-
-
-
- {expand === true ? dataComponentArray : null}
-
-
- );
-};
-
-const DataComponent = props => {
- const {
- header,
- paragraphs,
- } = props;
-
- return (
-
-
- {' '}
- {header}
-
-
- {`renderTime: ${paragraphs[0].rendertime}`}
-
-
- );
-};
-
-export default RenderingFrequency;
diff --git a/src/app/components/StateRoute/StateRoute.tsx b/src/app/components/StateRoute/StateRoute.tsx
index 318a3c8d7..6b08ba027 100644
--- a/src/app/components/StateRoute/StateRoute.tsx
+++ b/src/app/components/StateRoute/StateRoute.tsx
@@ -5,217 +5,224 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable max-len */
/* eslint-disable object-curly-newline */
-import React from 'react';
-import {
- MemoryRouter as Router,
- Route,
- NavLink,
- Switch,
-} from 'react-router-dom';
+import React, { useState } from 'react';
+import { MemoryRouter as Router, Route, NavLink, Routes, Outlet, Link } from 'react-router-dom';
import { ParentSize } from '@visx/responsive';
import Tree from './Tree';
import ComponentMap from './ComponentMap/ComponentMap';
-import { changeView, changeSlider } from '../../actions/actions';
-import { useStoreContext } from '../../store';
+import { changeView, changeSlider, toggleAxTree, setCurrentTabInApp } from '../../slices/mainSlice';
+import { useDispatch, useSelector } from 'react-redux';
import PerformanceVisx from './PerformanceVisx/PerformanceVisx';
-import WebMetrics from '../WebMetrics';
+import WebMetricsContainer from './WebMetrics/WebMetricsContainer';
+import { MainState, RootState, StateRouteProps } from '../../FrontendTypes';
+import AxContainer from './AxMap/AxContainer';
const History = require('./History').default;
-
const NO_STATE_MSG = 'No state change detected. Trigger an event to change state';
-
-export interface StateRouteProps {
- snapshot: {
- name?: string;
- componentData?: object;
- state?: string | object;
- stateSnaphot?: object;
- children?: any[];
- };
- hierarchy: any;
- snapshots: [];
- viewIndex: number;
- webMetrics: object;
- currLocation: object;
-}
-
const StateRoute = (props: StateRouteProps) => {
- const { snapshot, hierarchy, snapshots, viewIndex, webMetrics, currLocation } = props;
- const [{ tabs, currentTab }, dispatch] = useStoreContext();
- const { hierarchy, sliderIndex, viewIndex } = tabs[currentTab];
+ const {
+ axSnapshots,
+ snapshot,
+ hierarchy: propsHierarchy,
+ snapshots,
+ viewIndex: propsViewIndex,
+ webMetrics,
+ currLocation,
+ } = props;
- // Map
- const renderComponentMap = () => {
- if (hierarchy) {
- return (
-
- {({ width, height }) => (
- // eslint-disable-next-line react/prop-types
-
- )}
-
- );
- }
- return
{NO_STATE_MSG}
;
- };
+ const { tabs, currentTab }: MainState = useSelector((state: RootState) => state.main);
+ const { hierarchy: tabsHierarchy, sliderIndex, viewIndex: tabsViewIndex } = tabs[currentTab];
+ const hierarchy = propsHierarchy || tabsHierarchy;
+ const viewIndex = propsViewIndex || tabsViewIndex;
- // the hierarchy gets set upon the first click on the page
- // when the page is refreshed we may not have a hierarchy, so we need to check if hierarchy was initialized
- // if true, we invoke the D3 render chart with hierarchy
- // by invoking History component, and passing in all the props required to render D3 elements and perform timeJump from clicking of node
- // otherwise we send an alert to the user that no state was found.
- const renderHistory = () => {
- if (hierarchy) {
- return (
-
- {({ width, height }) => (
-
- )}
-
- );
- }
- return
{NO_STATE_MSG}
;
- };
+ const dispatch = useDispatch();
+ const [showTree, setShowTree] = useState(false);
+ const [showParagraph, setShowParagraph] = useState(true);
- // the hierarchy gets set on the first click in the page
- // when the page is refreshed we may not have a hierarchy, so we need to check if hierarchy was initialized
- // if true invoke render Tree with snapshot
- const renderTree = () => {
- if (hierarchy) {
- return
;
- }
- return
{NO_STATE_MSG}
;
+ const enableAxTreeButton = () => {
+ dispatch(toggleAxTree('toggleAxRecord'));
+ setShowParagraph(false);
+ setShowTree(true);
};
- const renderWebMetrics = () => {
- let LCPColor: String; let FIDColor: String; let FCPColor: String; let
- TTFBColor: String;
- if (webMetrics.LCP <= 2000) LCPColor = '#0bce6b';
- if (webMetrics.LCP > 2000 && webMetrics.LCP < 4000) LCPColor = '#E56543';
- if (webMetrics.LCP > 4000) LCPColor = '#fc2000';
- if (webMetrics.FID <= 100) FIDColor = '#0bce6b';
- if (webMetrics.FID > 100 && webMetrics.FID <= 300) FIDColor = '#fc5a03';
- if (webMetrics.FID > 300) FIDColor = '#fc2000';
- if (webMetrics.FCP <= 900) FCPColor = '#0bce6b';
- if (webMetrics.FCP > 900 && webMetrics.FCP <= 1100) FCPColor = '#fc5a03';
- if (webMetrics.FCP > 1100) FCPColor = '#fc2000';
- if (webMetrics.TTFB <= 600) TTFBColor = '#0bce6b';
- if (webMetrics.TTFB > 600) TTFBColor = '#fc2000';
+ return (
+
+
+
+
+ navData.isActive ? 'is-active router-link map-tab' : 'router-link map-tab'
+ }
+ end
+ >
+ Map
+
+
+ navData.isActive ? 'is-active router-link history-tab' : 'router-link history-tab'
+ }
+ to='/history'
+ >
+ History
+
+
+ navData.isActive ? 'is-active router-link performance' : 'router-link performance-tab'
+ }
+ to='/performance'
+ >
+ Performance
+
- return (
-
- (Number.isNaN(val)
- ? '- ms'
- : `${((val / 100) * 2500).toFixed(2)} ms`)}
- label="LCP"
- name="Largest Contentful Paint"
- description="Measures loading performance. The benchmark is less than 2500 ms."
- />
- (Number.isNaN(val) ? '- ms' : `${(val / 25).toFixed(2)} ms`)}
- label="FID"
- name="First Input Delay"
- description="Measures interactivity. The benchmark is less than 100 ms."
- />
- `${((val / 100) * 1000).toFixed(2)} ms`}
- label="FCP"
- name="First Contentful Paint"
- description="Measures the time it takes the browser to render the first piece of DOM content. No benchmark."
- />
- `${((val / 100) * 10).toFixed(2)} ms`}
- label="TTFB"
- name="Time to First Byte"
- description="Measures the time it takes for a browser to receive the first byte of page content. The benchmark is 600 ms."
- />
+
+ navData.isActive
+ ? 'is-active router-link web-metrics-tab'
+ : 'router-link web-metrics-tab'
+ }
+ to='/webMetrics'
+ >
+ Web Metrics
+
+
+ navData.isActive ? 'is-active router-link tree-tab' : 'router-link tree-tab'
+ }
+ to='/tree'
+ >
+ Tree
+
+
+ navData.isActive
+ ? 'is-active router-link accessibility-tab'
+ : 'router-link accessibility-tab'
+ }
+ to='/accessibility'
+ >
+ Accessibility
+
+
- );
- };
- const renderPerfView = () => {
- if (hierarchy) {
- return (
-
- {({ width, height }) => (
-
- )}
-
- );
- }
- return
{NO_STATE_MSG}
;
- };
-
- return (
-
-
-
- Map
-
-
- Performance
-
-
- History
-
-
- Web Metrics
-
-
- Tree
-
+
+ ) : (
+
+ {showParagraph && (
+
+
+ A Note to Developers: Reactime is using the Chrome Debugger API in order to
+ grab the Accessibility Tree. Enabling this option will allow you to record
+ Accessibility Tree snapshots, but will result in the Chrome browser
+ notifying you that the Chrome Debugger has started.
+
+
+ )}
+
+
+ Enable
+
+
+ )
+ }
+ />
+
+ {({ width, height }) => (
+
+ )}
+
+ ) : (
+ {NO_STATE_MSG}
+ )
+ }
+ />
+
+
+ {({ width, height }) => (
+
+ )}
+
+
+
+ ) : (
+ {NO_STATE_MSG}
+ )
+ }
+ />
+ } />
+ }
+ />
+
+ {({ width, height }) => {
+ const maxHeight = 1200;
+ const h = Math.min(height, maxHeight);
+ return (
+
+ );
+ }}
+
+ ) : null
+ }
+ />
+
-
-
-
-
-
-
-
-
+
);
};
diff --git a/src/app/components/StateRoute/Tree.tsx b/src/app/components/StateRoute/Tree.tsx
index 284a5e82d..7d83c30d5 100644
--- a/src/app/components/StateRoute/Tree.tsx
+++ b/src/app/components/StateRoute/Tree.tsx
@@ -1,8 +1,12 @@
import React, { useEffect } from 'react';
-import JSONTree from 'react-json-tree';
+import { JSONTree } from 'react-json-tree'; // React JSON Viewer Component
+import { setCurrentTabInApp } from '../../slices/mainSlice';
+import { useDispatch } from 'react-redux';
+import { TreeProps } from '../../FrontendTypes';
-import { setCurrentTabInApp } from '../../actions/actions';
-import { useStoreContext } from '../../store';
+/*
+ Creats a component based on the JSON. Options may be passed into the props of the JSONTree component
+*/
const colors = {
scheme: 'paraiso',
@@ -26,46 +30,47 @@ const colors = {
};
const getItemString = (
- type,
- data: { state?: object | string; name: string; children: [] }
+ type: any,
+ data: { state?: object | string; name: string; children: [] },
) => {
+ // function that allows the customization of how arrays, objects, and iterable nodes are displayed.
if (data && data.name) {
return
{data.name} ;
}
return
;
};
-interface TreeProps {
- snapshot: {
- name?: string;
- componentData?: object;
- state?: string | object;
- stateSnaphot?: object;
- children?: any[];
- };
-}
-
const Tree = (props: TreeProps) => {
- const { snapshot } = props;
- const [ store, dispatch] = useStoreContext();
+ const {
+ snapshot, // from 'tabs[currentTab]' object in 'MainContainer'
+ snapshots, // from 'tabs[currentTab].snapshotDisplay' object in 'MainContainer'
+ currLocation, // from 'tabs[currentTab]' object in 'MainContainer'
+ } = props;
+ // @ts-ignore
+ const dispatch = useDispatch();
useEffect(() => {
- dispatch(setCurrentTabInApp('history'));
+ dispatch(setCurrentTabInApp('tree')); // dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'tree' to facilitate render.
}, []);
return (
<>
- {snapshot && (
-
({ className: 'json-tree' }) }}
- shouldExpandNode={() => true}
- getItemString={getItemString}
- labelRenderer={(raw: any[]) => {
- return typeof raw[0] !== 'number' ? {raw[0]} : null;
- }}
- />
- )}
+
+ {snapshot && (
+ // @ts-ignore
+ ({ className: 'json-tree' }) }} // theme set to a base16 theme that has been extended to include "className: 'json-tree'"
+ shouldExpandNodeInitially={() => true} // determines if node should be expanded when it first renders (root is expanded by default)
+ getItemString={getItemString} // allows the customization of how arrays, objects, and iterable nodes are displayed.
+ labelRenderer={(raw: any[]) => {
+ // renders a label if the first element of raw is a number.
+ return typeof raw[0] !== 'number' ? {raw[0]} : null;
+ }}
+ />
+ )}
+
>
);
};
diff --git a/src/app/components/StateRoute/WebMetrics/WebMetrics.tsx b/src/app/components/StateRoute/WebMetrics/WebMetrics.tsx
new file mode 100644
index 000000000..673fe3e7a
--- /dev/null
+++ b/src/app/components/StateRoute/WebMetrics/WebMetrics.tsx
@@ -0,0 +1,151 @@
+import React, { useEffect } from 'react';
+import Charts from 'react-apexcharts';
+import ReactHover, { Trigger, Hover } from 'react-hover';
+import { setCurrentTabInApp } from '../../../slices/mainSlice';
+import { useDispatch } from 'react-redux';
+
+const WebMetrics = (props) => {
+ const dispatch = useDispatch();
+
+ const state = {
+ series: props.series,
+ options: {
+ colors: [props.color],
+ chart: {
+ height: 100,
+ width: 100,
+ type: 'radialBar',
+ toolbar: {
+ show: false,
+ },
+ foreColor: 'var(--text-primary)',
+ },
+ plotOptions: {
+ radialBar: {
+ startAngle: -135,
+ endAngle: 135,
+ hollow: {
+ margin: 0,
+ size: '75%',
+ background: 'transparent',
+ image: props.overLimit
+ ? 'https://static.vecteezy.com/system/resources/thumbnails/012/042/301/small/warning-sign-icon-transparent-background-free-png.png'
+ : undefined,
+ imageWidth: 32,
+ imageHeight: 32,
+ imageOffsetX: 0,
+ imageOffsetY: -64,
+ imageClipped: false,
+ position: 'front',
+ dropShadow: {
+ enabled: false,
+ top: 3,
+ left: 0,
+ blur: 4,
+ opacity: 0.24,
+ },
+ },
+ track: {
+ background: 'var(--border-color-dark)',
+ strokeWidth: '10%',
+ margin: 0,
+ },
+ dataLabels: {
+ show: true,
+ name: {
+ offsetY: -10,
+ show: true,
+ color: 'var(--text-primary)',
+ fontSize: '24px',
+ },
+ value: {
+ formatter: props.formatted,
+ color: 'var(--color-primary)',
+ fontSize: '16px',
+ show: true,
+ },
+ },
+ },
+ },
+ fill: {
+ type: 'solid',
+ gradient: {
+ shade: 'dark',
+ type: 'horizontal',
+ shadeIntensity: 0.1,
+ inverseColors: false,
+ opacityFrom: 1,
+ opacityTo: 1,
+ stops: [0, 100],
+ },
+ },
+ stroke: {
+ lineCap: 'flat',
+ },
+ labels: [props.label],
+ },
+ };
+
+ useEffect(() => {
+ dispatch(setCurrentTabInApp('webmetrics'));
+ }, []);
+
+ const getThresholdColor = (type: string): string => {
+ switch (type) {
+ case 'good':
+ return '#0bce6b';
+ case 'improvement':
+ return '#fc5a03';
+ case 'poor':
+ return '#fc2000';
+ default:
+ return 'var(--text-primary)';
+ }
+ };
+
+ const hoverOptions = {
+ followCursor: false,
+ shiftX: 20,
+ shiftY: 0,
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {props.name}
+
+
{props.description}
+
+ Good:
+ {`< ${props.score[0]}`}
+
+
+ Needs Improvement:
+ {`< ${props.score[1]}`}
+
+
+ Poor:
+ {`> ${props.score[1]}`}
+
+
+
+
+
+ );
+};
+
+export default WebMetrics;
diff --git a/src/app/components/StateRoute/WebMetrics/WebMetricsContainer.tsx b/src/app/components/StateRoute/WebMetrics/WebMetricsContainer.tsx
new file mode 100644
index 000000000..1ffd8efeb
--- /dev/null
+++ b/src/app/components/StateRoute/WebMetrics/WebMetricsContainer.tsx
@@ -0,0 +1,135 @@
+import React from 'react';
+import WebMetrics from './WebMetrics';
+
+const WebMetricsContainer = (props) => {
+ const { webMetrics } = props;
+ // Add default values for all color variables
+ let LCPColor = '#fc2000'; // Default to poor/red
+ let FIDColor = '#fc2000';
+ let FCPColor = '#fc2000';
+ let TTFBColor = '#fc2000';
+ let CLSColor = '#fc2000';
+ let INPColor = '#fc2000';
+
+ // Ensure webMetrics exists and has valid values
+ if (webMetrics) {
+ // LCP color logic
+ if (typeof webMetrics.LCP === 'number') {
+ if (webMetrics.LCP <= 2500) LCPColor = '#0bce6b';
+ else if (webMetrics.LCP <= 4000) LCPColor = '#fc5a03';
+ }
+
+ // FID color logic
+ if (typeof webMetrics.FID === 'number') {
+ if (webMetrics.FID <= 100) FIDColor = '#0bce6b';
+ else if (webMetrics.FID <= 300) FIDColor = '#fc5a03';
+ }
+
+ // FCP color logic
+ if (typeof webMetrics.FCP === 'number') {
+ if (webMetrics.FCP <= 1800) FCPColor = '#0bce6b';
+ else if (webMetrics.FCP <= 3000) FCPColor = '#fc5a03';
+ }
+
+ // TTFB color logic
+ if (typeof webMetrics.TTFB === 'number') {
+ if (webMetrics.TTFB <= 800) TTFBColor = '#0bce6b';
+ else if (webMetrics.TTFB <= 1800) TTFBColor = '#fc5a03';
+ }
+
+ // CLS color logic
+ if (typeof webMetrics.CLS === 'number') {
+ if (webMetrics.CLS <= 0.1) CLSColor = '#0bce6b';
+ else if (webMetrics.CLS <= 0.25) CLSColor = '#fc5a03';
+ }
+
+ // INP color logic
+ if (typeof webMetrics.INP === 'number') {
+ if (webMetrics.INP <= 200) INPColor = '#0bce6b';
+ else if (webMetrics.INP <= 500) INPColor = '#fc5a03';
+ }
+ }
+
+ return (
+
+
+ typeof webMetrics.LCP !== 'number' ? '- ms' : `${webMetrics.LCP.toFixed(2)} ms`
+ }
+ score={['2500 ms', '4000 ms']}
+ overLimit={webMetrics.LCP ? webMetrics.LCP > 7000 : false}
+ label='Largest Contentful Paint'
+ name='Largest Contentful Paint'
+ description='Measures loading performance.'
+ />
+
+ typeof webMetrics.FID !== 'number' ? '- ms' : `${webMetrics.FID.toFixed(2)} ms`
+ }
+ score={['100 ms', '300 ms']}
+ overLimit={webMetrics.FID ? webMetrics.FID > 500 : false}
+ label='First Input Delay'
+ name='First Input Delay'
+ description='Measures interactivity.'
+ />
+
+ typeof webMetrics.FCP !== 'number' ? '- ms' : `${webMetrics.FCP.toFixed(2)} ms`
+ }
+ score={['1800 ms', '3000 ms']}
+ overLimit={webMetrics.FCP ? webMetrics.FCP > 5000 : false}
+ label='First Contentful Paint'
+ name='First Contentful Paint'
+ description='Measures the time it takes the browser to render the first piece of DOM content.'
+ />
+
+ typeof webMetrics.TTFB !== 'number' ? '- ms' : `${webMetrics.TTFB.toFixed(2)} ms`
+ }
+ score={['800 ms', '1800 ms']}
+ overLimit={webMetrics.TTFB ? webMetrics.TTFB > 3000 : false}
+ label='Time To First Byte'
+ name='Time to First Byte'
+ description='Measures the time it takes for a browser to receive the first byte of page content.'
+ />
+
+ `CLS Score: ${
+ typeof webMetrics.CLS !== 'number'
+ ? 'N/A'
+ : `${webMetrics.CLS < 0.01 ? '~0' : webMetrics.CLS.toFixed(2)}`
+ }`
+ }
+ score={['0.1', '0.25']}
+ overLimit={webMetrics.CLS ? webMetrics.CLS > 0.5 : false}
+ label='Cumulative Layout Shift'
+ name='Cumulative Layout Shift'
+ description={`Quantifies the visual stability of a web page by measuring layout shifts during the application's loading and interaction.`}
+ />
+
+ typeof webMetrics.INP !== 'number' ? '- ms' : `${webMetrics.INP.toFixed(2)} ms`
+ }
+ score={['200 ms', '500 ms']}
+ overLimit={webMetrics.INP ? webMetrics.INP > 700 : false}
+ label='Interaction to Next Paint'
+ name='Interaction to Next Paint'
+ description={`Assesses a page's overall responsiveness to user interactions by observing the latency of all click, tap, and keyboard interactions that occur throughout the lifespan of a user's visit to a page`}
+ />
+
+ );
+};
+
+export default WebMetricsContainer;
diff --git a/src/app/components/SwitchApp.tsx b/src/app/components/SwitchApp.tsx
deleted file mode 100644
index be12928f1..000000000
--- a/src/app/components/SwitchApp.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import Select from 'react-select';
-import { useStoreContext } from '../store';
-import { setTab } from '../actions/actions';
-
-
-const SwitchAppDropdown = () => {
- const [{ currentTab, tabs }, dispatch] = useStoreContext();
-
- const tabsArray:any[] = [];
- Object.keys(tabs).forEach(tab => {
- tabsArray.unshift({ value: tab, label: tabs[tab].title});
- });
-
- const currTab = {
- value: currentTab,
- label: tabs[currentTab].title,
- };
-
- const customStyles = {
- menu: (provided, state) => {
- const outline = state.isSelected ? 'transparent' : 'transparent';
- const margin = 0;
-
- return {...provided, outline, margin};
- }
- }
-
- return (
- {
- dispatch(setTab(parseInt(e.value, 10)));
- }}
- options={tabsArray}
- />
- );
-};
-
-export default SwitchAppDropdown;
diff --git a/src/app/components/TimeTravel/Dropdown.tsx b/src/app/components/TimeTravel/Dropdown.tsx
new file mode 100644
index 000000000..db3d86350
--- /dev/null
+++ b/src/app/components/TimeTravel/Dropdown.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import Select from 'react-select';
+import { DropdownProps } from '../../FrontendTypes';
+
+/*
+ Allows the user to change the speed of the time-travel based on the selected dropdown value
+ Component is created in the TravelContainer.tsx
+*/
+
+const Dropdown = (props: DropdownProps): JSX.Element => {
+ const { speeds, setSpeed, selectedSpeed } = props;
+ return (
+
+ );
+};
+
+export default Dropdown;
diff --git a/src/app/components/TimeTravel/VerticalSlider.tsx b/src/app/components/TimeTravel/VerticalSlider.tsx
new file mode 100644
index 000000000..df41058f6
--- /dev/null
+++ b/src/app/components/TimeTravel/VerticalSlider.tsx
@@ -0,0 +1,73 @@
+import React, { useState, useEffect } from 'react';
+import Slider from 'rc-slider';
+import Tooltip from 'rc-tooltip';
+import { changeSlider } from '../../slices/mainSlice';
+import { useDispatch, useSelector } from 'react-redux';
+import { HandleProps, MainSliderProps, MainState, RootState } from '../../FrontendTypes';
+
+const { Handle } = Slider; // component constructor of Slider that allows customization of the handle
+//takes in snapshot length
+const handle = (props: HandleProps): JSX.Element => {
+ const { value, dragging, index, ...restProps } = props;
+
+ return (
+
+
+
+ );
+};
+
+function VerticalSlider(props: MainSliderProps): JSX.Element {
+ const dispatch = useDispatch();
+ const { snapshots } = props; // destructure props to get our total number of snapshots
+ const [sliderIndex, setSliderIndex] = useState(0); // create a local state 'sliderIndex' and set it to 0.
+ const { tabs, currentTab }: MainState = useSelector((state: RootState) => state.main);
+ const { currLocation } = tabs[currentTab]; // we destructure the currentTab object
+
+ useEffect(() => {
+ if (currLocation) {
+ // if we have a 'currLocation'
+ let correctedSliderIndex;
+
+ for (let i = 0; i < snapshots.length; i++) {
+ //@ts-ignore -- ignores the errors on the next line
+ if (snapshots[i].props.index === currLocation.index) {
+ correctedSliderIndex = i;
+ }
+ }
+ setSliderIndex(correctedSliderIndex);
+ } else {
+ setSliderIndex(0); // just set the thumb position to the beginning
+ }
+ }, [currLocation]); // if currLocation changes, rerun useEffect
+
+ return (
+ {
+ // when the slider position changes
+ setSliderIndex(index); // update the sliderIndex
+ dispatch(changeSlider(snapshots[index].props.index));
+ }}
+ handle={handle}
+ />
+ );
+}
+
+export default VerticalSlider;
diff --git a/src/app/components/Tutorial.tsx b/src/app/components/Tutorial.tsx
deleted file mode 100644
index 577a35873..000000000
--- a/src/app/components/Tutorial.tsx
+++ /dev/null
@@ -1,269 +0,0 @@
-/* eslint-disable react/sort-comp */
-/* eslint-disable lines-between-class-members */
-/* eslint-disable react/static-property-placement */
-
-import * as React from 'react';
-import { Component } from 'react';
-import 'intro.js/introjs.css';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faQuestion } from '@fortawesome/free-solid-svg-icons';
-import { tutorialSaveSeriesToggle, setCurrentTabInApp } from '../actions/actions';
-
-//Must be required in. This enables compatibility with TS. If imported in, throws ts error of not rendering steps as a class component correctly.
-const { Steps } = require('intro.js-react');
-
-interface tutorialProps {
- dispatch: (object) => void;
- currentTabInApp: string;
-}
-
-interface tutorialState {
- stepsEnabled: boolean;
-}
-
-// This is the tutorial displayed when the "How to use" button is clicked
-// This needs to be a class component to be compatible with updateStepElement from intro.js
-export default class Tutorial extends React.Component {
- constructor(props: tutorialProps) {
- super(props);
- this.state = {
- stepsEnabled: false,
- };
- }
-
- //tutorial class needs these public variables to be a valid class component for ts when rendered in buttonscontainer.tsx
- public context: any;
- public setState: any;
- public forceUpdate: any;
- public props: any;
- public state: any;
- public refs: any;
-
- render(): JSX.Element {
- const { currentTabInApp, dispatch } = this.props;
-
- // This updates the steps so that they can target dynamically rendered elements
- const onChangeHandler = (currentStepIndex: number) => {
- if (currentTabInApp === 'performance' && currentStepIndex === 1) {
- dispatch(tutorialSaveSeriesToggle('inputBoxOpen'));
- this.steps.updateStepElement(currentStepIndex);
- }
- if (currentTabInApp === 'performance' && currentStepIndex === 2) {
- this.steps.updateStepElement(currentStepIndex);
- }
- if (currentTabInApp === 'performance' && currentStepIndex === 4) {
- dispatch(tutorialSaveSeriesToggle('saved'));
- this.steps.updateStepElement(currentStepIndex);
- }
- if (currentTabInApp === 'performance' && currentStepIndex === 5) {
- this.steps.updateStepElement(currentStepIndex);
- dispatch(setCurrentTabInApp('performance-comparison'));
- }
- if (currentTabInApp === 'performance-comparison' && currentStepIndex === 6) {
- dispatch(tutorialSaveSeriesToggle(false));
- }
- };
-
- const onExit = () => {
- this.setState({ stepsEnabled: false });
- };
- const startIntro = () => {
- // If "How to use" is clicked while in the performance tab,
- // we'll navigate to the snapshops view before starting the tutorial
- // This is because the tutorial steps are designed to begin on the snapshots sub-tab
- // Check out the PerformanceVisx component to see the route redirect logic
- if (currentTabInApp === 'performance' || currentTabInApp === 'performance-comparison' || currentTabInApp === 'performance-component-details') {
- dispatch(setCurrentTabInApp('performance'));
- }
- this.setState({ stepsEnabled: true });
- };
-
- interface stepsObj {
- title: string,
- element?: string,
- intro: string,
- position: string,
- }
-
- let steps: stepsObj[] = [];
-
- switch (currentTabInApp) {
- case 'map':
- steps = [{
- title: 'Reactime Tutorial',
- intro: 'A performance and state managment tool for React apps.',
- position: 'top',
- },
- {
- title: 'Actions',
- element: '.action-container',
- intro: "Reactime records a snapshot whenever a target application's state is changed ",
- position: 'right',
- },
- {
- title: 'Toggle Record Button',
- element: '#recordBtn',
- intro: 'Toggle record button to pause state changes on target application ',
- position: 'right',
- },
- {
- element: '.individual-action',
- title: 'Snapshot',
- intro: 'Each snapshot allows the user to jump to any previously recorded state. It also detects the amount of renders of each component and average time of rendering .',
- position: 'right',
- },
- {
- title: 'Timejump',
- element: '.rc-slider',
- intro: 'Use the slider to go back in time to a particular state change Click the Play button to run through each state change automatically ',
- position: 'top',
- },
- {
- title: 'Lock Button',
- element: '.pause-button',
- intro: 'Use button to lock Reactime to the target application\'s tab in the Chrome Browser ',
- position: 'top',
- },
- {
- title: 'Split Button',
- element: '.split-button',
- intro: ' Use button to split Reactime into two windows in order to view multiple tabs simultaneously ',
- position: 'top',
- },
- {
- title: 'Download Button',
- element: '.export-button',
- intro: 'Use button to download a JSON file of all snapshots ',
- position: 'top',
- },
- {
- title: 'Upload Button',
- element: '.import-button',
- intro: 'Use button to upload a previously downloaded JSON file for snapshot comparisons ',
- position: 'top',
- },
- {
- element: '.map-tab',
- title: 'Map Tab',
- intro: 'This tab visually displays a component hierarchy tree for your app ',
- position: 'bottom',
- },
- {
- title: 'Performance Tab',
- element: '.performance-tab',
- intro: 'User can save a series of state snapshots and use it to analyze changes in component, render performance between current, and previous series of snapshots. User can save a series of state snapshots and use it to analyze changes in component render performance between current and previous series of snapshots. TIP: Click the how to use button within the performance tab for more details. ',
- position: 'bottom',
- },
- {
- title: 'History Tab',
- element: '.history-tab',
- intro: 'This tab visually displays a history of each snapshot ',
- position: 'bottom',
- },
- {
- title: 'Web Metrics Tab',
- element: '.web-metrics-tab',
- intro: ' This tab visually displays performance metrics and allows the user to gauge efficiency of their application ',
- position: 'bottom',
- },
- {
- title: 'Tree Tab',
- element: '.tree-tab',
- intro: 'This tab visually displays a JSON Tree containing the different components and states ',
- position: 'bottom',
- },
- {
- title: 'Tutorial Complete',
- intro: '',
- position: 'top',
- }];
- break;
- case 'performance':
- steps = [{
- title: 'Performance Tab',
- element: '.bargraph-position',
- intro: 'Here we can analyze the render times of our app This is the current series of state changes within our app Mouse over the bargraph elements for details on each specific component ',
- position: 'top',
- },
- {
- title: 'Saving Series & Actions',
- element: '.save-series-button',
- intro: 'Click here to save your current series data ',
- position: 'top',
- },
- {
- title: 'Saving Series & Actions',
- element: '#seriesname',
- intro: 'We can now give our series a name or leave it at the default ',
- position: 'top',
- },
- {
- title: 'Saving Series & Actions',
- element: '.actionname',
- intro: 'If we wish to save a specific action to compare later, give it a name here ',
- position: 'top',
- },
- {
- title: 'Saving Series & Actions',
- element: '.save-series-button',
- intro: 'Press save series again. Your series and actions are now saved! ',
- position: 'top',
- },
- {
- title: 'Comparison Tab',
- element: '#router-link-performance-comparison',
- intro: 'Now let\'s head over to the comparison tab ',
- position: 'top',
- },
- {
- title: 'Comparing Series',
- intro: 'Here we can select a saved series or action to compare ',
- position: 'top',
- }];
- break;
- default:
- steps = [{
- title: 'No Tutorial For This Tab',
- intro: 'A tutorial for this tab has not yet been created Please visit our official Github Repo for more information Reactime Github ',
- position: 'top',
- }];
- break;
- }
-
- return (
- <>
- onChangeHandler(currentStepIndex)}
- ref={steps => (this.steps = steps)}
- />
- startIntro()}
- >
-
- {' '}
- How to use
-
- >
- );
- }
-}
diff --git a/src/app/components/WebMetrics.tsx b/src/app/components/WebMetrics.tsx
deleted file mode 100644
index f5371164f..000000000
--- a/src/app/components/WebMetrics.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-import React, { useEffect } from 'react';
-import Charts from 'react-apexcharts';
-import ReactHover, { Trigger, Hover } from 'react-hover';
-
-import { setCurrentTabInApp } from '../actions/actions';
-import { useStoreContext } from '../store';
-
-const radialGraph = props => {
- const state = {
- series: [props.series],
- options: {
- colors: [props.color],
- chart: {
- height: 100,
- width: 100,
- type: 'radialBar',
- toolbar: {
- show: false,
- },
- },
- plotOptions: {
- radialBar: {
- startAngle: -135,
- endAngle: 135,
- hollow: {
- margin: 0,
- size: '75%',
- background: '#242529',
- image: undefined,
- imageOffsetX: 0,
- imageOffsetY: 0,
- position: 'front',
- dropShadow: {
- enabled: false,
- top: 3,
- left: 0,
- blur: 4,
- opacity: 0.24,
- },
- },
- track: {
- background: '#fff',
- strokeWidth: '3%',
- margin: 0, // margin is in pixels
- dropShadow: {
- enabled: true,
- top: -3,
- left: 0,
- blur: 4,
- opacity: 0.35,
- },
- },
-
- dataLabels: {
- show: true,
- name: {
- offsetY: -10,
- show: true,
- color: '#fff',
- fontSize: '24px',
- },
- value: {
- formatter: props.formatted,
- color: '#fff',
- fontSize: '16px',
- show: true,
- },
- },
- },
- },
- fill: {
- type: 'solid',
- gradient: {
- shade: 'dark',
- type: 'horizontal',
- shadeIntensity: 0.1,
- gradientToColors: [props.color],
- inverseColors: false,
- opacityFrom: 1,
- opacityTo: 1,
- stops: [0, 100],
- },
- },
- stroke: {
- lineCap: 'flat',
- },
- labels: [props.label],
- },
- };
-
- // This updates currentTabInApp which is used to determine what tutorial to display (depending on the active tab within Reactime)
- // Code is commented out because it interferes with the testing suite
- // const [ store, dispatch] = useStoreContext();
- // useEffect(() => {
- // dispatch(setCurrentTabInApp('history'));
- // }, []);
-
- const optionsCursorTrueWithMargin = {
- followCursor: true,
- shiftX: 20,
- shiftY: 0,
- };
-
- return (
-
-
-
-
-
-
-
-
-
-
- {props.name}
-
-
{props.description}
-
-
-
-
- );
-};
-
-export default radialGraph;
diff --git a/src/app/components/snapshots.js b/src/app/components/snapshots.js
deleted file mode 100644
index 9616c3396..000000000
--- a/src/app/components/snapshots.js
+++ /dev/null
@@ -1,144 +0,0 @@
- const snapshots = [
-{
- snapshot: 10,
- component1: 32,
- component2: 27,
- component3: 12,
- "all others": 14
-},
-{
- snapshot: 2,
- component1: 73,
- component2: 45,
- component3: 23,
- "all others": 80
-},
-{
- snapshot: 3,
- component1: 84,
- component2: 46,
- component3: 15,
- "all others": 46
-},
-{
- snapshot: 4,
- component1: 78,
- component2: 45,
- component3: 36,
- "all others": 10
-},
-{
- snapshot: 5,
- component1: 59,
- component2: 52,
- component3: 49,
- "all others": 28
-},
-{
- snapshot: 6,
- component1: 36,
- component2: 96,
- component3: 1,
- "all others": 46
-},
-{
- snapshot: 7,
- component1: 6,
- component2: 6,
- component3: 42,
- "all others": 99
-},
-{
- snapshot: 8,
- component1: 76,
- component2: 29,
- component3: 44,
- "all others": 47
-},
-{
- snapshot: 9,
- component1: 43,
- component2: 62,
- component3: 5,
- "all others": 41
-},
-{
- snapshot: 10,
- component1: 10,
- component2: 84,
- component3: 54,
- "all others": 91
-},
-{
- snapshot: 11,
- component1: 5,
- component2: 78,
- component3: 38,
- "all others": 8
-},
-{
- snapshot: 12,
- component1: 67,
- component2: 73,
- component3: 31,
- "all others": 50
-},
-{
- snapshot: 13,
- component1: 43,
- component2: 42,
- component3: 7,
- "all others": 28
-},
-{
- snapshot: 14,
- component1: 48,
- component2: 26,
- component3: 1,
- "all others": 30
-},
-{
- snapshot: 15,
- component1: 60,
- component2: 28,
- component3: 64,
- "all others": 69
-},
-{
- snapshot: 16,
- component1: 70,
- component2: 15,
- component3: 32,
- "all others": 91
-},
-{
- snapshot: 17,
- component1: 34,
- component2: 86,
- component3: 46,
- "all others": 61
-},
-{
- snapshot: 18,
- component1: 7,
- component2: 50,
- component3: 26,
- "all others": 32
-},
-{
- snapshot: 19,
- component1: 70,
- component2: 40,
- component3: 74,
- "all others": 6
-},
-{
- snapshot: 20,
- component1: 33,
- component2: 78,
- component3: 59,
- "all others": 91
-}
-];
-
-export default snapshots;
diff --git a/src/app/components/useForceUpdate.ts b/src/app/components/useForceUpdate.ts
deleted file mode 100644
index 19186a13f..000000000
--- a/src/app/components/useForceUpdate.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { useState } from 'react';
-
-// This function will force a change in state and cause a re-render of the component.
-// The state information is irrelevant but an update is needed to force a re-render
-export default function useForceUpdate() {
- const [, setValue] = useState(0);
- return () => setValue(value => value + 1);
-}
diff --git a/src/app/constants/actionTypes.ts b/src/app/constants/actionTypes.ts
deleted file mode 100644
index 4dd50fe2d..000000000
--- a/src/app/constants/actionTypes.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-export const TOGGLE_MODE = 'TOGGLE_MODE';
-export const MOVE_BACKWARD = 'MOVE_BACKWARD';
-export const MOVE_FORWARD = 'MOVEFORWARD';
-export const IMPORT = 'IMPORT';
-export const EMPTY = 'EMPTY';
-export const CHANGE_VIEW = 'CHANGE_VIEW';
-export const CHANGE_SLIDER = 'CHANGE_SLIDER';
-export const SET_PORT = 'SET_PORT';
-export const PAUSE = 'PAUSE';
-export const PLAY = 'PLAY';
-export const INITIAL_CONNECT = 'INITIAL_CONNECT';
-export const NEW_SNAPSHOTS = 'NEW_SNAPSHOTS';
-export const SET_TAB = 'SET_TAB';
-export const DELETE_TAB = 'DELETE_TAB';
-export const NO_DEV = 'NO_DEV';
-export const TOGGLE_SPLIT = 'TOGGLE_SPLIT';
-export const TOGGLE_EXPANDED = 'TOGGLE_EXPANDED';
-export const LAUNCH_CONTENT = 'LAUNCH_CONTENT';
-export const SLIDER_ZERO = 'SLIDER_ZERO';
-export const ON_HOVER = 'ON_HOVER';
-export const ON_HOVER_EXIT = 'ON_HOVER_EXIT';
-export const SAVE = 'SAVE';
-export const DELETE_SERIES = 'DELETE_SERIES';
-export const SET_CURRENT_LOCATION = 'SET_CURRENT_LOCATION';
-export const SET_CURRENT_TAB_IN_APP = 'SET_CURRENT_TAB_IN_APP';
-export const TUTORIAL_SAVE_SERIES_TOGGLE = 'TUTORIAL_SAVE_SERIES_TOGGLE';
diff --git a/src/app/containers/ActionContainer.tsx b/src/app/containers/ActionContainer.tsx
index bbc7de14a..147d53bf9 100644
--- a/src/app/containers/ActionContainer.tsx
+++ b/src/app/containers/ActionContainer.tsx
@@ -1,57 +1,53 @@
/* eslint-disable max-len */
-import React, { useEffect, useState } from 'react';
-
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import {
- faToggleOff,
- faToggleOn,
-} from '@fortawesome/free-solid-svg-icons';
-import Action from '../components/Action';
-import SwitchAppDropdown from '../components/SwitchApp';
-import { emptySnapshots, changeView, changeSlider } from '../actions/actions';
-import { useStoreContext } from '../store';
-import RouteDescription from '../components/RouteDescription';
-
-const resetSlider = () => {
- const slider = document.querySelector('.rc-slider-handle');
- if (slider) {
- slider.setAttribute('style', 'left: 0');
- }
-};
-
-function ActionContainer(props): JSX.Element {
- const [{ tabs, currentTab, port }, dispatch] = useStoreContext();
- const {
- currLocation, hierarchy, sliderIndex, viewIndex,
- } = tabs[currentTab];
- const {
- toggleActionContainer, actionView, setActionView,
- } = props;
- const [recordingActions, setRecordingActions] = useState(true);
-
- let actionsArr = [];
- const hierarchyArr: any[] = [];
-
- // function to traverse state from hierarchy and also getting information on display name and component name
- const displayArray = (obj: {
- stateSnapshot: {
- route: any,
- children: any[]
- };
- name: number;
- branch: number;
- index: number;
- children?: [];
- }) => {
+import React, { useEffect, useState, useRef } from 'react';
+import Action from '../components/Actions/Action';
+import { emptySnapshots, changeSlider } from '../slices/mainSlice';
+import { useDispatch, useSelector } from 'react-redux';
+import RouteDescription from '../components/Actions/RouteDescription';
+import DropDown from '../components/Actions/DropDown';
+import ProvConContainer from './ProvConContainer';
+import { ActionContainerProps, CurrentTab, MainState, Obj, RootState } from '../FrontendTypes';
+import { Button } from '@mui/material';
+import RecordButton from '../components/Actions/RecordButton';
+
+/*
+ This file renders the 'ActionContainer'. The action container is the leftmost column in the application. It includes the button that shrinks and expands the action container, a dropdown to select the active site, a clear button, the current selected Route, and a list of selectable snapshots with timestamps.
+*/
+
+function ActionContainer(props: ActionContainerProps): JSX.Element {
+ const [dropdownSelection, setDropdownSelection] = useState('Time Jump');
+ const actionsEndRef = useRef(null as unknown as HTMLDivElement);
+
+ const dispatch = useDispatch();
+ const { currentTab, tabs, port }: MainState = useSelector((state: RootState) => state.main);
+
+ const { currLocation, hierarchy, sliderIndex, viewIndex }: Partial = tabs[currentTab]; // we destructure the currentTab object
+ const { snapshots } = props;
+ const [recordingActions, setRecordingActions] = useState(true); // We create a local state 'recordingActions' and set it to true
+ let actionsArr: JSX.Element[] = []; // we create an array 'actionsArr' that will hold elements we create later on
+ // we create an array 'hierarchyArr' that will hold objects and numbers
+ const hierarchyArr: (number | {})[] = [];
+
+ // Auto scroll when snapshots change
+ useEffect(() => {
+ if (actionsEndRef.current) {
+ actionsEndRef.current.scrollIntoView({ behavior: 'smooth' });
+ }
+ }, [snapshots]);
+
+ const displayArray = (obj: Obj): void => {
if (
- obj.stateSnapshot.children.length > 0
- && obj.stateSnapshot.children[0]
- && obj.stateSnapshot.children[0].state
- && obj.stateSnapshot.children[0].name
+ obj.stateSnapshot.children.length > 0 && // if the 'stateSnapshot' has a non-empty 'children' array
+ obj.stateSnapshot.children[0] && // and there is an element
+ obj.stateSnapshot.children[0].state && // with a 'state'
+ obj.stateSnapshot.children[0].name // and a 'name'
) {
const newObj: Record = {
+ // we create a new Record object (whose property keys are Keys and whose property values are Type.
+ //This utility can be used to map the properties of a type to another type) and populate it's properties with
+ //relevant values from our argument 'obj'.
index: obj.index,
- displayName: `${obj.name}.${obj.branch}`,
+ displayName: `${obj.index + 1}`,
state: obj.stateSnapshot.children[0].state,
componentName: obj.stateSnapshot.children[0].name,
routePath: obj.stateSnapshot.route.url,
@@ -60,58 +56,39 @@ function ActionContainer(props): JSX.Element {
? ''
: obj.stateSnapshot.children[0].componentData,
};
- hierarchyArr.push(newObj);
+ hierarchyArr.push(newObj); // we push our record object into 'hiearchyArr' defined on line 35
}
+
if (obj.children) {
- obj.children.forEach(element => {
+ // if argument has a 'children' array, we iterate through it and run 'displayArray' on each element
+ obj.children.forEach((element): void => {
+ //recursive call
displayArray(element);
});
}
};
- // the hierarchy gets set on the first click in the page
- // when page in refreshed we may not have a hierarchy so we need to check if hierarchy was initialized
- // if true invoke displayArray to display the hierarchy
- if (hierarchy) displayArray(hierarchy);
-
- // handles keyboard presses, function passes an event and index of each action-component
- function handleOnKeyDown(e: KeyboardEvent, i: number) {
- let currIndex = i;
- // up arrow key pressed
- if (e.key === 'ArrowUp') {
- currIndex -= 1;
- if (currIndex < 0) return;
- dispatch(changeView(currIndex));
- }
- // down arrow key pressed
- else if (e.key === 'ArrowDown') {
- currIndex += 1;
- if (currIndex > hierarchyArr.length - 1) return;
- dispatch(changeView(currIndex));
- }
- // enter key pressed
- else if (e.key === 'Enter') {
- e.stopPropagation();
- e.preventDefault(); // needed or will trigger onClick right after
- dispatch(changeSlider(currIndex));
- }
- }
- // Sort by index.
- hierarchyArr.sort((a, b) => a.index - b.index);
+
+ // the hierarchy gets set on the first click in the page
+ if (hierarchy) displayArray(hierarchy); // when page is refreshed we may not have a hierarchy so we need to check if hierarchy was initialized. If it was initialized, invoke displayArray to display the hierarchy
+
+ // Sort hierarchyArr by index property of each object. This will be useful when later when we build our components so that our components will be displayed in index/chronological order
+ hierarchyArr.sort((a: Obj, b: Obj): number => a.index - b.index);
+
+ // we create a map of components that are constructed from "hierarchyArr's" elements/snapshots
actionsArr = hierarchyArr.map(
- (
- snapshot: {
- routePath: any;
- state?: Record;
- index: number;
- displayName: string;
- componentName: string;
- componentData: { actualDuration: number } | undefined;
- },
- ) => {
- const { index } = snapshot;
- const selected = index === viewIndex;
- const last = viewIndex === -1 && index === hierarchyArr.length - 1;
+ (snapshot: {
+ routePath: any;
+ state?: Record;
+ index: number;
+ displayName: string;
+ componentName: string;
+ componentData: { actualDuration: number } | undefined;
+ }) => {
+ const { index } = snapshot; // destructure index from snapshot
+ const selected = index === viewIndex; // boolean on whether the current index is the same as the viewIndex
+ const last = viewIndex === -1 && index === hierarchyArr.length - 1; // boolean on whether the view index is less than 0 and if the index is the same as the last snapshot's index value in hierarchyArr
const isCurrIndex = index === currLocation.index;
+
return (
-
);
},
);
- useEffect(() => {
- setActionView(true);
- }, [setActionView]);
// Function sends message to background.js which sends message to the content script
- const toggleRecord = () => {
+ const toggleRecord = (): void => {
port.postMessage({
action: 'toggleRecord',
tabId: currentTab,
});
- // Record button's icon is being togggled on click
- setRecordingActions(!recordingActions);
+ setRecordingActions(!recordingActions); // Record button's icon is being togggled on click
};
- // Logic to create the route description components
type routes = {
- [route: string]: [];
- }
+ [route: string]: [];
+ };
+
+ const routes: {} = {}; // Logic to create the route description components begin
- const routes = {};
for (let i = 0; i < actionsArr.length; i += 1) {
+ // iterate through our actionsArr
if (!routes.hasOwnProperty(actionsArr[i].props.routePath)) {
- routes[actionsArr[i].props.routePath] = [actionsArr[i]];
+ routes[actionsArr[i].props.routePath] = [actionsArr[i]]; // if 'routes' doesn't have a property key that is the same as the current component at index[i] routePath we create an array with the first element being the component at index [i].
} else {
- routes[actionsArr[i].props.routePath].push(actionsArr[i]);
+ routes[actionsArr[i].props.routePath].push(actionsArr[i]); // If it does exist, we push the component at index [i] to the apporpriate routes[routePath]
}
}
// the conditional logic below will cause ActionContainer.test.tsx to fail as it cannot find the Empty button
// UNLESS actionView={true} is passed into in the beforeEach() call in ActionContainer.test.tsx
return (
-
-
-
-
-
+
);
}
diff --git a/src/app/containers/ButtonsContainer.tsx b/src/app/containers/ButtonsContainer.tsx
index e5459e4b8..b74edeba4 100644
--- a/src/app/containers/ButtonsContainer.tsx
+++ b/src/app/containers/ButtonsContainer.tsx
@@ -1,110 +1,115 @@
import * as React from 'react';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import {
- faUpload,
- faDownload,
- faSquare,
- faColumns,
- faUnlock,
- faLock,
-} from '@fortawesome/free-solid-svg-icons';
-import { importSnapshots, toggleMode, toggleSplit } from '../actions/actions';
-import { useStoreContext } from '../store';
+import { Button } from '@mui/material';
+import Tutorial from '../components/Buttons/Tutorial';
+import { toggleMode, importSnapshots, startReconnect } from '../slices/mainSlice';
+import { useDispatch, useSelector } from 'react-redux';
+import StatusDot from '../components/Buttons/StatusDot';
+import { MainState, RootState } from '../FrontendTypes';
+import { Lock, Unlock, Download, Upload, RefreshCw } from 'lucide-react';
+import { toast } from 'react-hot-toast';
-import Tutorial from '../components/Tutorial';
-
-function exportHandler(snapshots: []) {
- // create invisible download anchor link
- const fileDownload = document.createElement('a');
-
- // set file in anchor link
+function exportHandler(snapshots: []): void {
+ const fileDownload: HTMLAnchorElement = document.createElement('a');
fileDownload.href = URL.createObjectURL(
new Blob([JSON.stringify(snapshots)], { type: 'application/json' }),
);
-
- // set anchor as file download and click it
fileDownload.setAttribute('download', 'snapshot.json');
fileDownload.click();
-
- // remove file url
URL.revokeObjectURL(fileDownload.href);
}
-function importHandler(dispatch: (a: unknown) => void) {
+function importHandler(dispatch: (a: unknown) => void): void {
const fileUpload = document.createElement('input');
fileUpload.setAttribute('type', 'file');
fileUpload.onchange = (e: Event) => {
const reader = new FileReader();
+ const eventFiles = e.target as HTMLInputElement;
+
+ if (eventFiles) {
+ reader.readAsText(eventFiles.files[0]);
+ }
+
reader.onload = () => {
const test = reader.result.toString();
return dispatch(importSnapshots(JSON.parse(test)));
};
- const eventFiles = e.target as HTMLInputElement;
- if (eventFiles?.hasOwnProperty('files')) {
- // const eventFiles = target as HTMLInputElement;
- if (eventFiles) {
- reader.readAsText(eventFiles.files[0]);
- }
- }
};
fileUpload.click();
}
function ButtonsContainer(): JSX.Element {
- const [{ tabs, currentTab, split, currentTabInApp }, dispatch] = useStoreContext();
+ const dispatch = useDispatch();
+ const { currentTab, tabs, currentTabInApp, connectionStatus }: MainState = useSelector(
+ (state: RootState) => state.main,
+ );
+
+ //@ts-ignore
const {
- snapshots,
+ //@ts-ignore
mode: { paused },
} = tabs[currentTab];
- return (
-
-
dispatch(toggleMode('paused'))}
- >
- {paused ? (
-
- ) : (
-
- )}
- {paused ? 'Unlock' : 'Lock'}
-
-
-
dispatch(toggleSplit())}
- >
- {split ? (
-
- ) : (
-
- )}
- {split ? 'Unsplit' : 'Split'}
-
+ const handleReconnect = () => {
+ dispatch(startReconnect());
+ toast.success('Successfully reconnected', {
+ duration: 2000,
+ position: 'top-right',
+ style: {
+ background: 'var(--bg-primary)',
+ color: 'var(--text-primary)',
+ },
+ iconTheme: {
+ primary: 'var(--color-primary)',
+ secondary: 'var(--text-primary)',
+ },
+ });
+ };
-
exportHandler(snapshots)}
- >
-
- Download
-
-
importHandler(dispatch)}
- >
-
- Upload
-
- {/* The component below renders a button for the tutorial walkthrough of Reactime */}
-
+ return (
+
+
+ dispatch(toggleMode('paused'))}
+ >
+ {paused ? (
+
+ ) : (
+
+ )}
+ {paused ? 'Locked' : 'Unlocked'}
+
+ exportHandler(tabs[currentTab])}
+ >
+
+ Download
+
+ importHandler(dispatch)}>
+
+ Upload
+
+
+
+
+
+ }
+ >
+
+ Reconnect
+
+
);
}
diff --git a/src/app/containers/ErrorContainer.tsx b/src/app/containers/ErrorContainer.tsx
index 6d8516299..61c22378b 100644
--- a/src/app/containers/ErrorContainer.tsx
+++ b/src/app/containers/ErrorContainer.tsx
@@ -1,97 +1,156 @@
-/* eslint-disable max-len */
-import React, { useState, useEffect, useRef } from 'react';
-import { launchContentScript } from '../actions/actions';
-import Loader from '../components/Loader';
-import ErrorMsg from '../components/ErrorMsg';
-import { useStoreContext } from '../store';
-
-function ErrorContainer(): any {
- const [store, dispatch] = useStoreContext();
- const { tabs, currentTitle, currentTab } = store;
- // hooks for error checks
- const [loadingArray, setLoading] = useState([true, true, true]);
- const titleTracker = useRef(currentTitle);
- const timeout = useRef(null);
-
- function launch(): void{ dispatch(launchContentScript(tabs[currentTab])); }
-
- // check if tabObj exists > set status
- const status = { contentScriptLaunched: false, reactDevToolsInstalled: false, targetPageisaReactApp: false };
- if (tabs[currentTab]) { Object.assign(status, tabs[currentTab].status); }
-
- // hook that sets timer while waiting for a snapshot from the background script, resets if the tab changes/reloads
+import React, { useEffect } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { launchContentScript, setTab } from '../slices/mainSlice';
+import { MainState, RootState, ErrorContainerProps } from '../FrontendTypes';
+import { RefreshCw, Github, PlayCircle } from 'lucide-react';
+
+function ErrorContainer(props: ErrorContainerProps): JSX.Element {
+ const dispatch = useDispatch();
+ const { tabs, currentTitle, currentTab }: MainState = useSelector(
+ (state: RootState) => state.main,
+ );
+
+ // Helper function to check if a URL is localhost
+ const isLocalhost = (url: string): boolean => {
+ return url.startsWith('http://localhost:') || url.startsWith('https://localhost:');
+ };
+
+ // Add effect to initialize currentTab if not set
useEffect(() => {
- function setLoadingArray(i: number, value: boolean) {
- if (loadingArray[i] !== value) { // avoid unecessary state changes
- const loadingArrayClone = [...loadingArray];
- loadingArrayClone[i] = value;
- setLoading(loadingArrayClone);
+ const initializeCurrentTab = async () => {
+ if (!currentTab) {
+ try {
+ // Query specifically for localhost tabs first
+ const tabs = await chrome.tabs.query({ currentWindow: true });
+ const localhostTab = tabs.find(tab => tab.url && isLocalhost(tab.url));
+
+ if (localhostTab?.id) {
+ dispatch(setTab(localhostTab.id));
+ } else {
+ // Fallback to active tab if no localhost found
+ const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });
+ if (activeTab?.id) {
+ dispatch(setTab(activeTab.id));
+ }
+ }
+ } catch (error) {
+ console.error('Error getting tab:', error);
+ }
}
- }
+ };
+
+ initializeCurrentTab();
+ }, [currentTab, dispatch]);
- // check for tab reload/change: reset loadingArray
- if (titleTracker.current !== currentTitle) {
- titleTracker.current = currentTitle;
- setLoadingArray(0, true);
- setLoadingArray(1, true);
- setLoadingArray(2, true);
- if (timeout.current) {
- clearTimeout(timeout.current);
- timeout.current = null;
+ // function that launches the main app and refreshes the page
+ async function launch(): Promise
{
+ try {
+ // If no current tab, try to find localhost tab first
+ if (!currentTab) {
+ const tabs = await chrome.tabs.query({ currentWindow: true });
+ const localhostTab = tabs.find(tab => tab.url && isLocalhost(tab.url));
+
+ if (localhostTab?.id) {
+ dispatch(setTab(localhostTab.id));
+ await initializeLaunch(localhostTab.id);
+ } else {
+ console.warn('No localhost tab found');
+ }
+ return;
}
- }
- // if content script hasnt been found, set timer or immediately resolve
- if (!status.contentScriptLaunched) {
- if (loadingArray[0] === true) {
- timeout.current = setTimeout(() => { setLoadingArray(0, false); }, 1500);
+
+ // Verify current tab is still localhost
+ const tab = await chrome.tabs.get(currentTab);
+ if (!tab.url || !isLocalhost(tab.url)) {
+ // Try to find a localhost tab
+ const tabs = await chrome.tabs.query({ currentWindow: true });
+ const localhostTab = tabs.find(tab => tab.url && isLocalhost(tab.url));
+
+ if (localhostTab?.id) {
+ dispatch(setTab(localhostTab.id));
+ await initializeLaunch(localhostTab.id);
+ } else {
+ console.warn('No localhost tab found');
+ }
+ return;
}
- } else {
- setLoadingArray(0, false);
- }
- if (loadingArray[0] === false && status.contentScriptLaunched === true) {
- setLoadingArray(1, false);
- }
- if (loadingArray[1] === false && status.reactDevToolsInstalled === true) {
- setLoadingArray(2, false);
+
+ await initializeLaunch(currentTab);
+ } catch (error) {
+ console.error('Error during launch:', error);
}
- }, [status, currentTitle, timeout, loadingArray]);
+ }
- return (
-
-
+ async function initializeLaunch(tabId: number): Promise
{
+ const defaultPayload = {
+ status: {
+ contentScriptLaunched: false,
+ reactDevToolsInstalled: false,
+ targetPageisaReactApp: false,
+ },
+ };
-
- Launching Reactime on tab:
- {' '}
- {currentTitle}
-
+ dispatch(launchContentScript(defaultPayload));
+
+ // Allow the dispatch to complete before refreshing
+ setTimeout(() => {
+ chrome.tabs.reload(tabId);
+ }, 100);
+ }
-
-
Checking if content script has been launched on current tab
-
+ return (
+
+
-
Checking if React Dev Tools has been installed
-
+
+
+
+
+ Welcome to Reactime
+
-
Checking if target is a compatible React app
-
+
+ To ensure Reactime works correctly with your React application, please either refresh
+ your development page or click the launch button below. This allows Reactime to properly
+ connect with your app and start monitoring state changes.
+
+
+ Important: Reactime requires React Developer Tools to be installed and will only track state
+ changes on localhost development servers. If you haven't already, please{' '}
+
+ install React Developer Tools
+ {' '}
+ first.
+
+
-
+
+ Note: Reactime only works with React applications and by default only launches on URLs
+ starting with localhost.
+
+
+
+
+ Launch Reactime
+
-
-
-
-
- Please visit reactime.dev to more info.
-
);
}
-export default ErrorContainer;
+export default ErrorContainer;
\ No newline at end of file
diff --git a/src/app/containers/MainContainer.tsx b/src/app/containers/MainContainer.tsx
index e8fec2e69..01028fd5d 100644
--- a/src/app/containers/MainContainer.tsx
+++ b/src/app/containers/MainContainer.tsx
@@ -1,5 +1,5 @@
/* eslint-disable max-len */
-import React, { useEffect, useState } from 'react';
+import React, { useState } from 'react';
import ActionContainer from './ActionContainer';
import TravelContainer from './TravelContainer';
import ButtonsContainer from './ButtonsContainer';
@@ -12,110 +12,129 @@ import {
setTab,
deleteTab,
noDev,
+ aReactApp,
setCurrentLocation,
- pause,
-} from '../actions/actions';
-import { useStoreContext } from '../store';
+ disconnected,
+ endConnect,
+} from '../slices/mainSlice';
+import { useDispatch, useSelector } from 'react-redux';
+import { MainState, RootState } from '../FrontendTypes';
-//Must be required in. This enables compatibility with TS. If imported in, throws ts error of not rendering steps as a class component correctly.
-const Split = require('react-split');
+/*
+ This is the main container where everything in our application is rendered
+*/
function MainContainer(): JSX.Element {
- const [store, dispatch] = useStoreContext();
- const {
- tabs, currentTab, port, split,
- } = store;
- const [actionView, setActionView] = useState(true);
- // this function handles Time Jump sidebar view
- const toggleActionContainer = () => {
- setActionView(!actionView);
- // aside is like an added text that appears "on the side" aside some text.
- const toggleElem = document.querySelector('aside');
- toggleElem.classList.toggle('no-aside');
- // hides the record toggle button from Actions Container in Time Jump sidebar view
- const recordBtn = document.getElementById('recordBtn');
- if (recordBtn.style.display === 'none') {
- recordBtn.style.display = 'flex';
- } else {
- recordBtn.style.display = 'none';
+ const dispatch = useDispatch();
+
+ const { currentTab, tabs, port }: MainState = useSelector((state: RootState) => state.main);
+
+ // Function handles when Reactime unexpectedly disconnects
+ const handleDisconnect = (msg): void => {
+ if (msg === 'portDisconnect') dispatch(disconnected());
+ };
+
+ // Function to listen for a message containing snapshots from the /extension/build/background.js service worker
+ const messageListener = ({
+ action,
+ payload,
+ sourceTab,
+ }: {
+ action: string;
+ payload: Record
;
+ sourceTab: number;
+ }) => {
+ let maxTab: number;
+
+ // Add validation check
+ if (!sourceTab && action !== 'keepAlive') {
+ // Ensure payload exists and is an object
+ if (payload && typeof payload === 'object') {
+ const tabsArray = Object.keys(payload);
+ const numTabsArray = tabsArray.map((tab) => Number(tab));
+ maxTab = numTabsArray.length > 0 ? Math.max(...numTabsArray) : 0;
+ } else {
+ console.warn('Invalid payload received:', payload);
+ maxTab = 0;
+ }
+ }
+
+ switch (action) {
+ case 'deleteTab': {
+ dispatch(deleteTab(payload));
+ break;
+ }
+ case 'devTools': {
+ dispatch(noDev(payload));
+ break;
+ }
+ case 'aReactApp': {
+ dispatch(aReactApp(payload));
+ break;
+ }
+ case 'changeTab': {
+ dispatch(setTab(payload));
+ break;
+ }
+ case 'sendSnapshots': {
+ dispatch(setTab(payload));
+ dispatch(addNewSnapshots(payload));
+ break;
+ }
+ case 'initialConnectSnapshots': {
+ dispatch(initialConnect(payload));
+ break;
+ }
+ case 'setCurrentLocation': {
+ dispatch(setCurrentLocation(payload));
+ break;
+ }
+ default:
}
};
- // let port;
- useEffect(() => {
- // only open port once
- if (port) return;
-
- // open long-lived connection with background script
- const currentPort = chrome.runtime.connect();
- // listen for a message containing snapshots from the background script
- currentPort.onMessage.addListener(
- // parameter message is an object with following type script properties
- (message: {
- action: string;
- payload: Record;
- sourceTab: number;
- }) => {
- const { action, payload, sourceTab } = message;
- let maxTab: number;
- if (!sourceTab) {
- const tabsArray: Array = Object.keys(payload);
- const numTabsArray: number[] = tabsArray.map(tab => Number(tab));
- maxTab = Math.max(...numTabsArray);
- }
- switch (action) {
- case 'deleteTab': {
- dispatch(deleteTab(payload));
- break;
- }
- case 'devTools': {
- dispatch(noDev(payload));
- break;
- }
- case 'changeTab': {
- dispatch(setTab(payload));
- break;
- }
- case 'sendSnapshots': {
- dispatch(setTab(sourceTab));
- // set state with the information received from the background script
- dispatch(addNewSnapshots(payload));
- break;
- }
- case 'initialConnectSnapshots': {
- dispatch(initialConnect(payload));
- break;
- }
- case 'setCurrentLocation': {
- dispatch(setCurrentLocation(payload));
- break;
- }
- default:
- }
- return true;
- },
- );
- currentPort.onDisconnect.addListener(() => {
- console.log('this port is disconnecting line 79');
- // disconnecting
- });
+ async function awaitPortConnection() {
+ if (port) return; // only open port once so if it exists, do not run useEffect again
+
+ // Connect ot port and assign evaluated result (obj) to currentPort
+ const currentPort = await chrome.runtime.connect({ name: 'panel' });
+
+ // If messageListener exists on currentPort, remove it
+ while (currentPort.onMessage.hasListener(messageListener))
+ currentPort.onMessage.removeListener(messageListener);
+
+ // Add messageListener to the currentPort
+ currentPort.onMessage.addListener(messageListener);
+
+ // If handleDisconnect exists on chrome.runtime, remove it
+ while (chrome.runtime.onMessage.hasListener(handleDisconnect))
+ chrome.runtime.onMessage.removeListener(handleDisconnect);
+
+ // add handleDisconnect to chrome.runtime
+ chrome.runtime.onMessage.addListener(handleDisconnect);
// assign port to state so it could be used by other components
dispatch(setPort(currentPort));
- });
- // Error Page launch IF(Content script not launched OR RDT not installed OR Target not React app)
- if (!tabs[currentTab] || !tabs[currentTab].status.reactDevToolsInstalled || !tabs[currentTab].status.targetPageisaReactApp) {
- return (
-
- );
+ dispatch(endConnect());
}
+ awaitPortConnection();
- const {
- currLocation, viewIndex, sliderIndex, snapshots, hierarchy, webMetrics,
- } = tabs[currentTab];
- // if viewIndex is -1, then use the sliderIndex instead
- const snapshotView = viewIndex === -1 ? snapshots[sliderIndex] : snapshots[viewIndex];
+ if (
+ !tabs[currentTab] ||
+ //@ts-ignore
+ !tabs[currentTab].status.reactDevToolsInstalled ||
+ //@ts-ignore
+ !tabs[currentTab].status.targetPageisaReactApp
+ ) {
+ // @ts-ignore
+ return ;
+ }
+
+ const { axSnapshots, currLocation, viewIndex, sliderIndex, snapshots, hierarchy, webMetrics } =
+ tabs[currentTab]; // we destructure the currentTab object which is passed in from background.js
+ //@ts-ignore
+ const snapshotView = viewIndex === -1 ? snapshots[sliderIndex] : snapshots[viewIndex]; // if viewIndex is -1, then use the sliderIndex instead
// cleaning hierarchy and snapshotView from stateless data
const statelessCleaning = (obj: {
name?: string;
@@ -140,14 +159,12 @@ function MainContainer(): JSX.Element {
if (newObj.children) {
newObj.children = [];
if (obj.children.length > 0) {
- obj.children.forEach(
- (element: { state?: object | string; children?: [] }) => {
- if (element.state !== 'stateless' || element.children.length > 0) {
- const clean = statelessCleaning(element);
- newObj.children.push(clean);
- }
- },
- );
+ obj.children.forEach((element: { state?: object | string; children?: [] }) => {
+ if (element.state !== 'stateless' || element.children.length > 0) {
+ const clean = statelessCleaning(element);
+ newObj.children.push(clean);
+ }
+ });
}
}
return newObj;
@@ -155,65 +172,33 @@ function MainContainer(): JSX.Element {
const snapshotDisplay = statelessCleaning(snapshotView);
const hierarchyDisplay = statelessCleaning(hierarchy);
- function handleSplit(currentSplitMode: boolean): JSX.Element {
- if (!currentSplitMode) {
- return (
-
-
-
- );
- }
- return (
-
-
-
-
- );
- }
-
return (
-
-
-
- {snapshots.length ? (handleSplit(split)) : null}
-
-
+
+
+
+ {/* @ts-ignore */}
+ {snapshots.length ? (
+
+
+
+ ) : null}
+
+ {/* @ts-ignore */}
+
+
+
);
diff --git a/src/app/containers/ProvConContainer.tsx b/src/app/containers/ProvConContainer.tsx
new file mode 100644
index 000000000..5fd6dfa22
--- /dev/null
+++ b/src/app/containers/ProvConContainer.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import { ProvConContainerProps } from '../FrontendTypes';
+import JsonSection from '../components/JsonSection/JsonSection';
+import { keepContextAndProviderNodes, filterComponentProperties } from '../utils/providerUtils';
+
+const ProvConContainer = ({ currentSnapshot }: ProvConContainerProps): JSX.Element => {
+ // Process and filter the component tree
+ const contextProvidersOnly = keepContextAndProviderNodes(currentSnapshot);
+ const filteredProviders = filterComponentProperties(contextProvidersOnly);
+
+ return (
+
+
Providers / Consumers
+ {filteredProviders ? (
+
+ ) : (
+
+
No providers or consumers found in the current component tree.
+
+ )}
+
+ );
+};
+
+export default ProvConContainer;
diff --git a/src/app/containers/StateContainer.tsx b/src/app/containers/StateContainer.tsx
index 48bf732d3..06f1a58b7 100644
--- a/src/app/containers/StateContainer.tsx
+++ b/src/app/containers/StateContainer.tsx
@@ -3,78 +3,34 @@ import React, { useState } from 'react';
/*
that keeps the history of your “URL” in memory (does not read/write to the address bar)
Useful in tests and non-browser environments like React Native.
*/
-import {
- MemoryRouter as Router,
- Route,
- NavLink,
- Switch,
-} from 'react-router-dom';
+import { MemoryRouter as Router, Route, NavLink, Routes, Outlet } from 'react-router-dom';
import StateRoute from '../components/StateRoute/StateRoute';
-import DiffRoute from '../components/DiffRoute';
-
-interface StateContainerProps {
- snapshot: Record<
- number,
- {
- name?: string;
- componentData?: Record;
- state?: Record;
- stateSnaphot?: Record;
- children?: unknown[];
- }
- >;
- toggleActionContainer?: any;
- webMetrics?: object;
- hierarchy: Record;
- snapshots?: [];
- viewIndex?: number;
- currLocation?: object;
-}
+import DiffRoute from '../components/DiffRoute/DiffRoute';
+import { StateContainerProps } from '../FrontendTypes';
+import { Outlet } from 'react-router';
// eslint-disable-next-line react/prop-types
const StateContainer = (props: StateContainerProps): JSX.Element => {
const {
- snapshot,
- hierarchy,
- snapshots,
- viewIndex,
- webMetrics,
- currLocation,
- snapshots,
+ snapshot, // from 'tabs[currentTab]' object in 'MainContainer'
+ hierarchy, // from 'tabs[currentTab]' object in 'MainContainer'
+ snapshots, // from 'tabs[currentTab].snapshotDisplay' object in 'MainContainer'
+ viewIndex, // from 'tabs[currentTab]' object in 'MainContainer'
+ webMetrics, // from 'tabs[currentTab]' object in 'MainContainer'
+ currLocation, // from 'tabs[currentTab]' object in 'MainContainer'
+ axSnapshots, // from 'tabs[currentTab]' object in 'MainContainer'
} = props;
return (
-
-
-
-
-
-
- State
-
-
- Diff
-
-
-
-
- }
- />
+ <>
+
+
+
(
+ path='/*'
+ element={
{
snapshots={snapshots}
currLocation={currLocation}
/>
- )}
+ }
/>
-
+
-
+ >
);
};
diff --git a/src/app/containers/TravelContainer.tsx b/src/app/containers/TravelContainer.tsx
index 563a7e243..428a96918 100644
--- a/src/app/containers/TravelContainer.tsx
+++ b/src/app/containers/TravelContainer.tsx
@@ -1,66 +1,77 @@
/* eslint-disable max-len */
import React, { useState } from 'react';
-import MainSlider from '../components/MainSlider';
-import Dropdown from '../components/Dropdown';
-import {
- playForward, pause, startPlaying, moveForward, moveBackward, resetSlider,
-} from '../actions/actions';
-import { useStoreContext } from '../store';
+import Dropdown from '../components/TimeTravel/Dropdown';
+import { playForward, pause, startPlaying, resetSlider, changeSlider } from '../slices/mainSlice';
+import { useDispatch, useSelector } from 'react-redux';
+import { MainState, RootState, TravelContainerProps } from '../FrontendTypes';
+import { Play, Pause } from 'lucide-react';
-const speeds = [
+/*
+ This container renders the time-travel play button, seek bar, playback controls, and the playback speed dropdown, located towards the bottom of the application, above the locked, download, upload, and tutorial buttons
+*/
+
+// This object is used to create the options in the playback speed 'Dropdown' component
+const speeds: {
+ value: number;
+ label: string;
+}[] = [
{ value: 2000, label: '0.5x' },
{ value: 1000, label: '1.0x' },
{ value: 500, label: '2.0x' },
];
-
-// start slider movement
-function play(speed:number, playing:boolean, dispatch:(a:any) => void, snapshotsLength:number, sliderIndex:number) {
+//NOTE HERE REMOVED THE DISPATCH FUNCTION IN THE TYPE SCRIPT:
+//USING THE BUILT IN DISPATCH
+function play( // function that will start/pause slider movement
+ speed: number,
+ playing: boolean,
+ dispatch: (a: any) => void,
+ snapshotsLength: number,
+ sliderIndex: number,
+): void {
if (playing) {
+ // if already playing, clicking the button will pause the slider
dispatch(pause());
} else {
- let currentIndex = sliderIndex;
+ let currentIndex = sliderIndex; // the 'currentIndex' will be wherever the 'sliderIndex' is
if (currentIndex === snapshotsLength - 1) {
- // dispatch action to reset the slider
+ // if we reach the last snapshot, reset the slider and the currentIndex
dispatch(resetSlider());
currentIndex = 0;
}
- const intervalId = setInterval(() => {
+ const intervalId: NodeJS.Timeout = setInterval(() => {
+ // sets interval period to wait before advancing 'currentIndex'/slider
if (currentIndex < snapshotsLength - 1) {
- dispatch(playForward());
+ // as long as we're not the last snapshot, increment slider up through our dispatch and increment index
+ dispatch(playForward(true));
currentIndex += 1;
+ dispatch(changeSlider(currentIndex));
} else {
- dispatch(pause());
+ dispatch(pause()); // pause the slider when we reach the end
}
}, speed);
- dispatch(startPlaying(intervalId));
+ dispatch(startPlaying(intervalId)); // set's tabs[currentTab].playing to true and tabs[currentTab].intervalId to line 45's 'setInterval()'
}
}
-interface TravelContainerProps {
- snapshotsLength: number,
-}
-
-function TravelContainer(props:TravelContainerProps): JSX.Element {
+function TravelContainer(props: TravelContainerProps): JSX.Element {
const { snapshotsLength } = props;
- const [selectedSpeed, setSpeed] = useState(speeds[1]);
- const [{ tabs, currentTab }, dispatch] = useStoreContext();
+ const [selectedSpeed, setSpeed] = useState(speeds[1]); // create a new local state selectedSpeed and set it to the second element of the 'speeds' array (1.0x speed)
+
+ const dispatch = useDispatch();
+ const { tabs, currentTab }: MainState = useSelector((state: RootState) => state.main);
const { sliderIndex, playing } = tabs[currentTab];
return (
-
+
play(selectedSpeed.value, playing, dispatch, snapshotsLength, sliderIndex)}
>
- {playing ? 'Pause' : 'Play'}
-
-
-
dispatch(moveBackward())} type="button">
- {'<'}
-
-
dispatch(moveForward())} type="button">
- {'>'}
+
+ {playing ?
:
}
+
{playing ? 'Pause' : 'Play'}
+
diff --git a/src/app/index.tsx b/src/app/index.tsx
index 93d63cc4f..b24b57132 100644
--- a/src/app/index.tsx
+++ b/src/app/index.tsx
@@ -1,7 +1,14 @@
/* eslint-disable react/jsx-filename-extension */
import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './components/App';
+import { createRoot } from 'react-dom/client';
+import App from './App';
import './styles/main.scss';
+import { store } from './store'; //imported RTK Store
+import { Provider } from 'react-redux'; //imported Provider
-ReactDOM.render(
, document.getElementById('root'));
+const root = createRoot(document.getElementById('root'));
+root.render(
+
+
+ ,
+);
diff --git a/src/app/module.d.ts b/src/app/module.d.ts
index aa972d03f..8b5ed8d9c 100644
--- a/src/app/module.d.ts
+++ b/src/app/module.d.ts
@@ -7,11 +7,8 @@ declare module 'd3';
declare module 'react-spinners';
declare module 'immer';
declare module 'jsondiffpatch';
-declare module 'react-html-parser';
+declare module 'html-react-parser';
declare module 'react-json-tree';
declare module 'react-router-dom';
-declare module 'enzyme-adapter-react-16';
-declare module 'enzyme';
declare module 'react-apexcharts';
declare module 'react-hover';
-
\ No newline at end of file
diff --git a/src/app/reducers/mainReducer.js b/src/app/reducers/mainReducer.js
deleted file mode 100644
index 124cf1949..000000000
--- a/src/app/reducers/mainReducer.js
+++ /dev/null
@@ -1,375 +0,0 @@
-import { produce } from 'immer';
-import _, { values } from 'lodash';
-import * as types from '../constants/actionTypes.ts';
-
-export default (state, action) => produce(state, draft => {
- const {
- port, currentTab, tabs,
- } = draft;
- const {
- hierarchy, snapshots, mode, intervalId, viewIndex, sliderIndex,
- } = tabs[currentTab] || {};
-
- // eslint-disable-next-line max-len
- // function that finds the index in the hierarchy and extracts the name of the equivalent index to add to the post message
- // eslint-disable-next-line consistent-return
-
- // (action.payload, hierarchy)
- const findName = (index, obj) => {
- // eslint-disable-next-line eqeqeq
- if (obj && obj.index == index) {
- return obj.name;
- }
- const objChildArray = [];
- if (obj) {
- // eslint-disable-next-line no-restricted-syntax
- for (const objChild of obj.children) {
- objChildArray.push(findName(index, objChild));
- }
- }
- // eslint-disable-next-line no-restricted-syntax
- for (const objChildName of objChildArray) {
- if (objChildName) {
- return objChildName;
- }
- }
- };
-
- switch (action.type) {
- // This saves the series user wants to save to chrome local storage
- case types.SAVE: {
- const { newSeries, newSeriesName } = action.payload;
- if (!tabs[currentTab].seriesSavedStatus) {
- tabs[currentTab] = { ...tabs[currentTab], seriesSavedStatus: 'inputBoxOpen' };
- break;
- }
- // Runs if series name input box is active.
- // Updates chrome local storage with the newly saved series. Console logging the seriesArray grabbed from local storage may be helpful.
- if (tabs[currentTab].seriesSavedStatus === 'inputBoxOpen') {
- let seriesArray = localStorage.getItem('project');
- seriesArray = seriesArray === null ? [] : JSON.parse(seriesArray);
- newSeries.name = newSeriesName;
- seriesArray.push(newSeries);
- localStorage.setItem('project', JSON.stringify(seriesArray));
- tabs[currentTab] = { ...tabs[currentTab], seriesSavedStatus: 'saved' };
- break;
- }
- break;
- }
- // Delete case will delete ALL stored series in chrome local storage. To see chrome storage related data
- // Chrome Extension Manager (chrome:extensions) --> background page link --> Application Tab
- case types.DELETE_SERIES: {
- const allStorage = () => {
- const keys = Object.keys(localStorage);
- let i = keys.length;
- while (i--) {
- localStorage.removeItem(keys[i]);
- }
- };
- allStorage();
- Object.keys(tabs).forEach(tab => {
- tabs[tab] = {
- ...tabs[tab],
- };
- });
- tabs[currentTab] = { ...tabs[currentTab], seriesSavedStatus: false };
- break;
- }
- case types.ON_HOVER_EXIT: {
- port.postMessage({
- action: 'onHoverExit',
- payload: action.payload,
- tabId: currentTab,
- });
- break;
- }
-
- case types.ON_HOVER: {
- port.postMessage({
- action: 'onHover',
- payload: action.payload,
- tabId: currentTab,
- });
- break;
- }
-
- case types.MOVE_BACKWARD: {
- if (sliderIndex > 0) {
- const newIndex = sliderIndex - 1;
- // eslint-disable-next-line max-len
- // finds the name by the newIndex parsing through the hierarchy to send to background.js the current name in the jump action
- const nameFromIndex = findName(newIndex, hierarchy);
-
- port.postMessage({
- action: 'jumpToSnap',
- payload: snapshots[newIndex],
- index: newIndex,
- name: nameFromIndex,
- tabId: currentTab,
- newProp: 'newPropFromReducer',
- });
- clearInterval(intervalId);
-
- tabs[currentTab].sliderIndex = newIndex;
- tabs[currentTab].playing = false;
- }
- break;
- }
- case types.MOVE_FORWARD: {
- if (sliderIndex < snapshots.length - 1) {
- const newIndex = sliderIndex + 1;
- // eslint-disable-next-line max-len
- // finds the name by the newIndex parsing through the hierarchy to send to background.js the current name in the jump action
- const nameFromIndex = findName(newIndex, hierarchy);
-
- port.postMessage({
- action: 'jumpToSnap',
- payload: snapshots[newIndex],
- index: newIndex,
- name: nameFromIndex,
- tabId: currentTab,
- });
-
- tabs[currentTab].sliderIndex = newIndex;
-
- // message is coming from the user
- if (!action.payload) {
- clearInterval(intervalId);
- tabs[currentTab].playing = false;
- }
- }
- break;
- }
- case types.SLIDER_ZERO: {
- // eslint-disable-next-line max-len
- // resets name to 0 to send to background.js the current name in the jump action
- port.postMessage({
- action: 'jumpToSnap',
- index: 0,
- name: 0,
- payload: snapshots[0],
- tabId: currentTab,
- });
- tabs[currentTab].sliderIndex = 0;
- break;
- }
- case types.CHANGE_VIEW: {
- // unselect view if same index was selected
- if (viewIndex === action.payload) tabs[currentTab].viewIndex = -1;
- else tabs[currentTab].viewIndex = action.payload;
- // update currLocation
- // tabs[currentTab].currLocation = tabs[currentTab].hierarchy;
- break;
- }
- case types.CHANGE_SLIDER: {
- // eslint-disable-next-line max-len
- // finds the name by the action.payload parsing through the hierarchy to send to background.js the current name in the jump action
- const nameFromIndex = findName(action.payload, hierarchy);
- // nameFromIndex is a number based on which jump button is pushed
-
- port.postMessage({
- action: 'jumpToSnap',
- payload: snapshots[action.payload],
- index: action.payload,
- name: nameFromIndex,
- tabId: currentTab,
- });
- tabs[currentTab].sliderIndex = action.payload;
- break;
- }
- case types.EMPTY: {
- // send msg to background script
- port.postMessage({ action: 'emptySnap', tabId: currentTab });
- tabs[currentTab].sliderIndex = 0;
- tabs[currentTab].viewIndex = 0;
- tabs[currentTab].playing = false;
- const lastSnapshot = tabs[currentTab].snapshots[tabs[currentTab].snapshots.length - 1];
- // resets hierarchy to page last state recorded
- tabs[currentTab].hierarchy.stateSnapshot = { ...lastSnapshot };
- // resets hierarchy
- tabs[currentTab].hierarchy.children = [];
- // resets snapshots to page last state recorded
- tabs[currentTab].snapshots = [lastSnapshot];
- // resets currLocation to page last state recorded
- tabs[currentTab].currLocation = tabs[currentTab].hierarchy;
- tabs[currentTab].index = 1;
- tabs[currentTab].currParent = 0;
- tabs[currentTab].currBranch = 1;
- tabs[currentTab].seriesSavedStatus = false;
- break;
- }
- case types.SET_PORT: {
- draft.port = action.payload;
- break;
- }
- case types.IMPORT: {
- port.postMessage({
- action: 'import',
- payload: action.payload,
- tabId: currentTab,
- });
- tabs[currentTab].snapshots = action.payload;
- break;
- }
- case types.TOGGLE_MODE: {
- mode[action.payload] = !mode[action.payload];
- const newMode = mode[action.payload];
- let actionText;
- switch (action.payload) {
- case 'paused':
- actionText = 'setPause';
- break;
- case 'persist':
- actionText = 'setPersist';
- break;
- default:
- break;
- }
- port.postMessage({
- action: actionText,
- payload: newMode,
- tabId: currentTab,
- });
- break;
- }
- case types.PAUSE: {
- clearInterval(intervalId);
- tabs[currentTab].playing = false;
- tabs[currentTab].intervalId = null;
- break;
- }
- case types.PLAY: {
- tabs[currentTab].playing = true;
- tabs[currentTab].intervalId = action.payload;
- break;
- }
- case types.INITIAL_CONNECT: {
- const { payload } = action;
- Object.keys(payload).forEach(tab => {
- // check if tab exists in memory
- // add new tab
- tabs[tab] = {
- ...payload[tab],
- sliderIndex: 0,
- viewIndex: -1,
- intervalId: null,
- playing: false,
- };
- });
-
- // only set first tab if current tab is non existent
- const firstTab = parseInt(Object.keys(payload)[0], 10);
- if (currentTab === undefined || currentTab === null) draft.currentTab = firstTab;
- break;
- }
- case types.NEW_SNAPSHOTS: {
- const { payload } = action;
- Object.keys(tabs).forEach(tab => {
- if (!payload[tab]) {
- delete tabs[tab];
- } else {
- // maintain isExpaned prop from old stateSnapshot to preserve componentMap expansion
- const persistIsExpanded = (newNode, oldNode) => {
- newNode.isExpanded = oldNode ? oldNode.isExpanded : true;
- if (newNode.children) {
- newNode.children.forEach((child, i) => {
- persistIsExpanded(child, oldNode?.children[i]);
- });
- }
- };
- persistIsExpanded(payload[tab].currLocation.stateSnapshot, tabs[tab].currLocation.stateSnapshot);
-
- const { snapshots: newSnaps } = payload[tab];
- tabs[tab] = {
- ...payload[tab],
- sliderIndex: newSnaps.length - 1,
- seriesSavedStatus: false,
- };
- }
- });
-
- // only set first tab if current tab is non existent
- const firstTab = parseInt(Object.keys(payload)[0], 10);
- if (currentTab === undefined || currentTab === null) draft.currentTab = firstTab;
- break;
- }
- case types.SET_TAB: {
- if (!mode?.paused) {
- if (typeof action.payload === 'number') {
- draft.currentTab = action.payload;
- break;
- } else if (typeof action.payload === 'object') {
- draft.currentTab = action.payload.tabId;
- if (action.payload?.title) draft.currentTitle = action.payload.title;
- break;
- }
- }
- break;
- }
- case types.DELETE_TAB: {
- delete draft.tabs[action.payload];
- break;
- }
- case types.LAUNCH_CONTENT: {
- // Fired when user clicks launch button on the error page. Send msg to background to launch
- port.postMessage({
- action: 'launchContentScript',
- payload: action.payload,
- tabId: currentTab,
- });
- break;
- }
- case types.NO_DEV: {
- const { payload } = action;
- if (tabs[currentTab]) {
- const { reactDevToolsInstalled } = payload[currentTab].status;
- tabs[currentTab].status.reactDevToolsInstalled = reactDevToolsInstalled;
- }
- break;
- }
- case types.TOGGLE_SPLIT: {
- draft.split = !draft.split;
- break;
- }
- case types.TOGGLE_EXPANDED: {
- // find correct node from currLocation and toggle isExpanded
- const checkChildren = node => {
- if (_.isEqual(node, action.payload)) {
- node.isExpanded = !node.isExpanded;
- return;
- }
- if (node.children) {
- node.children.forEach(child => {
- checkChildren(child);
- });
- }
- };
- checkChildren(tabs[currentTab].currLocation.stateSnapshot);
- break;
- }
- case types.SET_CURRENT_LOCATION: {
- const { payload } = action;
- const persistIsExpanded = (newNode, oldNode) => {
- newNode.isExpanded = oldNode ? oldNode.isExpanded : true;
- if (newNode.children) {
- newNode.children.forEach((child, i) => {
- persistIsExpanded(child, oldNode?.children[i]);
- });
- }
- };
- persistIsExpanded(payload[currentTab].currLocation.stateSnapshot, tabs[currentTab].currLocation.stateSnapshot);
- tabs[currentTab].currLocation = payload[currentTab].currLocation;
- break;
- }
- case types.SET_CURRENT_TAB_IN_APP: {
- draft.currentTabInApp = action.payload;
- break;
- }
- case types.TUTORIAL_SAVE_SERIES_TOGGLE: {
- tabs[currentTab] = { ...tabs[currentTab], seriesSavedStatus: action.payload };
- break;
- }
- default:
- throw new Error(`nonexistent action: ${action.type}`);
- }
-});
diff --git a/src/app/slices/mainSlice.ts b/src/app/slices/mainSlice.ts
new file mode 100644
index 000000000..740e9b718
--- /dev/null
+++ b/src/app/slices/mainSlice.ts
@@ -0,0 +1,447 @@
+import { createSlice } from '@reduxjs/toolkit';
+import { InitialState } from '../FrontendTypes';
+import _ from 'lodash';
+import Action from '../components/Actions/Action';
+
+const initialState: InitialState = {
+ // we initialize what our initialState is here
+ port: null,
+ currentTab: null,
+ currentTitle: 'No Target',
+ tabs: {},
+ currentTabInApp: null,
+ connectionStatus: true,
+ connectRequested: true,
+};
+
+const findName = (index: number, obj) => {
+ // eslint-disable-next-line eqeqeq
+ if (obj && obj.index == index) {
+ return obj.name;
+ }
+ const objChildArray = [];
+ if (obj) {
+ // eslint-disable-next-line no-restricted-syntax
+ for (const objChild of obj.children) {
+ objChildArray.push(findName(index, objChild));
+ }
+ }
+ // eslint-disable-next-line no-restricted-syntax
+ for (const objChildName of objChildArray) {
+ if (objChildName) {
+ return objChildName;
+ }
+ }
+};
+
+export const mainSlice = createSlice({
+ name: 'main',
+ initialState,
+ reducers: {
+ emptySnapshots: (state) => {
+ const { tabs, currentTab, port } = state;
+
+ port.postMessage({ action: 'emptySnap', tabId: currentTab }); //communicate with background.js (service worker)
+ // properties associated with timetravel + seek bar
+ tabs[currentTab].sliderIndex = 0;
+ tabs[currentTab].viewIndex = 0;
+ tabs[currentTab].playing = false;
+
+ const currSnapshot = tabs[currentTab].snapshots[tabs[currentTab].currLocation.index]; // current snapshot
+ const currAxSnapshot = tabs[currentTab].axSnapshots[tabs[currentTab].currLocation.index]; // current accessibility tree snapshot
+
+ tabs[currentTab].hierarchy.stateSnapshot = { ...currSnapshot }; // resets hierarchy to current snapshot
+ tabs[currentTab].hierarchy.axSnapshot = { ...currAxSnapshot }; // resets hierarchy to current accessibility tree snapshot
+ tabs[currentTab].hierarchy.children = []; // resets hierarchy
+ tabs[currentTab].snapshots = [currSnapshot]; // resets snapshots to current snapshot
+ tabs[currentTab].axSnapshots = [currAxSnapshot]; // resets snapshots to current snapshot
+
+ // resets currLocation to current snapshot
+ tabs[currentTab].index = 1;
+ tabs[currentTab].currParent = 0;
+ tabs[currentTab].currBranch = 1;
+ tabs[currentTab].currLocation = tabs[currentTab].hierarchy; // reset currLocation
+ tabs[currentTab].seriesSavedStatus = false;
+ },
+
+ addNewSnapshots: (state, action) => {
+ const { tabs, currentTab } = state;
+
+ const { payload } = action;
+ Object.keys(tabs).forEach((tab) => {
+ if (!payload[tab]) delete tabs[tab];
+ else {
+ // maintain isExpanded prop from old stateSnapshot to preserve componentMap expansion
+ const persistIsExpanded = (newNode, oldNode) => {
+ newNode.isExpanded = oldNode ? oldNode.isExpanded : true;
+ if (newNode.children) {
+ newNode.children.forEach((child, i) => {
+ persistIsExpanded(child, oldNode?.children[i]);
+ });
+ }
+ };
+ persistIsExpanded(
+ payload[tab].currLocation.stateSnapshot,
+ tabs[tab].currLocation.stateSnapshot,
+ );
+
+ const { snapshots: newSnaps } = payload[tab];
+ tabs[tab] = {
+ ...payload[tab],
+ intervalId: tabs[tab].intervalId,
+ playing: tabs[tab].playing,
+ sliderIndex: tabs[tab].sliderIndex,
+ seriesSavedStatus: false,
+ };
+ }
+ });
+
+ // only set first tab if current tab is non existent
+ const firstTab = parseInt(Object.keys(payload)[0], 10);
+ if (currentTab === undefined || currentTab === null) state.currentTab = firstTab;
+ },
+
+ initialConnect: (state, action) => {
+ const { tabs, tab, currentTab } = state;
+ const { hierarchy, snapshots, mode, intervalId, viewIndex, sliderIndex } =
+ tabs[currentTab] || {};
+ const { payload } = action;
+
+ Object.keys(payload).forEach((tab) => {
+ // check if tab exists in memory
+ // add new tab
+ tabs[tab] = {
+ ...payload[tab],
+ sliderIndex: 0,
+ viewIndex: -1,
+ intervalId: null,
+ playing: false,
+ };
+ });
+
+ // only set first tab if current tab is non existent
+ const firstTab = parseInt(Object.keys(payload)[0], 10);
+ if (currentTab === undefined || currentTab === null) state.currentTab = firstTab;
+ },
+
+ setPort: (state, action) => {
+ state.port = action.payload;
+ },
+
+ setTab: (state, action) => {
+ const { tabs, currentTab } = state;
+ const { mode } = tabs[currentTab] || {};
+ if (!mode?.paused) {
+ if (typeof action.payload === 'number') {
+ state.currentTab = action.payload;
+ return;
+ } else if (typeof action.payload === 'object') {
+ state.currentTab = action.payload.tabId;
+ if (action.payload?.title) state.currentTitle = action.payload.title;
+ return;
+ }
+ }
+ },
+
+ deleteTab: (state, action) => {
+ delete state.tabs[action.payload];
+ },
+
+ noDev: (state, action) => {
+ const { payload } = action;
+ const { tabs, currentTab } = state;
+
+ if (tabs[currentTab]) {
+ const { reactDevToolsInstalled } = payload[currentTab].status;
+ // JR 12.20. 9.47pm this was not applying to state before
+ state.tabs[currentTab].status.reactDevToolsInstalled = reactDevToolsInstalled;
+ }
+ },
+
+ aReactApp: (state, action) => {
+ const { payload } = action;
+ const { tabs, currentTab } = state;
+
+ if (tabs[currentTab]) {
+ // JR 12.20. 9.47pm this was not applying to state before
+ state.tabs[currentTab].status.targetPageisaReactApp = true;
+ }
+ },
+
+ setCurrentLocation: (state, action) => {
+ const { tabs, currentTab } = state;
+ const { payload } = action;
+
+ const persistIsExpanded = (newNode, oldNode) => {
+ newNode.isExpanded = oldNode ? oldNode.isExpanded : true;
+ if (newNode.children) {
+ newNode.children.forEach((child, i) => {
+ persistIsExpanded(child, oldNode?.children[i]);
+ });
+ }
+ };
+ persistIsExpanded(
+ payload[currentTab].currLocation.stateSnapshot,
+ tabs[currentTab].currLocation.stateSnapshot,
+ );
+ tabs[currentTab].currLocation = payload[currentTab].currLocation;
+ },
+
+ changeView: (state, action) => {
+ const { tabs, currentTab } = state;
+ const { viewIndex } = tabs[currentTab] || {};
+
+ // unselect view if same index was selected
+ tabs[currentTab].viewIndex = viewIndex === action.payload ? -1 : action.payload;
+ },
+
+ changeSlider: (state, action) => {
+ //should really be called jump to snapshot
+ const { port, currentTab, tabs } = state;
+ const { hierarchy, snapshots } = tabs[currentTab] || {};
+
+ // finds the name by the action.payload parsing through the hierarchy to send to background.js the current name in the jump action
+ const nameFromIndex = findName(action.payload, hierarchy);
+ // nameFromIndex is a number based on which jump button is pushed
+
+ port.postMessage({
+ action: 'jumpToSnap',
+ payload: snapshots[action.payload],
+ index: action.payload,
+ name: nameFromIndex,
+ tabId: currentTab,
+ });
+
+ tabs[currentTab].sliderIndex = action.payload;
+ },
+
+ setCurrentTabInApp: (state, action) => {
+ state.currentTabInApp = action.payload;
+ },
+
+ pause: (state) => {
+ const { tabs, currentTab } = state;
+ const { intervalId } = tabs[currentTab] || {};
+
+ clearInterval(intervalId);
+ tabs[currentTab].playing = false;
+ tabs[currentTab].intervalId = null;
+ },
+
+ launchContentScript: (state, action) => {
+ const { tabs, currentTab, port } = state;
+
+ // Fired when user clicks launch button on the error page. Send msg to background to launch
+ port.postMessage({
+ action: 'launchContentScript',
+ payload: action.payload,
+ tabId: currentTab,
+ });
+ },
+
+ playForward: (state, action) => {
+ const { port, tabs, currentTab } = state;
+ const { hierarchy, snapshots, sliderIndex, intervalId } = tabs[currentTab] || {};
+
+ if (sliderIndex < snapshots.length - 1) {
+ const newIndex = sliderIndex + 1;
+ // eslint-disable-next-line max-len
+ // finds the name by the newIndex parsing through the hierarchy to send to background.js the current name in the jump action
+ const nameFromIndex = findName(newIndex, hierarchy);
+
+ port.postMessage({
+ action: 'jumpToSnap',
+ payload: snapshots[newIndex],
+ index: newIndex,
+ name: nameFromIndex,
+ tabId: currentTab,
+ });
+
+ tabs[currentTab].sliderIndex = newIndex;
+
+ // message is coming from the user
+ if (!action.payload) {
+ clearInterval(intervalId);
+ tabs[currentTab].playing = false;
+ }
+ }
+ },
+
+ startPlaying: (state, action) => {
+ const { tabs, currentTab } = state;
+
+ tabs[currentTab].playing = true;
+ tabs[currentTab].intervalId = action.payload;
+ },
+
+ resetSlider: (state) => {
+ const { port, tabs, currentTab } = state;
+ const { snapshots, sliderIndex } = tabs[currentTab] || {};
+
+ // eslint-disable-next-line max-len
+ // resets name to 0 to send to background.js the current name in the jump action
+ port.postMessage({
+ action: 'jumpToSnap',
+ index: 0,
+ name: 0,
+ payload: snapshots[0],
+ tabId: currentTab,
+ });
+ tabs[currentTab].sliderIndex = 0;
+ },
+
+ toggleMode: (state, action) => {
+ const { port, tabs, currentTab } = state;
+ const { mode } = tabs[currentTab] || {};
+ mode[action.payload] = !mode[action.payload];
+ const newMode = mode[action.payload];
+ let actionText;
+ switch (action.payload) {
+ case 'paused':
+ actionText = 'setPause';
+ break;
+ default:
+ break;
+ }
+ port.postMessage({
+ action: actionText,
+ payload: newMode,
+ tabId: currentTab,
+ });
+ },
+
+ importSnapshots: (state, action) => {
+ const { port, tabs, currentTab } = state;
+
+ // Log the value of tabs[currentTab].snapshots before the update
+ port.postMessage({
+ action: 'import',
+ payload: action.payload,
+ tabId: currentTab,
+ });
+
+ const savedSnapshot = action.payload;
+
+ tabs[currentTab].sliderIndex = savedSnapshot.sliderIndex;
+ tabs[currentTab].viewIndex = savedSnapshot.viewIndex;
+ tabs[currentTab].playing = false;
+
+ // resets hierarchy to page last state recorded
+ tabs[currentTab].hierarchy.stateSnapshot = savedSnapshot.hierarchy.stateSnapshot;
+
+ // resets hierarchy
+ tabs[currentTab].hierarchy.children = savedSnapshot.hierarchy.children;
+
+ // resets snapshots to page last state recorded
+ tabs[currentTab].snapshots = savedSnapshot.snapshots;
+
+ // resets currLocation to page last state recorded
+ tabs[currentTab].currLocation = tabs[currentTab].hierarchy;
+ tabs[currentTab].index = savedSnapshot.index;
+ tabs[currentTab].currParent = savedSnapshot.currParent;
+ tabs[currentTab].currBranch = savedSnapshot.Branch;
+ tabs[currentTab].seriesSavedStatus = false;
+ },
+
+ tutorialSaveSeriesToggle: (state, action) => {
+ const { tabs, currentTab } = state;
+ tabs[currentTab] = { ...tabs[currentTab], seriesSavedStatus: action.payload }; // sets the tab[currentTab]'s 'seriesSavedStatus' property to the payload.
+ },
+
+ onHover: (state, action) => {
+ const { currentTab, port } = state;
+
+ port.postMessage({
+ action: 'onHover',
+ payload: action.payload,
+ tabId: currentTab,
+ });
+ },
+
+ onHoverExit: (state, action) => {
+ const { currentTab, port } = state;
+
+ port.postMessage({
+ action: 'onHoverExit',
+ payload: action.payload,
+ tabId: currentTab,
+ });
+ },
+
+ toggleExpanded: (state, action) => {
+ const { tabs, currentTab } = state;
+ const snapshot = tabs[currentTab].currLocation.stateSnapshot;
+
+ // Special case for root node
+ if (action.payload.name === 'root' && snapshot.name === 'root') {
+ snapshot.isExpanded = !snapshot.isExpanded;
+ return;
+ }
+
+ // Regular case for other nodes
+ const checkChildren = (node) => {
+ if (_.isEqual(node, action.payload)) {
+ node.isExpanded = !node.isExpanded;
+ } else if (node.children) {
+ node.children.forEach((child) => {
+ checkChildren(child);
+ });
+ }
+ };
+ checkChildren(snapshot);
+ },
+
+ disconnected: (state) => {
+ state.connectionStatus = false;
+ },
+
+ startReconnect: (state) => {
+ state.connectRequested = true;
+ state.port = initialState.port;
+ },
+
+ endConnect: (state) => {
+ state.connectRequested = false;
+ state.connectionStatus = true;
+ },
+
+ toggleAxTree: (state, action) => {
+ const { port, payload, tabs, currentTab } = state;
+ port.postMessage({
+ action: 'toggleAxRecord',
+ payload: action.payload,
+ tabId: currentTab,
+ });
+ },
+ },
+});
+
+export const {
+ emptySnapshots,
+ addNewSnapshots,
+ initialConnect,
+ setPort,
+ setTab,
+ deleteTab,
+ noDev,
+ aReactApp,
+ setCurrentLocation,
+ changeView,
+ changeSlider,
+ setCurrentTabInApp,
+ pause,
+ launchContentScript,
+ playForward,
+ startPlaying,
+ resetSlider,
+ toggleMode,
+ importSnapshots,
+ tutorialSaveSeriesToggle,
+ onHover,
+ onHoverExit,
+ toggleExpanded,
+ disconnected,
+ startReconnect,
+ endConnect,
+ toggleAxTree,
+} = mainSlice.actions;
diff --git a/src/app/store.ts b/src/app/store.ts
new file mode 100644
index 000000000..9ed9da56e
--- /dev/null
+++ b/src/app/store.ts
@@ -0,0 +1,13 @@
+//Import store from redux tool kit
+import { configureStore } from '@reduxjs/toolkit';
+import { mainSlice } from './slices/mainSlice';
+
+//Export Store
+export const store = configureStore({
+ reducer: {
+ main: mainSlice.reducer,
+ },
+ middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }),
+});
+
+export type RootState = ReturnType
\ No newline at end of file
diff --git a/src/app/store.tsx b/src/app/store.tsx
deleted file mode 100644
index 0241cca82..000000000
--- a/src/app/store.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import React, { useContext } from 'react';
-
-export const StoreContext = React.createContext();
-
-export const useStoreContext:any = () => useContext(StoreContext);
diff --git a/src/app/styles/abstracts/_variables.scss b/src/app/styles/abstracts/_variables.scss
deleted file mode 100644
index 543032fd3..000000000
--- a/src/app/styles/abstracts/_variables.scss
+++ /dev/null
@@ -1,61 +0,0 @@
-/// fontFamily: 'monaco, Consolas, Lucida Console, monospace'
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
-/// @type List
-$text-font-stack: 'Roboto', sans-serif !default;
-
-/// @type Color
-$fiery-rose: #ff6569;
-$blue-brand: #62d6fb;
-
-/// @type Color
-$blue-color-gradient: linear-gradient(145deg, #69e5ff, #58c1e2);
-$red-color-gradient: linear-gradient(145deg, #ff6569, #e65558);
-$grey-color-gradient: linear-gradient(145deg, #5c6068, #4d5157);
-
-/// @type Color:
-$box-shadow-blue: inset 5px 5px 10px #53b6d5, inset -5px -5px 10px #71f6ff;
-$box-shadow-red: inset 5px 5px 10px #d95053, inset -5px -5px 10px #ff6c71;
-
-/// @type Color
-$text-color: #e7e7e7;
-
-/// @type Color
-$brand-color: #242529 !default;
-
-/// @type Color
-$background-color: #333333 !default;
-$medium-background-color: #51565e !default;
-$light-background-color: #585d65 !default;
-
-/// Light grey
-/// @type Color
-$light-grey-one: #474c55 !default;
-
-/// @type Color
-$light-grey-two: #5f6369 !default;
-
-$light-grey-three: #65686e !default;
-
-$light-grey-four: #4c4c4d !default;
-
-/// @type Color
-$navbar-color: #44484e !default;
-
-/// @type Color
-$head-color: #242529 !default;
-
-/// @type Color
-$border-color: #292929 !default;
-
-/// @type Color
-$border-slider: #57c5f7 !default;
-
-/// @type Color
-$border-rc: #373737 !default;
-$background-rc-color: #e9e9e9 !default;
-
-/// @type Color
-$highlight-color: rgba(224, 224, 224, 0.5) !default;
-
-/// @type Font Size
-$button-text-size: 12px;
diff --git a/src/app/styles/base/_base.scss b/src/app/styles/base/_base.scss
deleted file mode 100644
index 4aa7f3611..000000000
--- a/src/app/styles/base/_base.scss
+++ /dev/null
@@ -1,45 +0,0 @@
-html {
- margin: 0;
- padding: 0;
- height: 100%;
-}
-
-body {
- margin: 0;
- height: 100%;
-}
-
-#root {
- height: 100%;
-}
-
-.travel-container {
- grid-area: travel;
-}
-.action-container {
- grid-area: actions;
- transition: 0.5s;
-}
-.state-container-container {
- grid-area: states;
-}
-.split {
- grid-area: states;
-}
-.buttons-container {
- grid-area: buttons;
- border-color: rgba(41, 41, 41, 1);
-}
-
-.action-container,
-.state-container,
-.travel-container {
- border-style: solid;
- border-color: $border-color;
- border-width: 1px;
-}
-
-.saveSeriesContainer {
- padding-bottom: 15px;
- padding-top: 10px;
-}
\ No newline at end of file
diff --git a/src/app/styles/base/_typography.scss b/src/app/styles/base/_typography.scss
deleted file mode 100644
index 2d3a51326..000000000
--- a/src/app/styles/base/_typography.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-body {
- color: $text-color;
- font: normal 13px $text-font-stack;
-}
diff --git a/src/app/styles/components/_actionComponent.scss b/src/app/styles/components/_actionComponent.scss
index 4a16971bf..4cdf0ceaa 100644
--- a/src/app/styles/components/_actionComponent.scss
+++ b/src/app/styles/components/_actionComponent.scss
@@ -1,44 +1,128 @@
+.route-container {
+ width: 100%;
+}
+
+.route-header {
+ background-color: var(--button-primary-bg);
+ color: var(--button-primary-text);
+ padding: 10px;
+ font-size: 14px;
+}
+
+.route-content {
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 50px;
+}
+
+/* Container for individual action */
+.individual-action {
+ margin: 0;
+ padding: 0;
+}
+
.action-component {
- padding: 5px 10px;
- display: grid;
- grid-template-columns: none;
- align-items: center;
- height: 20px;
- // background-color: $brand-color;
- border-bottom-style: solid;
- border-bottom-width: 1px;
- background-color: none;
- border-color: #292929;
- // border-color: $border-color;
- cursor: pointer;
- overflow: hidden;
- @extend %disable-highlight;
+ display: flex;
+ padding: 6px 16px;
+ background: var(--bg-primary);
+ border-bottom: 1px solid var(--border-color);
+ transition: background-color 200ms ease;
}
-.action-component-text {
- margin-bottom: 8px;
+.action-component:hover {
+ background-color: var(--hover-bg);
}
.action-component.selected {
- background-color: $light-grey-one;
+ background-color: var(--selected-bg);
}
-.action-component.exclude {
+.action-component-trigger {
+ width: 100%;
display: flex;
- justify-content: center;
- margin-top: 10px;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.action-component-text {
+ flex: 1;
+}
+
+/* Input styling */
+.actionname {
+ border: none;
+ background: transparent;
+ font-size: 1rem;
+ color: var(--text-primary);
+ width: 100%;
+ padding: 2px 0;
+}
+
+.actionname::placeholder {
+ color: var(--text-secondary);
}
-.action-component:focus {
+.actionname:focus {
outline: none;
}
-.action-component-trigger {
- display: grid;
- grid-template-columns: 4fr 1fr;
+/* Button styling */
+.time-button,
+.jump-button,
+.current-location {
+ min-width: 90px;
+ height: 28px;
+ padding: 0 8px;
+ border-radius: 6px;
+ font-size: 0.9375rem;
+ font-weight: 500;
+ display: flex;
align-items: center;
- height: 20px;
+ justify-content: center;
+ border: none;
+ transition: all 200ms ease;
+ margin: 0;
+}
+
+.time-button {
+ color: var(--text-secondary);
+ background: transparent;
+}
+
+.jump-button {
+ color: var(--button-primary-text);
+ background: var(--button-primary-bg);
+ display: none;
+ transition: all 200ms ease;
+}
+
+.jump-button:hover {
+ background: var(--text-primary);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
cursor: pointer;
- overflow: hidden;
- @extend %disable-highlight;
+}
+
+.current-location {
+ color: var(--color-primary);
+ background: var(--bg-tertiary);
+ border: 1px solid var(--color-primary);
+}
+
+/* Hide/show button transitions */
+.action-component:hover .time-button {
+ display: none;
+}
+
+.action-component:hover .jump-button {
+ display: block;
+}
+
+.current-snap {
+ font-weight: 700;
+ border: none;
+ background: transparent;
+ font-size: 1rem;
+ color: var(--text-primary);
+ width: 100%;
+ padding: 2px 0px;
}
diff --git a/src/app/styles/components/_ax.scss b/src/app/styles/components/_ax.scss
new file mode 100644
index 000000000..db9b06c4b
--- /dev/null
+++ b/src/app/styles/components/_ax.scss
@@ -0,0 +1,80 @@
+/* Container for the radio controls */
+.accessibility-controls {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ padding: 12px 24px;
+}
+
+/* Hide the default radio inputs */
+.accessibility-controls input[type='radio'] {
+ display: none;
+}
+
+/* Style the labels as buttons */
+.accessibility-controls label {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 60px;
+ padding: 8px 16px;
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--bg-primary);
+ background-color: var(--color-primary);
+ border-radius: 6px;
+ cursor: pointer;
+ transition: all 200ms ease;
+ user-select: none;
+}
+
+.accessibility-controls label:hover {
+ background-color: var(--color-primary-dark);
+}
+
+.accessibility-disable input[type='radio'] {
+ display: none;
+}
+
+.accessibility-disable label {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 60px;
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: 500;
+ background-color: var(--bg-secondary);
+ border: 1px solid var(--border-color);
+ color: var(--text-primary);
+ border-radius: 6px;
+ cursor: pointer;
+ transition: all 200ms ease;
+ user-select: none;
+}
+
+.accessibility-disable label:hover {
+ border-color: var(--border-color-dark);
+ background-color: var(--bg-tertiary);
+}
+
+.accessibility-text {
+ padding: 12px 24px;
+ max-width: 800px;
+ line-height: 1.5;
+}
+
+.accessibility-text p {
+ margin: 0;
+ color: var(--text-primary);
+ font-size: 16px;
+}
+
+.tooltipData-JSONTree {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ padding: 8px 12px;
+ border-bottom: 1px solid var(--border-color);
+ background-color: var(--bg-primary);
+}
diff --git a/src/app/styles/components/_buttons.scss b/src/app/styles/components/_buttons.scss
index ae9deb8eb..aea1c6560 100644
--- a/src/app/styles/components/_buttons.scss
+++ b/src/app/styles/components/_buttons.scss
@@ -1,394 +1,181 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
-
-.save-series-button {
- padding: 3px;
- outline: transparent;
- color: white;
+.play-button {
display: flex;
- justify-content: center;
align-items: center;
- border-style: solid;
- border-color: transparent;
- border-radius: 5px;
- cursor: pointer;
- line-height: 1.5em;
- font: 400 14px 'Roboto', sans-serif;
- // font-size: $button-text-size;
- width: 120px;
- background: $red-color-gradient;
- height: 30px;
- position: absolute;
- right: 3rem;
-
- &.animate {
- background: rgb(41, 164, 41);
- }
-}
-
-.delete-button {
- padding: 3px;
- outline: transparent;
- color: white;
- display: flex;
justify-content: center;
- align-items: center;
- border-style: solid;
- border-color: transparent;
- border-radius: 3px;
- cursor: pointer;
- line-height: 1.5em;
- font: 300 14px 'Roboto', sans-serif;
- font-size: $button-text-size;
- width: 120px;
- background: $red-color-gradient;
- height: 30px;
-
- &.animate {
- background: rgb(41, 164, 41);
- }
-}
-
-.empty-button {
- padding: 3px;
- outline: transparent;
- color: black;
- display: flex;
- justify-content: center;
- align-items: center;
- border-style: solid;
- border-color: transparent;
- border-radius: 3px;
- cursor: pointer;
- line-height: 1.5em;
- font: 300 14px 'Roboto', sans-serif;
- font-size: $button-text-size;
- width: 120px;
- background: #62d6fb;
-}
-
-.empty-button:hover {
- color: black;
- box-shadow: $box-shadow-red;
-}
-
-.state-dropdown {
- width: 240px;
- margin-left: 20px;
-}
-
-.action-component:hover .time-button {
- display: none;
-}
-
-.action-component:hover .jump-button {
- opacity: 1;
- transform: rotateX(0deg);
- transition: opacity 300ms, transform 0.15s linear;
-}
-
-.time-button {
- outline: none;
- height: 20px;
- margin-bottom: 8px;
- width: 70px;
- border: none;
- border-radius: 3px;
- background: $grey-color-gradient;
- font: normal 11px 'Roboto', sans-serif;
- color: #b0b0b0;
-}
-
-.jump-button {
- outline: none;
- height: 20px;
- margin-bottom: 8px;
- width: 70px;
- border: transparent;
- border-radius: 3px;
- background-color: #565a61;
- font: normal 11px 'Roboto', sans-serif;
- color: #b0b0b0;
- transform: rotateX(90deg);
- transition: opacity 300ms, transform 0.15s linear;
- opacity: 0;
-}
-
-.jump-button:hover {
- // remove the blue border when button is clicked
- color: white;
- background-color: $fiery-rose;
- cursor: pointer;
-}
-
-.current-location {
- outline: none;
- height: 20px;
- margin-bottom: 8px;
- width: 70px;
- border: transparent;
- border-radius: 3px;
- font: normal 11px 'Roboto', sans-serif;
-}
-
-.empty-button:hover {
- color: white;
- background-color: $highlight-color;
-}
-
-.play-button {
+ gap: 8px;
width: 100px;
- height: 25px;
- margin: 0 1% 0 2%;
- color: $brand-color;
- border-color: transparent;
- background: $blue-color-gradient;
- border-radius: 5px;
-}
-
-.play-button:hover {
- background: $blue-color-gradient;
- transform: translate3d(0, -3px, 0);
- cursor: pointer;
-}
-
-.backward-button {
- width: 30px;
- height: 25px;
- margin: 7px;
- color: $brand-color;
- border-color: transparent;
- background: $blue-color-gradient;
- border-radius: 5px;
-}
-
-.forward-button {
- width: 30px;
- height: 25px;
- margin: 7px;
- color: $brand-color;
- border-color: transparent;
- background: $blue-color-gradient;
- border-radius: 5px;
-}
-
-.play-button:focus,
-.backward-button:focus,
-.forward-button:focus {
- outline: none;
- box-shadow: $box-shadow-blue;
-}
-
-.forward-button:hover,
-.backward-button:hover {
- background: $blue-color-gradient;
- transform: translate3d(0, -3px, 0);
- cursor: pointer;
-}
-
-.import-button,
-.howToUse-button,
-.export-button,
-.pause-button,
-.split-button {
- @extend %button-shared;
- color: white;
- border-color: transparent;
- background: $blue-color-gradient;
-}
-
-.import-button:hover,
-.howToUse-button:hover,
-.export-button:hover,
-.pause-button:hover,
-.split-button:hover {
- @extend %button-shared;
- color: #62d6fb;
- box-shadow: 1px 1px 2px 1px rgba(30, 86, 171, 0.25);
- transform: translate3d(0, -3px, 0);
-}
-
-.svg-inline--fa {
- color: $blue-brand;
- margin-right: 0.75em;
- display: inline-block;
- font-size: inherit;
- height: 0.75em;
- overflow: visible;
- vertical-align: -0.125em;
-}
-
-%button-shared {
- padding: 5px;
- outline: none;
- display: flex;
- justify-content: center;
- align-items: center;
+ height: 40px;
+ padding: 8px 12x;
+ border-radius: 8px;
+ border: none;
+ background-color: var(--button-primary-bg);
+ color: var(--button-primary-text);
+ font-size: 14px;
+ font-weight: 500;
cursor: pointer;
- line-height: 1.5em;
- font: 300 14px 'Roboto', sans-serif;
- font-size: $button-text-size;
-
- background: $brand-color;
- border-radius: 5px;
+ transition: all 200ms ease;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
position: relative;
- border: 1px solid #b8c4c240;
+ overflow: hidden;
- @extend %disable-highlight;
-}
-
-// Save button
-.dropdown-dark {
- background: #444;
- border-color: #111111 #0a0a0a black;
- background-image: -webkit-linear-gradient(
- top,
- transparent,
- rgba(0, 0, 0, 0.4)
- );
- background-image: -moz-linear-gradient(top, transparent, rgba(0, 0, 0, 0.4));
- background-image: -o-linear-gradient(top, transparent, rgba(0, 0, 0, 0.4));
- background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.4));
- -webkit-box-shadow: inset 0 1px rgba(255, 255, 255, 0.1),
- 0 1px 1px rgba(0, 0, 0, 0.2);
- box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px 1px rgba(0, 0, 0, 0.2);
-}
-
-.dropdown-dark:before {
- border-bottom-color: #aaa;
-}
-
-.dropdown-dark:after {
- border-top-color: #aaa;
-}
+ &:hover {
+ background-color: var(--text-primary);
+ }
-.dropdown-dark .dropdown-select {
- color: #aaa;
- text-shadow: 0 1px black;
- background: #444;
- /* Fallback for IE 8 */
-}
+ &:focus {
+ outline: none;
+ box-shadow:
+ 0 0 0 2px white,
+ 0 0 0 4px #1f2937;
+ }
-.dropdown-dark .dropdown-select:focus {
- color: #ccc;
-}
+ &-content {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ position: relative;
+ z-index: 1;
+ }
-.dropdown-dark .dropdown-select > option {
- background: #444;
- text-shadow: 0 1px rgba(0, 0, 0, 0.4);
-}
+ &::after {
+ content: '';
+ position: absolute;
+ width: 5px;
+ height: 5px;
+ background: rgba(255, 255, 255, 0.5);
+ opacity: 1;
+ border-radius: 50%;
+ transform: scale(1);
+ animation: ripple 600ms linear;
+ display: none;
+ }
-.MuiSelect-icon {
- color: lightgrey !important;
+ &:active::after {
+ display: block;
+ }
}
-.series-options-container {
+.record-button-container {
display: flex;
- justify-content: space-between;
align-items: center;
- margin: 0 1rem;
-}
-
-.snapshotId-header {
- font-size: 1rem;
+ padding: 4px 16px;
+ background: transparent;
+ justify-content: space-between;
}
-.dropdown-and-delete-series-container {
+.record-controls {
display: flex;
align-items: center;
}
-.close-button-container {
+.record-label {
display: flex;
- justify-content: flex-end;
+ align-items: center;
+ gap: 8px;
+ color: var(--text-primary);
+ font-size: 14px;
+ font-weight: 500;
}
-.closebtn {
- font-size: 20px;
- color: #818181;
- background-color: transparent;
- border: none;
- box-shadow: none;
+.record-icon {
+ width: 10px;
+ height: 10px;
+ background-color: #ef4444;
+ border-radius: 50%;
+ transition: opacity 0.3s ease;
}
-.closebtn:hover {
- color: #f1f1f1;
+.record-icon.recording {
+ animation: pulse 2s infinite;
}
-.side-bar-button {
- width: 80px;
- height: 30px;
- padding: 0 2rem;
+@keyframes pulse {
+ 0% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.5;
+ }
+ 100% {
+ opacity: 1;
+ }
}
-/* sidebar button open and closing functionality */
-aside {
- // width: 250px;
- background: #242529;
- color: #fff;
- transition: width 1s;
+.clear-button-modern {
+ width: 100% !important;
+ background-color: var(--bg-tertiary) !important;
+ color: var(--text-primary) !important;
+ font-size: 0.875rem !important;
+ font-weight: 500 !important;
+ text-transform: uppercase !important;
+ padding: 0.375rem 1rem !important;
+ border-radius: 0.375rem !important;
+ transition: background-color 200ms ease-in-out !important;
}
-.no-aside {
- width: 30px;
- margin-right: 15px;
+.clear-button-modern:hover {
+ background-color: var(--border-color) !important;
}
-.toggle {
- // width: 40px;
- // height: 10px;
- display: block;
+/* Theme toggle button styling */
+.theme-toggle {
position: relative;
- margin-top: 1rem;
-}
-
-/* toggle i handles arrow animation */
-.toggle i,
-.toggle i::after,
-.toggle i::before {
- position: absolute;
- width: 27px;
- height: 4px;
- border-radius: 4px;
- transition: transform 0.15s;
- background-color: $blue-brand;
-}
-
-.toggle i {
- top: 8px;
- left: 9px;
- display: block;
- background: $blue-brand;
+ width: 48px;
+ height: 24px;
+ border-radius: 16px;
+ border: 2px solid var(--border-color);
+ background-color: var(--bg-tertiary);
+ cursor: pointer;
+ transition: all 300ms ease;
+ padding: 2px;
}
-.toggle i::before {
- top: -5px;
+.theme-toggle.dark {
+ background-color: var(--bg-primary);
+ border-color: var(--border-color-dark);
}
-.toggle i::after {
- bottom: -6px;
+.theme-toggle-slider {
+ position: relative;
+ width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ background-color: var(--bg-primary);
+ transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
-.toggle i::after,
-.toggle i::before {
- content: '';
- display: block;
+.theme-toggle.dark .theme-toggle-slider {
+ transform: translateX(24px);
+ background-color: var(--color-primary);
}
-.toggle i::before {
- transform: translate3d(-8px, 0, 0) rotate(-45deg) scale(0.7, 1);
+.theme-toggle-icons {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 4px;
+ pointer-events: none;
}
-.toggle i::after {
- transform: translate3d(-8px, 0, 0) rotate(45deg) scale(0.7, 1);
+.theme-toggle-icon {
+ width: 14px;
+ height: 14px;
+ transition: color 300ms ease;
}
-.no-aside .toggle i::before,
-.no-aside .toggle i::after {
- transform: none;
+.theme-toggle.dark .theme-toggle-icon.moon {
+ color: var(--color-primary);
}
-#arrow {
- margin-bottom: 40px;
+.theme-toggle .theme-toggle-icon.sun {
+ color: var(--color-primary);
}
-
-/* ^ sidebar button open and closing functionality */
diff --git a/src/app/styles/components/_componentMap.scss b/src/app/styles/components/_componentMap.scss
new file mode 100644
index 000000000..7167fee01
--- /dev/null
+++ b/src/app/styles/components/_componentMap.scss
@@ -0,0 +1,148 @@
+/* Component Map Container */
+.componentMapContainer {
+ fill: var(--bg-secondary);
+ transition: all 0.3s ease;
+ overflow: auto;
+}
+.componentMapContainer svg {
+ background-color: var(--bg-secondary);
+}
+
+#root {
+ height: 100%;
+}
+
+/* Node Styling */
+.compMapParent,
+.compMapChild {
+ fill: var(--bg-primary);
+ stroke: var(--border-color);
+ filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.05));
+ transition: all 0.2s ease;
+}
+
+.compMapParent:hover,
+.compMapChild:hover {
+ stroke: var(--color-primary);
+ stroke-width: 2px;
+ cursor: pointer;
+ filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.1));
+}
+
+/* Root Node Styling */
+.compMapRoot {
+ fill: var(--color-primary);
+ stroke: var(--color-primary-dark);
+ filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
+ transition: all 0.2s ease;
+}
+
+.compMapRoot:hover {
+ filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.15));
+ cursor: pointer;
+ transform: scale(1.05);
+}
+
+/* Text Styling */
+.compMapRootText {
+ fill: var(--bg-primary);
+ font-weight: 500;
+ user-select: none;
+}
+
+.compMapParentText,
+.compMapChildText {
+ fill: var(--text-primary);
+ font-weight: 500;
+ user-select: none;
+}
+
+/* Link Styling */
+.compMapLink {
+ stroke-linecap: round;
+ transition: all 0.3s ease;
+}
+
+.compMapLink:hover {
+ stroke-width: 2;
+ filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
+}
+
+.link-controls {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ padding: 12px 16px;
+ background: var(--bg-primary);
+ border-bottom: 1px solid var(--border-color);
+ justify-content: space-between;
+ max-width: 1200px;
+}
+
+.control-group {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.control-label {
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--text-secondary);
+ user-select: none;
+}
+
+.control-select {
+ background-color: var(--bg-secondary);
+ border: 1px solid var(--border-color);
+ color: var(--text-primary);
+ font-size: 14px;
+ padding: 6px 12px;
+ border-radius: 6px;
+ min-width: 100px;
+ cursor: pointer;
+ transition: all 200ms ease;
+ appearance: none;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%236b7280'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: right 8px center;
+ background-size: 16px;
+}
+
+.control-select:hover {
+ border-color: var(--border-color-dark);
+ background-color: var(--bg-tertiary);
+}
+
+.control-select:focus {
+ outline: none;
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 2px rgba(20, 184, 166, 0.1);
+}
+
+.control-range {
+ appearance: none;
+ width: 120px;
+ height: 4px;
+ border-radius: 2px;
+ background: var(--border-color);
+ outline: none;
+ margin: 0;
+ cursor: pointer;
+
+ &::-webkit-slider-thumb {
+ appearance: none;
+ width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ background: var(--color-primary);
+ cursor: pointer;
+ transition: all 200ms ease;
+ border: none;
+
+ &:hover {
+ background: var(--color-primary-dark);
+ transform: scale(1.1);
+ }
+ }
+}
diff --git a/src/app/styles/components/_jsonTree.scss b/src/app/styles/components/_jsonTree.scss
deleted file mode 100644
index 9150fe089..000000000
--- a/src/app/styles/components/_jsonTree.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.json-tree {
- font-size: 13px;
- overflow: auto;
- margin: 10px;
- padding: 0;
- width: 900px;
- background-color: $brand-color;
- list-style: none;
-}
diff --git a/src/app/styles/components/_performanceVisx.scss b/src/app/styles/components/_performanceVisx.scss
index 2e6f0c71a..7442dd944 100644
--- a/src/app/styles/components/_performanceVisx.scss
+++ b/src/app/styles/components/_performanceVisx.scss
@@ -1,63 +1,75 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
-
-#RenderContainer {
+.saveSeriesContainer {
display: flex;
- justify-content: center;
-}
-
-.MuiSwitch-colorPrimary.Mui-checked {
- color: #62d6fb !important;
+ align-items: center;
+ padding: 12px 16px;
+ background-color: var(--bg-primary);
+ max-width: 1200px;
+ justify-content: space-around;
+ border-bottom: 1px solid var(--border-color);
}
-.MuiSwitch-switchBase {
- color: #ff6569 !important;
+.routesForm {
+ display: flex;
+ align-items: center;
+ gap: 10px;
}
-.MuiSwitch-track {
- background-color: #e7e7e7 !important;
+#routes-dropdown {
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--text-secondary);
+ user-select: none;
+ white-space: nowrap;
}
-.MuiTypography-body1 {
- font-size: 2em !important;
+.performance-dropdown,
+#routes-select,
+#snapshot-select,
+.control-select {
+ background-color: var(--bg-secondary);
+ border: 1px solid var(--border-color);
+ color: var(--text-primary);
+ font-size: 14px;
+ padding: 6px 12px;
+ border-radius: 6px;
+ min-width: 140px;
+ cursor: pointer;
+ transition: all 200ms ease;
+ appearance: none;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%236b7280'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: right 8px center;
+ background-size: 16px;
}
-#routes-formcontrol {
- padding: 3px;
- margin-left: 50px;
- font: 400 14px 'Roboto', sans-serif;
- text-align: left;
- // min-width: 10em;
- // max-height: 50%;
+.performance-dropdown:hover,
+#routes-select:hover,
+#snapshot-select:hover,
+.control-select:hover {
+ border-color: var(--border-color-dark);
+ background-color: var(--bg-tertiary);
}
-#routes-dropdown {
- color: white !important;
- // background-color: #ff6569 !important;
- font: 400 14px 'Roboto', sans-serif;
- text-align: left;
+.performance-dropdown:focus,
+#routes-select:focus,
+#snapshot-select:focus,
+.control-select:focus {
+ outline: none;
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 2px rgba(20, 184, 166, 0.1);
}
-#routes-select, #snapshot-select{
- color: white !important;
- background-color: #ff6569 !important;
- font: 400 14px 'Roboto', sans-serif;
- text-align: left;
- width: 120px;
- height: 30px;
- border-radius: 5px;
- text-align: center;
+.routes,
+.control-select option {
+ padding: 0.5rem;
+ color: var(--text-primary);
}
-
-#seriesname {
- float: right;
- width: 220px;
- margin-right: 165px;
- height: 24px;
+// bar graph background
+.perf-rect {
+ fill: var(--bg-secondary);
}
-input:focus,
-textarea:focus,
-select:focus {
- outline: none;
+.bargraph-position {
+ background-color: var(--bg-secondary);
}
diff --git a/src/app/styles/components/_rc-slider.scss b/src/app/styles/components/_rc-slider.scss
index 4df0d6579..c868f3349 100644
--- a/src/app/styles/components/_rc-slider.scss
+++ b/src/app/styles/components/_rc-slider.scss
@@ -1,250 +1,54 @@
.rc-slider {
- position: relative;
- width: 100%;
- margin: 20px;
- border-radius: 6px;
- -ms-touch-action: none;
- touch-action: none;
- box-sizing: border-box;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+ position: relative;
+ width: 100%;
+ margin: 12px;
+ border-radius: 6px;
}
-.rc-slider * {
- box-sizing: border-box;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-}
.rc-slider-rail {
- position: absolute;
- width: 100%;
- background-color: #ebf2fa;
- height: 4px;
- border-radius: 6px;
+ position: absolute;
+ width: 100%;
+ background-color: #d9d9d9;
+ height: 4px;
+ border-radius: 6px;
}
+
.rc-slider-track {
- position: absolute;
- left: 0;
- height: 4px;
- border-radius: 6px;
- background-color: $fiery-rose;
+ position: absolute;
+ left: 0;
+ height: 4px;
+ border-radius: 6px;
+ background-color: #284b63;
}
+
.rc-slider-handle {
- position: absolute;
- margin-left: -10px;
- margin-top: -10px;
- width: 25px;
- height: 25px;
- cursor: pointer;
- cursor: -webkit-grab;
- cursor: grab;
- border-radius: 50%;
- background: $red-color-gradient;
- -ms-touch-action: pan-x;
- touch-action: pan-x;
-}
-.rc-slider-handle:focus {
- border-color: $border-slider;
- outline: none;
-}
-.rc-slider-handle-click-focused:focus {
- border-color: #96dbfa;
-}
-.rc-slider-handle:hover {
- border-color: $border-slider;
-}
-.rc-slider-handle:active {
- background: #e4494b;
- border-color: $border-slider;
- cursor: -webkit-grabbing;
- cursor: grabbing;
-}
-.rc-slider-mark {
- position: absolute;
- top: 18px;
- left: 0;
- width: 100%;
- font-size: 12px;
-}
-.rc-slider-mark-text {
- position: absolute;
- display: inline-block;
- vertical-align: middle;
- text-align: center;
- cursor: pointer;
- color: #999;
-}
-.rc-slider-mark-text-active {
- color: #666;
-}
-.rc-slider-step {
- position: absolute;
- width: 100%;
- height: 4px;
- background: transparent;
-}
-.rc-slider-dot {
- position: absolute;
- bottom: -2px;
- margin-left: -4px;
- width: 8px;
- height: 8px;
- border: 2px solid $background-rc-color;
- background-color: #fff;
- cursor: pointer;
- border-radius: 50%;
- vertical-align: middle;
-}
-.rc-slider-dot-active {
- border-color: #96dbfa;
-}
-.rc-slider-disabled {
- background-color: $background-rc-color;
-}
-.rc-slider-disabled .rc-slider-track {
- background-color: #ccc;
-}
-.rc-slider-disabled .rc-slider-handle,
-.rc-slider-disabled .rc-slider-dot {
- border-color: #ccc;
- box-shadow: none;
- background-color: #fff;
- cursor: not-allowed;
-}
-.rc-slider-disabled .rc-slider-mark-text,
-.rc-slider-disabled .rc-slider-dot {
- cursor: not-allowed !important;
+ position: absolute;
+ margin-left: -8px;
+ width: 20px;
+ height: 20px;
+ cursor: pointer;
+ cursor: -webkit-grab;
+ cursor: grab;
+ border-radius: 50%;
+ background: #374151;
+ border: none;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ transition:
+ transform 0.2s ease,
+ box-shadow 0.2s ease;
}
+
.rc-slider-vertical {
- width: 14px;
- height: 100%;
- padding: 0 5px;
+ height: 100%;
+ padding: 0 5px;
}
+
.rc-slider-vertical .rc-slider-rail {
- height: 100%;
- width: 4px;
+ height: 100%;
+ width: 4px;
}
+
.rc-slider-vertical .rc-slider-track {
- left: 5px;
- bottom: 0;
- width: 4px;
-}
-.rc-slider-vertical .rc-slider-handle {
- margin-left: -5px;
- margin-bottom: -7px;
- -ms-touch-action: pan-y;
- touch-action: pan-y;
-}
-.rc-slider-vertical .rc-slider-mark {
- top: 0;
- left: 18px;
- height: 100%;
-}
-.rc-slider-vertical .rc-slider-step {
- height: 100%;
- width: 4px;
-}
-.rc-slider-vertical .rc-slider-dot {
- left: 2px;
- margin-bottom: -4px;
-}
-.rc-slider-vertical .rc-slider-dot:first-child {
- margin-bottom: -4px;
-}
-.rc-slider-vertical .rc-slider-dot:last-child {
- margin-bottom: -4px;
-}
-.rc-slider-tooltip-zoom-down-enter,
-.rc-slider-tooltip-zoom-down-appear {
- animation-duration: 0.3s;
- animation-fill-mode: both;
- display: block !important;
- animation-play-state: paused;
-}
-.rc-slider-tooltip-zoom-down-leave {
- animation-duration: 0.3s;
- animation-fill-mode: both;
- display: block !important;
- animation-play-state: paused;
-}
-.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,
-.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active {
- animation-name: rcSliderTooltipZoomDownIn;
- animation-play-state: running;
-}
-.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active {
- animation-name: rcSliderTooltipZoomDownOut;
- animation-play-state: running;
-}
-.rc-slider-tooltip-zoom-down-enter,
-.rc-slider-tooltip-zoom-down-appear {
- transform: scale(0, 0);
- animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
-}
-.rc-slider-tooltip-zoom-down-leave {
- animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
-}
-@keyframes rcSliderTooltipZoomDownIn {
- 0% {
- opacity: 0;
- transform-origin: 50% 100%;
- transform: scale(0, 0);
- }
- 100% {
- transform-origin: 50% 100%;
- transform: scale(1, 1);
- }
-}
-@keyframes rcSliderTooltipZoomDownOut {
- 0% {
- transform-origin: 50% 100%;
- transform: scale(1, 1);
- }
- 100% {
- opacity: 0;
- transform-origin: 50% 100%;
- transform: scale(0, 0);
- }
-}
-.rc-slider-tooltip {
- position: absolute;
- left: -9999px;
- top: -9999px;
- visibility: visible;
- box-sizing: border-box;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-}
-.rc-slider-tooltip * {
- box-sizing: border-box;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-}
-.rc-slider-tooltip-hidden {
- display: none;
-}
-.rc-slider-tooltip-placement-top {
- padding: 4px 0 8px 0;
-}
-.rc-slider-tooltip-inner {
- padding: 6px 2px;
- min-width: 24px;
- height: 24px;
- font-size: 12px;
- line-height: 1;
- color: #fff;
- text-align: center;
- text-decoration: none;
- background-color: #6c6c6c;
- border-radius: 6px;
-}
-.rc-slider-tooltip-arrow {
- position: absolute;
- width: 0;
- height: 0;
- border-color: transparent;
- border-style: solid;
-}
-.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow {
- bottom: 4px;
- left: 50%;
- margin-left: -4px;
- border-width: 4px 4px 0;
- border-top-color: #6c6c6c;
+ left: 5px;
+ width: 4px;
}
diff --git a/src/app/styles/components/_renderingFrequency.scss b/src/app/styles/components/_renderingFrequency.scss
deleted file mode 100644
index f0ed4f99f..000000000
--- a/src/app/styles/components/_renderingFrequency.scss
+++ /dev/null
@@ -1,116 +0,0 @@
-.borderStyling {
- border-radius: 5px;
- border: 1px solid rgba(184, 196, 194, 0.25);
- box-shadow: 2px 3px 4px 2px rgba(0, 0, 0, 0.2);
- width: 53vw;
-}
-
-.borderCheck {
- border: 1px solid rgba(184, 196, 194, 0.25);
- box-shadow: 2px 3px 4px 2px rgba(0, 0, 0, 0.2);
- padding: 5px;
- width: 10vw;
- height: 25vw;
- overflow-y: scroll;
- overflow-wrap: break-word;
- overscroll-behavior: contain;
-}
-
-.DataComponent {
- padding-left: 30px;
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- width: 50vw;
- height: 40vw;
- overflow-y: scroll;
- overflow-wrap: break-word;
- overscroll-behavior: contain;
-}
-
-
-.StyledGridElement {
- display: flex;
- align-items: center;
- justify-content: space-between;
- background: #242529;
- padding: 20px;
- height: 5vh;
- margin: 20px 10px;
- font-family: 'Roboto', sans-serif;
-
- h3 {
- color: $text-color;
- margin-bottom: 5px;
- margin-top: 5px;
- text-transform: uppercase;
- font-size: 14px;
- font-weight: 500;
- }
-
- h4 {
- color: $text-color;
- margin-bottom: 5px;
- margin-top: 5px;
- font-weight: 300;
- }
-
- p {
- color: $brand-color;
- line-height: 20px;
- text-align: center;
- font-size: 18px;
- line-height: 18px;
- }
-}
-
-.ExpandStyledGridElement {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- background: #242529;
- padding: 20px;
- margin: 20px 10px;
- font-family: 'Roboto', sans-serif;
-
- h3 {
- color: $text-color;
- margin-bottom: 5px;
- margin-top: 5px;
- text-transform: uppercase;
- font-size: 14px;
- font-weight: 500;
- }
-
- h4 {
- color: $text-color;
- margin-bottom: 5px;
- margin-top: 5px;
- font-weight: 300;
- }
-
- p {
- color: white;
- line-height: 20px;
- text-align: center;
- font-size: 18px;
- line-height: 18px;
- }
-}
-
-.RenderRight {
- cursor: pointer;
- padding-right: 5px;
- border-right: 5px;
- background: $blue-color-gradient;
- width: 50px;
- padding: 0 0.5em;
- right: 10%;
- opacity: 70%;
- transition: 0.3s;
-}
-
-.RenderRight:hover {
- opacity: 100%;
-}
\ No newline at end of file
diff --git a/src/app/styles/components/_sliderHandle.scss b/src/app/styles/components/_sliderHandle.scss
deleted file mode 100644
index 207b16c80..000000000
--- a/src/app/styles/components/_sliderHandle.scss
+++ /dev/null
@@ -1,170 +0,0 @@
-.rc-tooltip.rc-tooltip-zoom-enter,
-.rc-tooltip.rc-tooltip-zoom-leave {
- display: block;
-}
-.rc-tooltip-zoom-enter,
-.rc-tooltip-zoom-appear {
- opacity: 0;
- animation-duration: 0.3s;
- animation-fill-mode: both;
- animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);
- animation-play-state: paused;
-}
-.rc-tooltip-zoom-leave {
- animation-duration: 0.3s;
- animation-fill-mode: both;
- animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05);
- animation-play-state: paused;
-}
-.rc-tooltip-zoom-enter.rc-tooltip-zoom-enter-active,
-.rc-tooltip-zoom-appear.rc-tooltip-zoom-appear-active {
- animation-name: rcToolTipZoomIn;
- animation-play-state: running;
-}
-.rc-tooltip-zoom-leave.rc-tooltip-zoom-leave-active {
- animation-name: rcToolTipZoomOut;
- animation-play-state: running;
-}
-@keyframes rcToolTipZoomIn {
- 0% {
- opacity: 0;
- transform-origin: 50% 50%;
- transform: scale(0, 0);
- }
- 100% {
- opacity: 1;
- transform-origin: 50% 50%;
- transform: scale(1, 1);
- }
-}
-@keyframes rcToolTipZoomOut {
- 0% {
- opacity: 1;
- transform-origin: 50% 50%;
- transform: scale(1, 1);
- }
- 100% {
- opacity: 0;
- transform-origin: 50% 50%;
- transform: scale(0, 0);
- }
-}
-.rc-tooltip {
- position: absolute;
- z-index: 1070;
- display: block;
- visibility: visible;
- font-size: 12px;
- line-height: 1.5;
- opacity: 0.9;
-}
-.rc-tooltip-hidden {
- display: none;
-}
-.rc-tooltip-placement-top,
-.rc-tooltip-placement-topLeft,
-.rc-tooltip-placement-topRight {
- padding: 5px 0 9px 0;
-}
-.rc-tooltip-placement-right,
-.rc-tooltip-placement-rightTop,
-.rc-tooltip-placement-rightBottom {
- padding: 0 5px 0 9px;
-}
-.rc-tooltip-placement-bottom,
-.rc-tooltip-placement-bottomLeft,
-.rc-tooltip-placement-bottomRight {
- padding: 9px 0 5px 0;
-}
-.rc-tooltip-placement-left,
-.rc-tooltip-placement-leftTop,
-.rc-tooltip-placement-leftBottom {
- padding: 0 9px 0 5px;
-}
-.rc-tooltip-inner {
- padding: 8px 10px;
- color: #fff;
- text-align: left;
- text-decoration: none;
- background-color: $border-slider;
- border-radius: 6px;
- box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);
- min-height: 34px;
-}
-.rc-tooltip-arrow {
- position: absolute;
- width: 0;
- height: 0;
- border-color: transparent;
- border-style: solid;
-}
-.rc-tooltip-placement-top .rc-tooltip-arrow,
-.rc-tooltip-placement-topLeft .rc-tooltip-arrow,
-.rc-tooltip-placement-topRight .rc-tooltip-arrow {
- bottom: 4px;
- margin-left: -5px;
- border-width: 5px 5px 0;
- border-top-color: $border-slider;
-}
-.rc-tooltip-placement-top .rc-tooltip-arrow {
- left: 50%;
-}
-.rc-tooltip-placement-topLeft .rc-tooltip-arrow {
- left: 15%;
-}
-.rc-tooltip-placement-topRight .rc-tooltip-arrow {
- right: 15%;
-}
-.rc-tooltip-placement-right .rc-tooltip-arrow,
-.rc-tooltip-placement-rightTop .rc-tooltip-arrow,
-.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {
- left: 4px;
- margin-top: -5px;
- border-width: 5px 5px 5px 0;
- border-right-color: $border-slider;
-}
-.rc-tooltip-placement-right .rc-tooltip-arrow {
- top: 50%;
-}
-.rc-tooltip-placement-rightTop .rc-tooltip-arrow {
- top: 15%;
- margin-top: 0;
-}
-.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {
- bottom: 15%;
-}
-.rc-tooltip-placement-left .rc-tooltip-arrow,
-.rc-tooltip-placement-leftTop .rc-tooltip-arrow,
-.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {
- right: 4px;
- margin-top: -5px;
- border-width: 5px 0 5px 5px;
- border-left-color: $border-slider;
-}
-.rc-tooltip-placement-left .rc-tooltip-arrow {
- top: 50%;
-}
-.rc-tooltip-placement-leftTop .rc-tooltip-arrow {
- top: 15%;
- margin-top: 0;
-}
-.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {
- bottom: 15%;
-}
-.rc-tooltip-placement-bottom .rc-tooltip-arrow,
-.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow,
-.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {
- top: 4px;
- margin-left: -5px;
- border-width: 0 5px 5px;
- border-bottom-color: $border-slider;
-}
-.rc-tooltip-placement-bottom .rc-tooltip-arrow {
- left: 50%;
-}
-.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow {
- left: 15%;
-}
-.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {
- right: 15%;
-}
diff --git a/src/app/styles/components/d3graph.css b/src/app/styles/components/d3graph.css
index 9d4a9eb8c..319d14ddd 100644
--- a/src/app/styles/components/d3graph.css
+++ b/src/app/styles/components/d3graph.css
@@ -1,95 +1,122 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
-body {
- background-color: black;
+/* Base node styling */
+.node {
+ cursor: pointer;
+ fill-opacity: 1;
+ transition: all 200ms ease;
}
-.node {
- cursor: pointer;
- fill-opacity: 0.8;
+/* Node rectangle styling */
+.node rect {
+ fill: var(--bg-primary);
+ stroke: var(--border-color);
+ stroke-width: 1px;
+ transition: all 200ms ease;
+}
+
+.node:hover rect {
+ stroke: var(--color-primary);
+ stroke-width: 2px;
+ filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.1));
}
-/* this represents leaf nodes aka nodes with no children */
+/* Node text styling */
.node text {
- fill: #fae6e4;
- background-color: red;
- font-size: 10px;
- font-family: 'Roboto', sans-serif;
+ font-size: 14px;
+ font-weight: 500;
+ fill: var(--text-primary);
+}
+
+/* Parent node specific styling */
+.node--internal rect {
+ fill: var(--bg-primary);
+ stroke: var(--border-color);
+}
+
+.node--internal:hover rect {
+ stroke: var(--color-primary);
+ stroke-width: 2px;
}
-/* modifies text of parent nodes (has children) */
.node--internal text {
- fill: white;
- font-size: 10px;
+ font-size: 14px;
+ font-weight: 500;
+ fill: var(--text-primary);
+}
+
+/* Current/active node styling */
+.node.active rect {
+ stroke: var(--color-primary);
+ stroke-width: 2px;
}
+
+/* Link styling */
.link {
- fill: none;
- stroke: #fae6e4;
- stroke-opacity: 0.4;
- stroke-width: 3px;
+ fill: none;
+ stroke: var(--border-color);
+ stroke-width: 2px;
+ transition: stroke 200ms ease;
}
+.link:hover {
+ stroke: var(--border-color-dark);
+}
+
+/* Current path highlight */
+.link.current-link {
+ stroke: var(--color-primary);
+ stroke-opacity: 0.6;
+}
+
+/* Tooltip styling */
div.tooltip {
- position: absolute;
- padding: 0.5rem 1rem;
- color: white;
- z-index: 100;
- font-size: 14px;
- font-family: 'Roboto', sans-serif;
- background: rgb(17, 17, 17, 0.9);
- box-shadow: rgb(33 33 33 / 20%) 0px 1px 2px;
- border-radius: 5px;
- max-width: 300px;
-}
-
-.d3-tip {
- line-height: 1;
- padding: 6px;
- background: #679dca;
- color: #2b2f39;
- border-radius: 4px;
- font-size: 13px;
- max-width: 400px;
- overflow-wrap: break-word;
- font-family: 'Overpass Mono', monospace;
-}
-
-/* Creates a small triangle extender for the tooltip */
-.d3-tip:after {
- box-sizing: border-box;
- display: inline;
- font-size: 15px;
- line-height: 1;
- color: #679dca;
- content: '\25BC';
- position: absolute;
- text-align: center;
-}
-
-/* Style northward tooltips specifically */
-.d3-tip.n:after {
- margin: -2px 0 0 0;
- top: 100%;
- left: 0;
-}
-
-.history-d3-container {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- height: calc(100% - 70px);
-}
-
-.perf-d3-container {
- height: calc(100% - 70px);
-}
-
-.perf-d3-svg {
- display: block;
-}
-
-.perf-chart-labels {
- font: 1.3em sans-serif;
- fill: #2a2f3a;
- pointer-events: none;
- text-anchor: middle;
+ position: absolute;
+ padding: 12px;
+ color: var(--text-primary);
+ z-index: 100;
+ font-size: 14px;
+ font-weight: 500;
+ background: var(--bg-primary);
+ border: 1px solid var(--border-color);
+ box-shadow:
+ 0 4px 6px -1px rgba(0, 0, 0, 0.1),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ border-radius: 8px;
+ max-width: 250px;
+}
+
+/* Container styling */
+.display {
+ background-color: var(--bg-secondary);
+ flex: 1;
+ min-height: 0;
+ overflow: auto;
+}
+
+/* State changes text container styling */
+.node foreignObject div {
+ max-height: 100%; /* Fixed height for scroll container */
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-width: thin;
+ padding-right: 6px;
+ scrollbar-color: var(--border-color-dark) var(--bg-secondary);
+}
+
+/* Custom scrollbar styling for Webkit browsers */
+.node foreignObject div::-webkit-scrollbar {
+ width: 6px;
+}
+
+.node foreignObject div::-webkit-scrollbar-track {
+ background: var(--bg-secondary);
+ border-radius: 3px;
+}
+
+.node foreignObject div::-webkit-scrollbar-thumb {
+ background: var(--border-color-dark);
+ border-radius: 3px;
+}
+
+.node foreignObject div::-webkit-scrollbar-thumb:hover {
+ background: var(--text-tertiary);
}
diff --git a/src/app/styles/components/diff.css b/src/app/styles/components/diff.css
index cb74dd16f..17a164469 100644
--- a/src/app/styles/components/diff.css
+++ b/src/app/styles/components/diff.css
@@ -1,150 +1,96 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
.jsondiffpatch-delta {
- font-family: 'Roboto', sans-serif;
- font-size: 12px;
+ font-size: 14px;
margin: 0;
- padding: 0 0 0 12px;
+ padding: 0;
display: inline-block;
+ color: var(--text-primary);
}
.jsondiffpatch-delta pre {
- font-family: 'Roboto', sans-serif;
- font-size: 12px;
+ font-size: 14px;
margin: 0;
padding: 0;
display: inline-block;
+ color: var(--text-primary);
}
ul.jsondiffpatch-delta {
list-style-type: none;
- padding: 0 0 0 20px;
+ padding: 0;
margin: 0;
+ color: var(--text-primary);
}
.jsondiffpatch-delta ul {
list-style-type: none;
- padding: 0 0 0 20px;
+ padding: 0;
margin: 0;
+ color: var(--text-primary);
+}
+
+.node foreignObject div .initial-state,
+.node foreignObject div .no-changes {
+ color: var(--text-secondary);
+ font-style: italic;
+ padding: 4px 0;
+ display: block;
}
+
.jsondiffpatch-added .jsondiffpatch-property-name,
.jsondiffpatch-added .jsondiffpatch-value pre,
.jsondiffpatch-modified .jsondiffpatch-right-value pre,
.jsondiffpatch-textdiff-added {
- background: #5A6C46;
+ color: #14b8a6;
}
.jsondiffpatch-deleted .jsondiffpatch-property-name,
.jsondiffpatch-deleted pre,
.jsondiffpatch-modified .jsondiffpatch-left-value pre,
.jsondiffpatch-textdiff-deleted {
- background: #7E5C69;
text-decoration: line-through;
+ color: #dc2626;
}
-.jsondiffpatch-unchanged,
-.jsondiffpatch-movedestination {
- color: white;
-}
-.jsondiffpatch-unchanged,
-.jsondiffpatch-movedestination > .jsondiffpatch-value {
- transition: all 0.5s;
- -webkit-transition: all 0.5s;
- overflow-y: hidden;
-}
-.jsondiffpatch-unchanged-showing .jsondiffpatch-unchanged,
-.jsondiffpatch-unchanged-showing .jsondiffpatch-movedestination > .jsondiffpatch-value {
- max-height: 100px;
-}
-.jsondiffpatch-unchanged-hidden .jsondiffpatch-unchanged,
-.jsondiffpatch-unchanged-hidden .jsondiffpatch-movedestination > .jsondiffpatch-value {
- max-height: 0;
-}
-.jsondiffpatch-unchanged-hiding .jsondiffpatch-movedestination > .jsondiffpatch-value,
-.jsondiffpatch-unchanged-hidden .jsondiffpatch-movedestination > .jsondiffpatch-value {
- display: block;
-}
-.jsondiffpatch-unchanged-visible .jsondiffpatch-unchanged,
-.jsondiffpatch-unchanged-visible .jsondiffpatch-movedestination > .jsondiffpatch-value {
- max-height: 100px;
-}
-.jsondiffpatch-unchanged-hiding .jsondiffpatch-unchanged,
-.jsondiffpatch-unchanged-hiding .jsondiffpatch-movedestination > .jsondiffpatch-value {
- max-height: 0;
-}
-.jsondiffpatch-unchanged-showing .jsondiffpatch-arrow,
-.jsondiffpatch-unchanged-hiding .jsondiffpatch-arrow {
- display: none;
-}
+
.jsondiffpatch-value {
display: inline-block;
}
.jsondiffpatch-property-name {
display: inline-block;
- padding-right: 5px;
- vertical-align: top;
+ padding-right: 4px;
}
+
.jsondiffpatch-property-name:after {
content: ': ';
}
-.jsondiffpatch-child-node-type-array > .jsondiffpatch-property-name:after {
- content: ': [';
-}
-.jsondiffpatch-child-node-type-array:after {
- content: '],';
-}
-div.jsondiffpatch-child-node-type-array:before {
- content: '[';
-}
-div.jsondiffpatch-child-node-type-array:after {
- content: ']';
-}
-.jsondiffpatch-child-node-type-object > .jsondiffpatch-property-name:after {
- content: ': {';
-}
-.jsondiffpatch-child-node-type-object:after {
- content: '},';
-}
-div.jsondiffpatch-child-node-type-object:before {
- content: '{';
-}
-div.jsondiffpatch-child-node-type-object:after {
- content: '}';
-}
-.jsondiffpatch-value pre:after {
- content: ',';
-}
+
li:last-child > .jsondiffpatch-value pre:after,
.jsondiffpatch-modified > .jsondiffpatch-left-value pre:after {
content: '';
}
+
.jsondiffpatch-modified .jsondiffpatch-value {
display: inline-block;
}
+
.jsondiffpatch-modified .jsondiffpatch-right-value {
- margin-left: 5px;
-}
-.jsondiffpatch-moved .jsondiffpatch-value {
- display: none;
+ margin-left: 6px;
}
+
.jsondiffpatch-moved .jsondiffpatch-moved-destination {
display: inline-block;
- background: #ffffbb;
- color: #888;
+ color: #ffffbb;
}
+
.jsondiffpatch-moved .jsondiffpatch-moved-destination:before {
content: ' => ';
}
-ul.jsondiffpatch-textdiff {
- padding: 0;
-}
+
.jsondiffpatch-textdiff-location {
- color: #bbb;
+ color: #ffffbb;
display: inline-block;
min-width: 60px;
}
+
.jsondiffpatch-textdiff-line {
display: inline-block;
}
+
.jsondiffpatch-textdiff-line-number:after {
content: ',';
}
-.jsondiffpatch-error {
- background: red;
- color: white;
- font-weight: bold;
-}
diff --git a/src/app/styles/layout/_actionContainer.scss b/src/app/styles/layout/_actionContainer.scss
index 09640eea2..08a46b361 100644
--- a/src/app/styles/layout/_actionContainer.scss
+++ b/src/app/styles/layout/_actionContainer.scss
@@ -1,34 +1,24 @@
.action-container {
- // overflow: auto;
- // background-color: $brand-color;
+ background: var(--bg-primary);
+ border-right: 1px solid var(--border-color);
+ transition: width 0.3s ease;
overflow-x: hidden;
- background-color: #282828;
-}
-
-.actionname {
- background-color: inherit;
- color: #fffeff;
-}
-
-#recordBtn{
+ overflow-y: auto;
height: 100%;
- display:flex;
-}
-.actionToolContainer{
- display: flex;
- justify-content: space-between;
- align-items: center;
+ .action-button-wrapper {
+ opacity: 1;
+ visibility: visible;
+ transition:
+ opacity 0.2s ease,
+ visibility 0.2s ease;
+ }
}
-#recordBtn .fa-regular{
- height: 100%;
- width: 28px;
+.clear-button-container {
+ padding: 16px;
}
-.route {
- background-color: #ff6569;
- padding-left: 10px;
- padding-top: 5px;
- padding-bottom: 5px;
-}
\ No newline at end of file
+.dropdown-container {
+ padding: 4px 16px;
+}
diff --git a/src/app/styles/layout/_bodyContainer.scss b/src/app/styles/layout/_bodyContainer.scss
index abf8e9251..5e030eb8f 100644
--- a/src/app/styles/layout/_bodyContainer.scss
+++ b/src/app/styles/layout/_bodyContainer.scss
@@ -2,24 +2,17 @@
height: 100%;
overflow: hidden;
display: grid;
- grid-template-columns: min-content 1fr;
- grid-template-rows: 90% 5% 5%;
+ grid-template-columns: 280px 1fr;
+ grid-template-rows: 1fr auto;
grid-template-areas:
'actions states'
- 'travel travel'
- 'buttons buttons';
+ 'bottom bottom';
+ transition: grid-template-columns 0.3s ease;
}
-
-/* if extension width is less than 500px, stack the body containers */
-@media (max-width: 500px) {
- .body-container {
- grid-template-rows: 3fr 5fr 1fr;
- grid-template-columns: auto;
- grid-template-areas:
- 'actions'
- 'states'
- 'travel'
- 'buttons';
- }
+.bottom-controls {
+ grid-area: bottom;
+ display: flex;
+ width: 100%;
+ border-top: 1px solid var(--border-color);
}
diff --git a/src/app/styles/layout/_buttonsContainer.scss b/src/app/styles/layout/_buttonsContainer.scss
index 81263aea6..c4f3cb9ab 100644
--- a/src/app/styles/layout/_buttonsContainer.scss
+++ b/src/app/styles/layout/_buttonsContainer.scss
@@ -1,72 +1,104 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
-* {
- font-family: 'Roboto', sans-serif;
-}
.buttons-container {
- margin: 0 1% 0 1%;
- display: grid;
- grid-template-columns: repeat(5, 1fr);
- grid-gap: 1%;
- padding: 1% 0 1% 0;
+ display: flex;
+ align-items: center;
+ background: var(--bg-primary);
+ border-top: 1px solid var(--border-color);
+ width: 100%;
}
-.introjs-tooltip {
- color: black;
- background-color: white;
- min-width: 20rem;
+.buttons-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ max-width: 1200px;
+ width: 100%;
+ margin: 0 auto;
+ padding: 0 24px;
+ gap: 16px;
}
-.introjs-tooltiptext ul{
- padding-left: 2px;
+
+.introjs-button {
+ padding: 8px 16px;
+ font-size: 14px;
+ border-radius: 8px;
}
-// .introjs-helperLayer{
-// // border: 2px solid yellow
-// }
+.introjs-tooltip-title {
+ font-size: 18px;
+ font-weight: bold;
+ color: var(--text-primary);
+}
-.tools-container {
- display: flex;
- justify-content: space-between;
- border: .5px solid grey;
- background-color: #35383e;
- padding: 3px;
- margin-bottom: 1rem;
+.introjs-progressbar {
+ background-color: var(--color-primary);
}
-#seriesname {
- background-color: #333;
- color: white;
+.introjs-tooltip {
+ color: var(--text-primary);
+ background-color: var(--bg-primary);
+ min-width: 20rem;
}
-@media (max-width: 500px) {
- .buttons-container {
- grid-template-columns: repeat(2, 1fr);
- }
+.introjs-tooltiptext ul {
+ padding-left: 20px;
}
.introjs-nextbutton {
- background-color: none;
- color: #3256f1;
- border: 1px solid;
- outline: none;
+ background-color: var(--color-primary);
+ color: var(--button-primary-text);
}
-.introjs-prevbutton{
- background-color: none;
- color: #3256f1;
- border: 1px solid;
- outline: none;
+.introjs-prevbutton {
+ background-color: var(--bg-secondary);
+ color: var(--text-primary);
}
-
.introjs-skipbutton {
- color: #d72828;
- border: 1px solid;
- margin-top: 2px;
- font-size: 12px;
- outline: none;
+ color: #d72828;
+ margin-right: 8px;
+ font-size: 14px;
}
-.introjs-button {
- background: none;
- outline: none;
-}
\ No newline at end of file
+.buttons-container button {
+ display: flex;
+ align-items: center;
+ color: var(--text-secondary);
+ font-size: 1rem;
+ font-weight: 500;
+ background: transparent;
+ border: none;
+ border-radius: 0.375rem;
+ transition: all 200ms ease;
+ gap: 8px;
+}
+
+.status-dot {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+}
+
+.status-dot.active {
+ background-color: var(--color-primary);
+ animation: pulse 2s infinite;
+}
+
+.status-dot.inactive {
+ background-color: var(--text-tertiary);
+}
+
+@keyframes pulse {
+ 0% {
+ opacity: 1;
+ transform: scale(1);
+ }
+ 50% {
+ opacity: 0.7;
+ transform: scale(1.1);
+ }
+ 100% {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
diff --git a/src/app/styles/layout/_errorContainer.scss b/src/app/styles/layout/_errorContainer.scss
index e789d5ae0..9c41044e2 100644
--- a/src/app/styles/layout/_errorContainer.scss
+++ b/src/app/styles/layout/_errorContainer.scss
@@ -1,78 +1,102 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
-* {
- font-family: 'Roboto', sans-serif;
-}
.error-container {
- height: 100%;
- margin: 0 auto;
- background-color: $brand-color;
- overflow: hidden;
- font: 'Roboto', sans-serif;
+ height: 100%;
+ background-color: var(--bg-secondary);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+.error-logo {
+ height: 50px;
+ margin-bottom: 2rem;
+}
+
+.error-content {
+ max-width: 600px;
+ width: 100%;
+}
- display: flex;
- flex-direction: column;
- align-items: center;
- a {
- color: white;
- margin-top: 1%;
- height: 3%;
- }
- img {
- text-align: center;
- padding-top: 5%;
- padding-bottom: 1.5%;
- }
- p {
- padding: 0;
- text-align: center;
- margin: 2% 0;
- }
- .loaderChecks {
- padding: 1%;
- border: 1px solid;
- border-style: solid;
- border-color: white;
- display: grid;
- grid-template-columns: 4fr 1fr;
- grid-template-rows: repeat(3, 1fr);
- grid-column-gap: .5%;
- grid-row-gap: .5%;
- justify-content: center;
- align-items: center;
- }
- h2 {
- padding-left: 2%;
- padding-right: 2%;
- }
- .check, .fail{
- font-size: 3em;
- color: green;
- margin: 0;
- align-self: center;
- justify-self: center;
- }
- .fail{
- color: red;
- }
- .errorMsg{
- text-align: center;
- font-weight: bold;
- }
+.error-alert {
+ background-color: var(--bg-primary);
+ border: 1px solid var(--border-color);
+ border-radius: 8px;
+ padding: 1.5rem;
+ margin-bottom: 2rem;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.error-title {
+ font-size: 1.25rem;
+ font-weight: 600;
+ color: var(--text-primary);
+ margin-bottom: 0.75rem;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
- .launchContentButton {
- background: $blue-brand;
- color: $brand-color;
- margin: 3px;
- padding: 5px 10px;
- border-radius: 5px;
- border: 1px solid rgb(36, 37, 41);
- }
+.error-description {
+ color: var(--text-secondary);
+ line-height: 1.5;
+ margin-bottom: 1rem;
+}
+
+.error-note {
+ text-align: center;
+ color: var(--text-tertiary);
+ font-size: 0.875rem;
+ margin-bottom: 1rem;
+}
- .launchContentButton:hover {
- background: $light-background-color;
- }
+.launch-button {
+ background-color: var(--button-primary-bg);
+ color: var(--button-primary-text);
+ border: none;
+ padding: 12px 24px;
+ border-radius: 8px;
+ font-size: 1.125rem;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ margin: 0 auto;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.launch-button:hover {
+ background-color: var(--text-primary);
+}
+
+.launch-button:active {
+ background-color: var(--button-primary-bg);
+}
+
+.github-link {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ margin-top: 2rem;
+ color: var(--color-primary);
+ text-decoration: none;
+ transition: color 0.2s ease;
+}
+
+.github-link:hover {
+ color: var(--color-primary-dark);
+ text-decoration: underline;
+}
+
+.devtools-link {
+ color: var(--color-primary);
+ text-decoration: none;
+ transition: color 0.2s ease;
+}
- .launchContentButton:active {
- box-shadow: 1px 1px 10px black;
- }
+.devtools-link:hover {
+ color: var(--color-primary-dark);
+ text-decoration: underline;
}
diff --git a/src/app/styles/layout/_headContainer.scss b/src/app/styles/layout/_headContainer.scss
deleted file mode 100644
index 0f26b0192..000000000
--- a/src/app/styles/layout/_headContainer.scss
+++ /dev/null
@@ -1,124 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
-* {
- font-family: 'Roboto', sans-serif;
-}
-
-.head-container {
- height: 5%;
- background: linear-gradient(
- 90deg,
- rgba(41, 41, 41, 1) 0%,
- rgba(51, 51, 51, 1) 50%,
- rgba(41, 41, 41, 1) 100%
- );
-}
-
-.head-container {
- display: flex;
- flex-direction: row-reverse;
- align-items: center;
- justify-content: center;
-}
-
-div .tab-select-container {
- background-color: $background-color;
- font-size: 14px;
- height: 40px;
- width: 100%;
- margin-bottom: 0;
-}
-
-.tab-select-container:focus {
- background-color: $background-color;
-
- outline: none;
-}
-
-.tab-select-container:active {
- background-color: $background-color;
-
- outline: none;
- border-color: transparent;
-}
-
-svg {
- color: #58c1e2;
-}
-
-.tab-select-container {
- background-color: $background-color;
- height: 70%;
-
- .tab-select__control:focus {
- outline: none;
- }
- div.tab-select-container.css-2b097c-container {
- background-color: $background-color;
- margin: 0;
- }
-
- .tab-select__control,
- .tab-select__menu {
- background-color: $background-color;
- outline: none;
- font-size: 14px;
- border-style: none;
- background-color: $brand-color;
- z-index: 2;
- margin-bottom: 0;
- @extend %disable-highlight;
- }
- .tab-select__single-value {
- color: white;
- }
- .tab-select__value-container {
- background-color: $background-color;
- margin: 0;
- padding: 0px;
- }
- .tab-select__value-container:focus {
- outline: none;
- }
- .tab-select__option:hover {
- margin-top: 0;
- background-color: $light-grey-three;
- color: black;
- }
- .tab-select__option--is-selected,
- .tab-select__option--is-focused {
- background-color: transparent;
- outline: transparent;
- }
- .tab-select__indicator {
- padding: 0;
- }
- .tab-select__indicator-separator {
- margin-top: 3px;
- margin-bottom: 3px;
- }
-
- .css-1uccc91-singleValue {
- margin-left: 8px;
- }
- // removes the cursor from blinking
- .css-w8afj7-Input {
- color: transparent;
- }
-
- // removes min-height of dropdown and change it to 100%
- .css-yk16xz-control,
- .css-1pahdxg-control {
- min-height: initial;
- height: 100%;
- background-color: $background-color;
- border: none;
- outline: none;
- margin-bottom: 0;
- border-radius: 0;
- }
- .css-yk16xz-control:focus,
- .css-1pahdxg-control:focus {
- outline: none;
- border-radius: 0;
- }
-}
diff --git a/src/app/styles/layout/_mainContainer.scss b/src/app/styles/layout/_mainContainer.scss
index a9a67ae90..b8da1cd86 100644
--- a/src/app/styles/layout/_mainContainer.scss
+++ b/src/app/styles/layout/_mainContainer.scss
@@ -1,15 +1,25 @@
.main-container {
height: 100%;
margin: 0 auto;
- background-color: $brand-color;
+ background-color: var(--bg-secondary);
overflow: hidden;
}
-.state-container-container{
+.state-container-container {
display: contents;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
}
-.split {
+.history-view {
+ height: 100%;
+ width: 100%;
display: flex;
- overflow-y: auto;
+ flex-direction: column;
+}
+
+.history-end-anchor {
+ height: 1px;
+ width: 100%;
}
diff --git a/src/app/styles/layout/_stateContainer.scss b/src/app/styles/layout/_stateContainer.scss
index 7a65795af..2a29e913a 100644
--- a/src/app/styles/layout/_stateContainer.scss
+++ b/src/app/styles/layout/_stateContainer.scss
@@ -1,259 +1,189 @@
.state-container {
- font-size: 10px;
overflow: auto;
- background-color: $brand-color;
- // margin-left: 5px;
-}
-
-.toggleAC {
- // color: #00dffc;
- color: $blue-brand;
- background: $background-color;
- height: 50%;
- text-decoration: none;
- border: none;
-}
-
-.toggleAC:focus {
- outline: none;
- box-shadow: none;
-}
-
-.state-container .navbar {
- background-color: $background-color;
+ height: 100%;
display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
- height: 30px;
- position: static;
+ flex-direction: column;
}
-.state-container .main-navbar {
- background-color: $background-color;
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: center;
- height: 35px;
- margin: 6px;
-}
-
-.state-container .componentMapContainer{
- height: 95% !important;
-}
-
-.state-container .main-navbar-container {
- position: sticky;
- top: 0px;
- left: 0px;
- z-index: 1;
- // background-color: $background-color;
- background-color: #252525;
-
+.app-body {
+ height: 100%;
display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- height: 35px;
+ flex-direction: column;
}
-.navbar {
- // prevent navbar from scrolling with state/tree display
- position: sticky;
- top: 0px;
- left: 0px;
- z-index: 1;
- @extend %disable-highlight;
+.app-content {
+ height: 100%;
+ min-height: 0;
}
-.no-data-message {
- color: $text-color;
- font: normal 13px $text-font-stack;
- padding: 10px;
+.main-navbar-container--structural {
+ height: 0;
+ padding: 0;
+ border: none;
+ overflow: hidden;
+ visibility: hidden;
+ pointer-events: none;
}
.state-container {
- .main-navbar-text {
- margin: 6px;
- }
-
- .main-router-link {
- font-size: 14px;
- height: 75%;
- width: 75px;
- display: flex;
- justify-content: center;
- align-items: center;
- text-decoration: none;
- color: $text-color;
-
- background: $brand-color;
- border-radius: 5px;
- border: 1px solid rgba(184, 196, 194, 0.25);
- }
-
- .main-router-link:hover {
- background: $light-background-color;
- }
-
- .main-router-link.is-active {
- background: $blue-brand;
- color: $brand-color;
- margin: 3px;
- border-radius: 5px;
- border: 1px solid rgb(36, 37, 41);
- }
-
.router-link {
- height: 100%;
- width: 34%;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: $medium-background-color;
+ padding: 8px 16px;
+ font-size: 14px;
+ font-weight: 500;
+ border: none;
+ border-bottom: 2px solid transparent;
+ color: var(--text-secondary);
text-decoration: none;
- color: $text-color;
- }
-
- .router-link:hover {
- background-color: $light-grey-three;
- }
-
- .router-link.is-active {
- background-color: $brand-color;
- }
-
- .navbar {
- background-color: $navbar-color;
- display: flex;
- flex-direction: row;
- justify-content: start;
- align-items: center;
- height: 30px;
+ background-color: transparent;
+ cursor: pointer;
+ transition:
+ color 200ms ease,
+ border-color 200ms ease;
+ margin: 0;
+ position: relative;
+ white-space: nowrap;
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ width: 0;
+ height: 2px;
+ background-color: var(--color-primary);
+ transition: all 0.3s ease;
+ transform: translateX(-50%);
+ }
+
+ &:hover {
+ color: var(--text-primary);
+ background-color: transparent;
+
+ &::after {
+ width: 100%;
+ }
+ }
+
+ &.is-active {
+ color: var(--color-primary);
+ background-color: transparent;
+
+ &::after {
+ width: 100%;
+ background-color: var(--color-primary);
+ }
+ }
}
.main-navbar {
- background-color: $background-color;
display: flex;
flex-direction: row;
- justify-content: flex-start;
+ justify-content: space-between;
align-items: center;
- height: 35px;
- margin: 6px;
+ gap: 8px;
+ width: 100%;
}
.main-navbar-container {
- top: 0px;
- left: 0px;
- z-index: 1;
- background-color: $background-color;
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: center;
- height: 40px;
+ border-bottom: 1px solid var(--border-color);
+ background: var(--bg-primary);
+ padding: 4.5px 24px;
}
}
-.no-data-message {
- color: $text-color;
- font: normal 13px $text-font-stack;
- padding: 10px;
+// tool tip styles
+.tooltip-header {
+ padding: 8px 8px 8px 12px;
+ background-color: var(--color-primary);
+ border: 1px solid var(--color-primary-dark);
+ border-radius: 8px;
}
-.performance-nav-bar-container {
- background-color: $navbar-color;
- display: flex;
- height: 30px;
+.tooltip-title {
+ margin: 0;
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--bg-primary);
}
-.router-link-performance {
- height: 100%;
- width: 34%;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: $brand-color;
- text-decoration: none;
- color: $text-color;
+.tooltip-container {
+ width: 250px;
+ background-color: var(--bg-primary);
+ border-radius: 8px;
+ overflow: hidden;
}
-.router-link-performance:hover {
- background-color: $light-grey-four;
+.tooltip-section {
+ padding: 8px 12px;
+ border-bottom: 1px solid var(--border-color);
+ transition: background-color 150ms ease;
}
-.router-link-performance.is-active {
- font-weight: 600;
+.tooltip-section:last-child {
+ border-bottom: none;
}
-// Web Metrics Container
-.web-metrics-container {
- display: grid;
- grid-template-columns: auto auto;
- align-items: center;
- justify-content: center;
+.tooltip-section-title {
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--color-primary);
}
-//container for metrics
-.metric {
- min-height: 200px;
- min-width: 200px;
+.tooltip-content {
+ max-height: 400px;
+ overflow-y: auto;
+ scrollbar-width: thin;
+ scrollbar-color: #cbd5e1 transparent;
}
-.bargraph {
- position: relative;
- margin-top: 1rem;
+.tooltip-item {
+ padding: 8px 0;
+ border-bottom: 1px solid rgba(107, 114, 128, 0.1);
}
-#hover-box {
- max-width: 150px;
- background-color: #51565e;
- border-radius: 5px;
- color: white;
+.tooltip-item:last-child {
+ border-bottom: none;
}
-.bargraph-position {
- position: relative;
+.tooltip-data {
+ border-left: 2px solid var(--color-primary-dark);
}
-// tool tip styles
-
-
-.visx-tooltip{
- overflow-y: auto;
- overflow-wrap: break-word;
- pointer-events:all !important;
-}
-.props, .stateTip{
- margin-top: 3px;
- line-height: 1;
- height: 100%;
- overflow-y: hidden;
- max-height: 400px;
-}
-.props{
- margin-top: 3px;
-}
-.props p{
- line-height:1;
- margin-top: 3px;
- margin-bottom: 0px;
+.tooltip-container {
+ animation: tooltipFade 150ms ease-out;
}
-.stateTip p{
- line-height:1;
- margin-top: 3px;
- margin-bottom: 0px;
+
+// Web Metrics Container
+.web-metrics-container {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
}
-.historyToolTip{
- z-index: 2;
+
+.metric {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
+.hover-box {
+ max-width: 250px;
+ background-color: #51565e;
+ border-radius: 8px;
+ color: white;
+ padding: 2px 8px;
+ line-height: 16px;
+}
-.state-container .router-link {
- border: 0.5px solid black;
+/* Tree styling */
+.json-tree {
+ overflow: auto;
+ list-style: none;
+ padding: 16px;
+ margin: 0;
}
-/* if state view is width is less than 500px, stack the body containers */
-// @media (max-width: 500px) {
-// }
+.tree-component {
+ height: 100%;
+ overflow: auto;
+}
diff --git a/src/app/styles/layout/_travelContainer.scss b/src/app/styles/layout/_travelContainer.scss
index 468be1df2..58f53a23b 100644
--- a/src/app/styles/layout/_travelContainer.scss
+++ b/src/app/styles/layout/_travelContainer.scss
@@ -1,61 +1,129 @@
.travel-container {
- // background: linear-gradient(
- // 90deg,
- // rgba(41, 41, 41, 1) 0%,
- // rgba(51, 51, 51, 1) 50%,
- // rgba(41, 41, 41, 1) 100%
- // );
- // border-color: $border-color;
- // display: flex;
- // flex-direction: row;
- // align-items: center;
- // justify-content: space-around;
+ background: var(--bg-primary);
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ border-top: 1px solid var(--border-color);
+ padding-left: 16px;
+ gap: 8px;
+}
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-around;
- border: none;
- margin-top: 18px;
+.react-select-container {
+ font-size: 16px;
+ min-width: 90px;
+ margin: 8px;
}
-.visx-group{
- margin-top: 10px;
+.react-select__control {
+ background-color: var(--bg-secondary) !important;
+ border: 1px solid var(--border-color) !important;
+ border-radius: 6px !important;
+ min-height: 36px !important;
+ box-shadow: none !important;
+ cursor: pointer !important;
+ transition: all 200ms ease !important;
}
+.react-select__control:hover {
+ border-color: var(--border-color-dark) !important;
+ background-color: var(--bg-tertiary) !important;
+}
-.react-select-container {
- font-size: 12px;
- min-width: 90px;
- margin: 8px;
- .react-select__control {
- background-color: $light-grey-four;
- border-color: transparent;
- @extend %disable-highlight;
- }
- .react-select__control:hover {
- cursor: pointer;
- }
- .react-select__menu {
- background-color: $light-grey-four;
- @extend %disable-highlight;
- }
- .react-select__single-value {
- color: white;
- }
- .react-select__option:hover {
- background-color: $fiery-rose;
- cursor: pointer;
- }
- .react-select__option--is-selected,
- .react-select__option--is-focused {
- background-color: transparent;
- cursor: pointer;
-
- }
-
- // removes the cursor from blinking
- .css-w8afj7-Input {
- color: transparent;
- }
+.react-select__control--is-focused {
+ border-color: var(--color-primary) !important;
+ box-shadow: 0 0 0 2px rgba(20, 184, 166, 0.1) !important;
+}
+
+.react-select__menu {
+ background-color: var(--bg-primary) !important;
+ border: 1px solid var(--border-color) !important;
+ border-radius: 6px !important;
+ box-shadow:
+ 0 4px 6px -1px rgba(0, 0, 0, 0.1),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important;
+ margin-top: 4px !important;
+ z-index: 100 !important;
+}
+
+.react-select__option {
+ background-color: var(--bg-primary) !important;
+ color: var(--text-primary) !important;
+ cursor: pointer !important;
+ padding: 8px 12px !important;
+ font-size: 14px !important;
+ transition: all 200ms ease !important;
+}
+
+.react-select__option:hover {
+ background-color: var(--bg-tertiary) !important;
+}
+
+.react-select__option--is-selected {
+ background-color: var(--color-primary) !important;
+ color: white !important;
+}
+
+.react-select__option--is-focused {
+ background-color: var(--bg-tertiary) !important;
+}
+
+.react-select__single-value {
+ color: var(--text-primary) !important;
+ font-size: 14px !important;
+}
+
+.react-select__indicator-separator {
+ background-color: var(--border-color) !important;
+}
+
+.react-select__dropdown-indicator {
+ color: var(--text-secondary) !important;
+ transition: transform 200ms ease !important;
+}
+
+.react-select__dropdown-indicator:hover {
+ color: var(--text-primary) !important;
+}
+
+.react-select__control--menu-is-open .react-select__dropdown-indicator {
+ transform: rotate(180deg) !important;
+}
+
+.react-select__placeholder {
+ color: var(--text-secondary) !important;
+ font-size: 14px !important;
+}
+
+.react-select__multi-value {
+ background-color: var(--bg-tertiary) !important;
+ border-radius: 4px !important;
+}
+
+.react-select__multi-value__label {
+ color: var(--text-primary) !important;
+ font-size: 14px !important;
+ padding: 2px 6px !important;
+}
+
+.react-select__multi-value__remove {
+ color: var(--text-secondary) !important;
+ cursor: pointer !important;
+ padding: 0 4px !important;
+ transition: all 200ms ease !important;
+}
+
+.react-select__multi-value__remove:hover {
+ background-color: var(--border-color) !important;
+ color: var(--text-primary) !important;
+}
+
+.react-select__clear-indicator {
+ color: var(--text-secondary) !important;
+ cursor: pointer !important;
+ padding: 0 8px !important;
+ transition: all 200ms ease !important;
+}
+
+.react-select__clear-indicator:hover {
+ color: var(--text-primary) !important;
}
diff --git a/src/app/styles/main.scss b/src/app/styles/main.scss
index ec662a4ad..a63383eaf 100644
--- a/src/app/styles/main.scss
+++ b/src/app/styles/main.scss
@@ -1,78 +1,90 @@
-@charset 'UTF-8';
-@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
+@use 'base/helpers';
-* {
- font-family: 'Roboto', sans-serif;
-}
+@use 'layout/mainContainer';
+@use 'layout/bodyContainer';
+@use 'layout/actionContainer';
+@use 'layout/errorContainer';
+@use 'layout/stateContainer';
+@use 'layout/travelContainer';
+@use 'layout/buttonsContainer';
-.tooltipWrapper {
- background-color: #505050;
- color: rgb(216, 216, 216);
- margin-top: 3px;
- margin-bottom: 3px;
- padding: 2px;
-}
+@use 'components/buttons';
+@use 'components/actionComponent';
+@use 'components/performanceVisx';
+@use 'components/componentMap';
+@use 'components/ax';
-.tooltipWrapper h2 {
- margin-top: 1px;
- margin-bottom: 1px;
- margin-left: 1px;
- font-size: small;
- font-weight: bolder;
-}
+@use './components/rc-slider';
+@use './components/d3graph';
+@use './components/diff';
-.tooltipWrapper p {
- margin-top: 1px;
- margin-bottom: 1px;
- margin-left: 10px;
- margin-right: 3px;
-}
+@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@100;200;300;400;500;600;700;800;900&display=swap');
-/* width */
-::-webkit-scrollbar {
- width: 5px;
- height: 8px;
+* {
+ font-family: 'Outfit', sans-serif;
+ font-size: 14px;
}
-/* Track */
-::-webkit-scrollbar-track {
- // background: rgb(20, 20, 20);
- background: none;
+html {
+ margin: 0;
+ padding: 0;
+ height: 100%;
}
-/* Handle */
-::-webkit-scrollbar-thumb {
- background: rgb(67, 67, 71);
+body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
}
-/* Handle on hover */
-::-webkit-scrollbar-thumb:hover {
- background: rgb(97, 97, 97);
+:root {
+ // Base colors
+ --color-primary: #14b8a6;
+ --color-primary-dark: #0d9488;
+ --color-primary-light: #2dd4bf;
+
+ // Background colors
+ --bg-primary: #ffffff;
+ --bg-secondary: #f9fafb;
+ --bg-tertiary: #f3f4f6;
+
+ // Border colors
+ --border-color: #e5e7eb;
+ --border-color-dark: #d1d5db;
+
+ // Text colors
+ --text-primary: #374151;
+ --text-secondary: #6b7280;
+ --text-tertiary: #9ca3af;
+
+ // Interactive colors
+ --hover-bg: #f9fafb;
+ --selected-bg: #f3f4f6;
+ --button-primary-bg: #111827;
+ --button-primary-text: #ffffff;
+
+ // Transitions
+ --theme-transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}
-// fixing the tooltip display for overflow scrolling
-
-// 1. Configuration and helpers
-@import 'abstracts/variables';
-
-// 3. Base stuff
-@import 'base/base', 'base/helpers', 'base/typography';
-
-// 4. Layout-related sections
-@import 'layout/mainContainer', 'layout/bodyContainer', 'layout/actionContainer',
-'layout/errorContainer', 'layout/stateContainer', 'layout/travelContainer',
-'layout/buttonsContainer', 'layout/headContainer.scss';
-
-// 5. Components
-@import 'components/buttons', 'components/actionComponent',
-'components/jsonTree', 'components/renderingFrequency',
-'components/performanceVisx';
-
-// slider component
-@import './components/rc-slider', './components/sliderHandle';
-
-// d3 chart component
-@import './components/d3graph.css';
-
-// diff component
-@import './components/diff';
\ No newline at end of file
+:root.dark {
+ // Background colors
+ --bg-primary: #1f2937;
+ --bg-secondary: #2d3748;
+ --bg-tertiary: #374151;
+
+ // Border colors
+ --border-color: #374151;
+ --border-color-dark: #4b5563;
+
+ // Text colors
+ --text-primary: #f3f4f6;
+ --text-secondary: #9ca3af;
+ --text-tertiary: #6b7280;
+
+ // Interactive colors
+ --hover-bg: #2d3748;
+ --selected-bg: #374151;
+ --button-primary-bg: #0f172a;
+ --button-primary-text: #ffffff;
+}
diff --git a/src/app/types/provider.types.ts b/src/app/types/provider.types.ts
new file mode 100644
index 000000000..86c24841b
--- /dev/null
+++ b/src/app/types/provider.types.ts
@@ -0,0 +1,26 @@
+export interface ComponentData {
+ context?: Record;
+ props?: Record;
+ hooksState?: Record;
+ reducerStates?: Record;
+}
+
+export interface Node {
+ name?: string;
+ componentData?: ComponentData;
+ props?: Record;
+ children?: Node[];
+}
+
+export interface FilteredNode {
+ [key: string]: any;
+}
+
+export interface JsonTheme {
+ scheme: string;
+ base00: string;
+ base0B: string;
+ base0D: string;
+ base09: string;
+ base0C: string;
+}
\ No newline at end of file
diff --git a/src/app/utils/providerUtils.ts b/src/app/utils/providerUtils.ts
new file mode 100644
index 000000000..ebddd8d6f
--- /dev/null
+++ b/src/app/utils/providerUtils.ts
@@ -0,0 +1,142 @@
+import { FilteredNode, Node, JsonTheme } from '../types/provider.types';
+
+export const jsonTheme: JsonTheme = {
+ scheme: 'custom',
+ base00: 'transparent',
+ base0B: '#14b8a6', // dark navy for strings
+ base0D: '#60a5fa', // Keys
+ base09: '#f59e0b', // Numbers
+ base0C: '#EF4444', // Null values
+};
+
+export const keepContextAndProviderNodes = (node: Node | null): Node | null => {
+ if (!node) return null;
+
+ // Check if this node should be kept
+ const hasContext =
+ node?.componentData?.context && Object.keys(node.componentData.context).length > 0;
+ const isProvider = node?.name && node.name.endsWith('Provider');
+ const shouldKeepNode = hasContext || isProvider;
+
+ // Process children first
+ let processedChildren: Node[] = [];
+ if (node.children) {
+ processedChildren = node.children
+ .map((child) => keepContextAndProviderNodes(child))
+ .filter((child): child is Node => child !== null); // Remove null results
+ }
+
+ // If this node should be kept or has kept children, return it
+ if (shouldKeepNode || processedChildren.length > 0) {
+ return {
+ ...node,
+ children: processedChildren,
+ };
+ }
+
+ // If neither the node should be kept nor it has kept children, filter it out
+ return null;
+};
+
+export const filterComponentProperties = (node: Node | null): FilteredNode | null => {
+ if (!node) return null;
+
+ // Helper function to check if an object is empty (including nested objects)
+ const isEmptyObject = (obj: unknown): boolean => {
+ if (!obj) return true;
+ if (Array.isArray(obj)) return obj.length === 0;
+ if (typeof obj !== 'object') return false;
+
+ // Check each property recursively
+ for (const key in obj as object) {
+ const value = (obj as Record)[key];
+ if (typeof value === 'object') {
+ if (!isEmptyObject(value)) return false;
+ } else if (value !== undefined && value !== null) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ // Create a new object for the filtered node
+ const filteredNode: FilteredNode = {};
+
+ // Flatten root level props if they exist
+ if (node.props && !isEmptyObject(node.props)) {
+ Object.entries(node.props).forEach(([key, value]) => {
+ if (!isEmptyObject(value)) {
+ filteredNode[`${key}`] = value;
+ }
+ });
+ }
+
+ // Flatten componentData properties into root level if they exist
+ if (node.componentData?.context && !isEmptyObject(node.componentData.context)) {
+ // Add context directly if it exists
+ Object.entries(node.componentData.context).forEach(([key, value]) => {
+ if (!isEmptyObject(value)) {
+ filteredNode[`${key}`] = value;
+ }
+ });
+
+ // Flatten componentData.props if they exist
+ if (node.componentData.props && !isEmptyObject(node.componentData.props)) {
+ Object.entries(node.componentData.props).forEach(([key, value]) => {
+ if (!isEmptyObject(value)) {
+ filteredNode[`${key}`] = value;
+ }
+ });
+ }
+
+ // Flatten componentData.hooksState if it exists
+ if (node.componentData.hooksState && !isEmptyObject(node.componentData.hooksState)) {
+ Object.entries(node.componentData.hooksState).forEach(([key, value]) => {
+ if (!isEmptyObject(value)) {
+ filteredNode[`${key}`] = value;
+ }
+ });
+ }
+ }
+
+ // Flatten root level hooksState if it exists
+ if (node.componentData?.hooksState && !isEmptyObject(node.componentData.hooksState)) {
+ filteredNode['State'] = node.componentData.hooksState;
+ }
+
+ // Process children and add them using the node's name as the key
+ if (node.children && Array.isArray(node.children)) {
+ for (const child of node.children) {
+ const filteredChild = filterComponentProperties(child);
+ if (filteredChild && !isEmptyObject(filteredChild) && child.name) {
+ filteredNode[child.name] = filteredChild;
+ }
+ }
+ }
+
+ // Only return the node if it has at least one non-empty property
+ return isEmptyObject(filteredNode) ? null : filteredNode;
+};
+
+export const parseStringifiedValues = (obj: unknown): unknown => {
+ if (!obj || typeof obj !== 'object') return obj;
+
+ const parsed = { ...(obj as Record) };
+ for (const key in parsed) {
+ if (typeof parsed[key] === 'string') {
+ try {
+ // Check if the string looks like JSON
+ if ((parsed[key] as string).startsWith('{') || (parsed[key] as string).startsWith('[')) {
+ const parsedValue = JSON.parse(parsed[key] as string);
+ parsed[key] = parsedValue;
+ }
+ } catch (e) {
+ // If parsing fails, keep original value
+ continue;
+ }
+ } else if (typeof parsed[key] === 'object') {
+ parsed[key] = parseStringifiedValues(parsed[key]);
+ }
+ }
+ return parsed;
+};
\ No newline at end of file
diff --git a/src/backend/__tests__/helpers.test.ts b/src/backend/__tests__/helpers.test.ts
deleted file mode 100644
index 0ffcb5e8a..000000000
--- a/src/backend/__tests__/helpers.test.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-/* eslint-disable max-len */
-/* eslint-disable jest/no-disabled-tests */
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable react/button-has-type */
-/* eslint-disable react/jsx-filename-extension */
-/* eslint-disable jest/valid-describe */
-/* eslint-disable react/react-in-jsx-scope */
-// import { configure } from 'enzyme';
-// import Adapter from 'enzyme-adapter-react-16';
-// import toJson from 'enzyme-to-json';
-import { throttle, getHooksNames } from '../helpers';
-
-// Newer Enzyme versions require an adapter to a particular version of React
-// configure({ adapter: new Adapter() });
-
-// Replace any setTimeout functions with jest timer
-jest.useFakeTimers();
-
-describe('AST Unit Tests', () => {
-
- describe('throttle', () => {
- let mockFunc;
- let throttledMockFunc;
-
- beforeEach(() => {
- mockFunc = jest.fn();
- throttledMockFunc = throttle(mockFunc, 1000);
- });
-
- it('Should return a function', () => {
- expect(typeof throttledMockFunc).toBe('function');
- });
-
- it('throttles subsequent fire attempts into one shot after cooldown', () => {
- throttledMockFunc();
- expect(mockFunc).toHaveBeenCalledTimes(1);
- jest.advanceTimersByTime(20);
- throttledMockFunc();
- jest.advanceTimersByTime(20);
- throttledMockFunc();
- jest.advanceTimersByTime(20);
- throttledMockFunc();
- expect(mockFunc).toHaveBeenCalledTimes(1);
- jest.advanceTimersByTime(941);
- expect(mockFunc).toHaveBeenCalledTimes(2);
- });
-
- it('Should only invoke function', () => {
- // Because we haven't invoked returned function from throttle
- // mock func should not have been called yet
- expect(mockFunc).not.toHaveBeenCalled();
- throttledMockFunc();
- expect(mockFunc).toHaveBeenCalledTimes(1);
- });
- });
-
-
-
- // test notes
- describe('getHooksNames', () => {
- it('Should return object with one getter/setter for a single useState instance', () => {
- const elementType = `function SingleUseFakeComponent() {
- const [testCount, setTestCount] = useState(0);
- const age = 20;
- return ( You clicked this {testCount} times
-
setTestCount(testCount + 1)}>+1
-
setTestCount(testCount - 1)}>-1
- You are {age} years old!
-
age + 1}>Get Older
-
-
);
- }`;
-
- expect(getHooksNames(elementType)).toEqual(['testCount', 'setTestCount']);
- });
-
- it('Should output the right number of properties when given multiple hooks', () => {
- const elementType = `function SingleUseFakeComponent() {
- const [testCount, setTestCount] = useState(0);
- const [biscuitCount, setBiscuitCount] = useState(0);
- const age = 20;
- return ( You clicked this {testCount} times
-
setTestCount(testCount + 1)}>+1
-
setTestCount(testCount - 1)}>-1
- You are {age} years old!
-
age + 1}>Get Older
-
-
);
- }`;
-
- expect(getHooksNames(elementType)).toEqual(['testCount', 'setTestCount', 'biscuitCount', 'setBiscuitCount']);
- expect(Object.keys(getHooksNames(elementType))).toHaveLength(4);
- });
-
- it('Should ignore any non-hook definitions', () => {
- const elementType = `function SingleUseFakeComponent() {
- const [testCount, setTestCount] = useState(0);
- const age = 20;
- return ( You clicked this {testCount} times
-
setTestCount(testCount + 1)}>+1
-
setTestCount(testCount - 1)}>-1
- You are {age} years old!
-
age + 1}>Get Older
-
-
);
- }`;
-
- const expectedNumHookVariables = 2;
- expect(Object.keys(getHooksNames(elementType))).toHaveLength(expectedNumHookVariables);
- });
-
- it('Should return an empty object if no hooks found', () => {
- const elementType = `function SingleUseFakeComponent() {
- const age = 20;
- return ( You clicked this {testCount} times
-
setTestCount(testCount + 1)}>+1
-
setTestCount(testCount - 1)}>-1
- You are {age} years old!
-
age + 1}>Get Older
-
-
);
- }`;
-
- expect(getHooksNames(elementType)).toEqual([]);
- });
-
- it('Should throw an error if input returns invalid JSX', () => {
- const useState = `const singleUseStateTest = () => {
- age: 20;
- return ( You are {age} years old!
- Get Older
- )
- }`;
-
- expect(getHooksNames(useState)).toEqual(['unknown']);
- });
- });
-});
diff --git a/src/backend/__tests__/ignore/IncrementClass.tsx b/src/backend/__tests__/ignore/IncrementClass.tsx
new file mode 100644
index 000000000..0d41d8975
--- /dev/null
+++ b/src/backend/__tests__/ignore/IncrementClass.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+export default class IncrementClass extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = { count: 0 };
+ this.handleClick = this.handleClick.bind(this);
+ }
+
+ handleClick() {
+ this.setState({ count: this.state.count + 1 });
+ }
+
+ render() {
+ return (
+
+
+ You clicked me {this.state.count} times.
+
+
+ );
+ }
+}
diff --git a/src/backend/__tests__/ignore/IncrementFunc.tsx b/src/backend/__tests__/ignore/IncrementFunc.tsx
new file mode 100644
index 000000000..f3a436817
--- /dev/null
+++ b/src/backend/__tests__/ignore/IncrementFunc.tsx
@@ -0,0 +1,25 @@
+import React, { useState } from 'react';
+function IncrementFunc() {
+ const [count, setCount] = useState(0);
+ return (
+
+ setCount(count + 1)}>
+ You clicked me {count} times.
+
+
+ );
+}
+
+export default IncrementFunc;
+
+export function IncrementFuncMultiStates() {
+ const [count, setCount] = useState(0);
+ const [count1, setCount1] = useState(1);
+ return (
+
+ setCount(count + 1)}>
+ You clicked me {count + count1} times
+
+
+ );
+}
diff --git a/src/backend/__tests__/ignore/deepCopy.ts b/src/backend/__tests__/ignore/deepCopy.ts
new file mode 100644
index 000000000..6ea468be9
--- /dev/null
+++ b/src/backend/__tests__/ignore/deepCopy.ts
@@ -0,0 +1,14 @@
+export default function deepCopy(obj: T): T {
+ if (obj === null || typeof obj !== 'object') {
+ return obj;
+ }
+ const copy = Array.isArray(obj) ? [] : {};
+ Object.keys(obj).forEach((key) => {
+ if (typeof obj[key] === 'function') {
+ copy[key] = obj[key];
+ } else {
+ copy[key] = deepCopy(obj[key]);
+ }
+ });
+ return copy as T;
+}
diff --git a/src/backend/__tests__/ignore/propComponent-testcase.ts b/src/backend/__tests__/ignore/propComponent-testcase.ts
new file mode 100644
index 000000000..f517eb5da
--- /dev/null
+++ b/src/backend/__tests__/ignore/propComponent-testcase.ts
@@ -0,0 +1,35 @@
+import { Fiber } from '../../types/backendTypes';
+import { FunctionComponent } from '../../types/backendTypes';
+
+// -------------------TEST CASE FOR COMPONENT WITH PROPS-----------------------
+export const Router: Fiber = {
+ tag: FunctionComponent,
+ elementType: { name: 'Router' },
+ sibling: null,
+ stateNode: null,
+ child: null,
+ memoizedState: {
+ memoizedState: null,
+ queue: null,
+ },
+ memoizedProps: { location: { pathname: '/tictactoe' } },
+ actualDuration: 1,
+ actualStartTime: 2,
+ selfBaseDuration: 3,
+ treeBaseDuration: 4,
+ _debugHookTypes: ['useContext', 'useMemo', 'useMemo'],
+};
+export const RenderedRoute: Fiber = {
+ tag: FunctionComponent,
+ elementType: { name: 'RenderedRoute' },
+ sibling: null,
+ stateNode: null,
+ child: null,
+ memoizedState: null,
+ memoizedProps: { match: { pathname: '/tictactoe' } },
+ actualDuration: 1,
+ actualStartTime: 2,
+ selfBaseDuration: 3,
+ treeBaseDuration: 4,
+ _debugHookTypes: ['useContext'],
+};
diff --git a/src/backend/__tests__/ignore/stateComponents-testcases.ts b/src/backend/__tests__/ignore/stateComponents-testcases.ts
new file mode 100644
index 000000000..401311b72
--- /dev/null
+++ b/src/backend/__tests__/ignore/stateComponents-testcases.ts
@@ -0,0 +1,177 @@
+import Tree from '../../models/tree';
+import routes from '../../models/routes';
+import { ComponentData, Fiber } from '../../types/backendTypes';
+import { FunctionComponent, ClassComponent, HostRoot } from '../../types/backendTypes';
+import IncrementFunc from './IncrementFunc';
+import IncrementClass from './IncrementClass';
+import componentActionsRecord from '../../models/masterState';
+import deepCopy from './deepCopy';
+
+// ----------------------------TEST CASES FOR ROOT------------------------------
+export const root: Fiber = {
+ tag: HostRoot,
+ elementType: null,
+ key: null,
+ sibling: null,
+ stateNode: null,
+ child: null,
+ memoizedState: null,
+ memoizedProps: null,
+ actualDuration: 1,
+ actualStartTime: 2,
+ selfBaseDuration: 3,
+ treeBaseDuration: 4,
+ _debugHookTypes: null,
+};
+export const rootPayload = new Tree('root', 'root');
+rootPayload.route = routes.addRoute('http://localhost/');
+
+// ----------------------TEST CASE FOR FUNCTIONAL COMPONENT---------------------
+export const functionalComponent: Fiber = {
+ tag: FunctionComponent,
+ elementType: IncrementFunc,
+ sibling: null,
+ stateNode: null,
+ key: null,
+ child: null,
+ memoizedState: {
+ memoizedState: 0,
+ queue: {
+ dispatch: function (newState) {
+ this.memoizedState = newState;
+ },
+ },
+ },
+ memoizedProps: {},
+ actualDuration: 1,
+ actualStartTime: 2,
+ selfBaseDuration: 3,
+ treeBaseDuration: 4,
+ _debugHookTypes: ['useState'],
+};
+
+const functionalComponentData: ComponentData = {
+ actualDuration: 1,
+ actualStartTime: 2,
+ selfBaseDuration: 3,
+ treeBaseDuration: 4,
+ key: null,
+ context: {},
+ hooksIndex: [0],
+ hooksState: { count: 0 },
+ index: null,
+ props: {},
+ state: null,
+};
+
+componentActionsRecord.clear();
+export const functionalPayload: Tree = new Tree('root', 'root');
+functionalPayload.route = rootPayload.route;
+functionalPayload.addChild({ count: 0 }, 'IncrementFunc', functionalComponentData, null);
+
+// -----------------------TEST CASE FOR CLASS COMPONENT-------------------------
+
+export const classComponent: Fiber = {
+ tag: ClassComponent,
+ elementType: IncrementClass,
+ sibling: null,
+ key: null,
+ stateNode: {
+ state: { count: 0 },
+ setState: function (callback) {
+ this.state = { ...callback() };
+ },
+ },
+ child: null,
+ memoizedState: {
+ count: 0,
+ },
+ memoizedProps: {},
+ actualDuration: 1,
+ actualStartTime: 2,
+ selfBaseDuration: 3,
+ treeBaseDuration: 4,
+ _debugHookTypes: null,
+};
+classComponent.stateNode.setState = classComponent.stateNode.setState.bind(
+ classComponent.stateNode,
+);
+
+const classComponentData: ComponentData = {
+ actualDuration: 1,
+ actualStartTime: 2,
+ selfBaseDuration: 3,
+ treeBaseDuration: 4,
+ key: null,
+ context: {},
+ hooksIndex: null,
+ hooksState: null,
+ index: 0,
+ props: {},
+ state: { count: 0 },
+};
+
+componentActionsRecord.clear();
+export const classPayload = new Tree('root', 'root');
+classPayload.route = rootPayload.route;
+classPayload.addChild({ count: 0 }, 'IncrementClass', classComponentData, null);
+
+componentActionsRecord.clear();
+export const updateClassPayload = new Tree('root', 'root');
+updateClassPayload.route = rootPayload.route;
+updateClassPayload.addChild(
+ { count: 2 },
+ 'IncrementClass',
+ { ...classComponentData, state: { count: 2 } },
+ null,
+);
+
+// -----------------------TEST CASE FOR MIX OF COMPONENTS-----------------------
+componentActionsRecord.clear();
+export const mixComponents: Fiber = deepCopy(root);
+mixComponents.child = deepCopy(functionalComponent);
+mixComponents.sibling = deepCopy(classComponent);
+mixComponents.child!.child = deepCopy(functionalComponent);
+mixComponents.child!.child!.sibling = deepCopy(classComponent);
+// console.dir(mixComponents, { depth: null });
+
+export const mixPayload = new Tree('root', 'root');
+mixPayload.route = rootPayload.route;
+
+// Outer Func Comp
+let funcPayloadMix = new Tree({ count: 0 }, 'IncrementFunc1', functionalComponentData, null);
+funcPayloadMix.componentData = {
+ ...funcPayloadMix.componentData,
+ hooksState: { count: 0 },
+ hooksIndex: [0],
+};
+mixPayload.children.push(deepCopy(funcPayloadMix));
+
+// Outer Class Comp
+let classPayloadMix = new Tree({ count: 0 }, 'IncrementClass', classComponentData, null);
+classPayloadMix.componentData = {
+ ...classPayloadMix.componentData,
+ state: { count: 0 },
+ index: 3,
+};
+mixPayload.children.push(deepCopy(classPayloadMix));
+
+// Inner Func Comp
+funcPayloadMix = new Tree({ count: 0 }, 'IncrementFunc2', functionalComponentData, null);
+funcPayloadMix.componentData = {
+ ...funcPayloadMix.componentData,
+ hooksState: { count: 0 },
+ hooksIndex: [1],
+};
+mixPayload.children[0].children.push(deepCopy(funcPayloadMix));
+
+// Inner Class Comp
+classPayloadMix = new Tree({ count: 0 }, 'IncrementClass', classComponentData, null);
+classPayloadMix.componentData = {
+ ...classPayloadMix.componentData,
+ state: { count: 0 },
+ index: 2,
+};
+mixPayload.children[0].children.push(deepCopy(classPayloadMix));
+
+// console.dir(mixPayload, { depth: null });
diff --git a/src/backend/__tests__/index.html b/src/backend/__tests__/index.html
index fb22c16dd..3bcdac167 100644
--- a/src/backend/__tests__/index.html
+++ b/src/backend/__tests__/index.html
@@ -1,11 +1,11 @@
-
-
-
- Testing LinkFiber
-
-
-
-
-
\ No newline at end of file
+
+
+
+ Testing LinkFiber
+
+
+
+
+
diff --git a/src/backend/__tests__/linkFiber.test.ts b/src/backend/__tests__/linkFiber.test.ts
new file mode 100644
index 000000000..f2dcf7028
--- /dev/null
+++ b/src/backend/__tests__/linkFiber.test.ts
@@ -0,0 +1,311 @@
+/**
+ * @jest-environment node
+ */
+import linkFiberInitialization from '../routers/linkFiber';
+import timeJumpInitialization from '../controllers/timeJump';
+import componentActionsRecord from '../models/masterState';
+import {
+ root,
+ rootPayload,
+ classComponent,
+ classPayload,
+ updateClassPayload,
+ functionalComponent,
+ functionalPayload,
+ mixComponents,
+ mixPayload,
+} from './ignore/stateComponents-testcases';
+import { Status, FiberRoot } from '../types/backendTypes';
+import Tree from '../models/tree';
+import { DevTools } from '../types/linkFiberTypes';
+import { JSDOM } from 'jsdom';
+import path from 'path';
+import fs from 'fs';
+
+describe('linkFiber', () => {
+ let mode: Status;
+ let linkFiber: () => Promise;
+ let linkFiberDelayed: (resolve: any) => NodeJS.Timeout;
+ let timeJump: (targetSnapshot: Tree) => Promise;
+ let fiberRoot: FiberRoot;
+ let devTools: DevTools;
+ let onCommitFiberRootDelayed: (resolve: any) => NodeJS.Timeout;
+ const DELAY = 75; //ms
+ const mockPostMessage = jest.fn();
+ let dom: JSDOM;
+
+ beforeAll(() => {
+ // Set up a fake DOM environment with JSDOM
+ const indexHTML = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf-8');
+ dom = new JSDOM(indexHTML, { url: 'http://localhost' });
+ global.window = dom.window as unknown as Window & typeof globalThis;
+ global.document = dom.window._document;
+ });
+
+ afterAll(() => {
+ // Clean up the fake DOM environment
+ dom.window.close();
+ });
+
+ beforeEach(() => {
+ mode = {
+ jumping: false,
+ };
+ // Initialize Fiber Root:
+ fiberRoot = { current: root };
+
+ // Initialize linkFiber
+ linkFiber = linkFiberInitialization(mode);
+ // Since linkFiber invoke a throttle function that get delay for 70 ms, between each test, linkFiber need to be delayed for 75 ms to ensure no overlapping async calls.
+ linkFiberDelayed = (resolve) => setTimeout(async () => resolve(await linkFiber()), DELAY);
+
+ // Initialize timeJump
+ timeJump = timeJumpInitialization(mode);
+
+ // Set up mock postMessage function
+ window.postMessage = mockPostMessage;
+
+ // Set up mock React DevTools global hook
+ window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
+ renderers: new Map<1, { version: string }>([[1, { version: '16' }]]),
+ onCommitFiberRoot: (renderID = 0, root = fiberRoot, priortyLevel) => {},
+ getFiberRoots: (renderID = 0) => new Set([fiberRoot]),
+ };
+ devTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
+ // Since onCommitFiberRoot invoke a throttle function that get delay for 70 ms, between each test, onCommitFiberRoot need to be delayed for 75 ms to ensure no overlapping async calls.
+ onCommitFiberRootDelayed = (resolve) =>
+ setTimeout(
+ async () => resolve(await devTools.onCommitFiberRoot(0, fiberRoot, 'high')),
+ DELAY,
+ );
+ });
+
+ afterEach(() => {
+ jest.clearAllMocks();
+ // Clear the compoennt action record
+ componentActionsRecord.clear();
+ delete window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
+ });
+
+ describe('link fiber initiliaztion', () => {
+ it('link fiber should return a function', () => {
+ expect(typeof linkFiber).toBe('function');
+ });
+ it('returned function should not throw an error', async () => {
+ await expect(new Promise(linkFiberDelayed)).resolves.not.toThrowError();
+ });
+ });
+
+ describe('React dev tools and react app check', () => {
+ it('should not do anything if React Devtools is not installed', async () => {
+ delete window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
+ await expect(new Promise(linkFiberDelayed)).resolves.not.toThrowError();
+ expect(mockPostMessage).not.toHaveBeenCalled();
+ });
+
+ it('should post a message to front end that React DevTools is installed', async () => {
+ await new Promise(linkFiberDelayed);
+ expect(mockPostMessage).toHaveBeenCalled();
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'devToolsInstalled',
+ payload: 'devToolsInstalled',
+ },
+ '*',
+ );
+ });
+
+ it('should post a message & send snapshot to the front end if the target application is a React App', async () => {
+ await new Promise(linkFiberDelayed);
+
+ expect(mockPostMessage).toHaveBeenCalledTimes(3);
+ // Post message for devTool Installed
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'devToolsInstalled',
+ payload: 'devToolsInstalled',
+ },
+ '*',
+ );
+
+ // Post message for target is a react app
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'aReactApp',
+ payload: 'aReactApp',
+ },
+ '*',
+ );
+ // Post message to send a snapshot of react app to front end
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: rootPayload,
+ },
+ '*',
+ );
+ });
+
+ it('should not do anything if the target application is not a React App', async () => {
+ (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers = new Map();
+ await new Promise(linkFiberDelayed);
+ expect(mockPostMessage).toHaveBeenCalledTimes(1);
+ expect(mockPostMessage).not.toHaveBeenCalledTimes(3);
+ });
+ });
+
+ describe('document visibility', () => {
+ it('should initiate an event listener for visibility change', async () => {
+ const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
+ await new Promise(linkFiberDelayed);
+ expect(addEventListenerSpy).toHaveBeenCalledWith('visibilitychange', expect.any(Function));
+ });
+ it('should not send snapshot when document is hidden', async () => {
+ // Initialize linkFiber:
+ await new Promise(linkFiberDelayed);
+ expect(mockPostMessage).toHaveBeenCalledTimes(3);
+ // Simulate document hidden
+ Object.defineProperty(document, 'hidden', { value: true });
+ const visibilityChangeEvent = new window.Event('visibilitychange');
+ document.dispatchEvent(visibilityChangeEvent);
+ // Reset count of mockPostMessage
+ mockPostMessage.mockClear();
+ await new Promise(onCommitFiberRootDelayed);
+ // If document hidden, no message/snapshot will be posted
+ expect(mockPostMessage).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('addOneMoreStep', () => {
+ it('should monkey patch on onCommitFiberRoot', async () => {
+ // Obtain the original onCommitFiberRoot
+ const orginalOnCommitFiberRoot =
+ window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.onCommitFiberRoot.toString();
+ await new Promise(linkFiberDelayed);
+ // Obtain the monkey patch (modified) onCommitFiberRoot
+ const monkeyPatchOnCommitFiberRoot =
+ window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.onCommitFiberRoot.toString();
+ // The onCommitFiberRoot method should be been modifed
+ expect(orginalOnCommitFiberRoot).not.toEqual(monkeyPatchOnCommitFiberRoot);
+ });
+
+ it('should send a snapshot when new fiberRoot is committed for a class component', async () => {
+ // When first initialize linkFiber, should send snapShot of rootPayload
+ await new Promise(linkFiberDelayed);
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: rootPayload,
+ },
+ '*',
+ );
+ mockPostMessage.mockClear();
+ // After modified fiberRoot to classComponent, onCommitFiberRoot should send snapSot of classPayload
+ fiberRoot = { current: classComponent };
+ await new Promise(onCommitFiberRootDelayed);
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: classPayload,
+ },
+ '*',
+ );
+ });
+
+ it('should send a snapshot when new fiberRoot is committed for a functional component', async () => {
+ // When first initialize linkFiber, should send snapShot of rootPayload
+ await new Promise(linkFiberDelayed);
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: rootPayload,
+ },
+ '*',
+ );
+ mockPostMessage.mockClear();
+
+ // After modified fiberRoot to functionalComponent, onCommitFiberRoot should send snapSot of functionalPayload
+ fiberRoot = { current: functionalComponent };
+ await new Promise(onCommitFiberRootDelayed);
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: functionalPayload,
+ },
+ '*',
+ );
+ });
+
+ it('should send a snapshot when new fiberRoot is commited for mixture of components', async () => {
+ // When first initialize linkFiber, should send snapShot of rootPayload
+ await new Promise(linkFiberDelayed);
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: rootPayload,
+ },
+ '*',
+ );
+ mockPostMessage.mockClear();
+
+ // After modified fiberRoot to mixComponents, onCommitFiberRoot should send snapSot of mixPayload
+ fiberRoot = { current: mixComponents };
+ await new Promise(onCommitFiberRootDelayed);
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: mixPayload,
+ },
+ '*',
+ );
+ });
+ });
+
+ describe('mode unit tests', () => {
+ it('should not send snapshot if mode is jumping & not navigating', async () => {
+ // When first initialize linkFiber, should not have the update class payload
+ fiberRoot = { current: classComponent };
+ await new Promise(linkFiberDelayed);
+ mockPostMessage.mockClear();
+
+ // Simulate jumping and navigating
+ mode.jumping = true;
+ await new Promise(onCommitFiberRootDelayed);
+ // During jumping &/or navigating, should not post any message/snapshot to front end
+ expect(mockPostMessage).not.toHaveBeenCalled();
+ });
+
+ it('should update react fiber tree based on the payload from frontend when mode is navigating', async () => {
+ // When first initialize linkFiber, should not have the update class payload
+ fiberRoot = { current: classComponent };
+ await new Promise(linkFiberDelayed);
+ expect(mockPostMessage).not.toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: updateClassPayload,
+ },
+ '*',
+ );
+ mockPostMessage.mockClear();
+
+ // Simulate jumping and navigating
+ mode.jumping = true;
+ mode.navigating = () => timeJump(updateClassPayload);
+ await new Promise(onCommitFiberRootDelayed);
+ // During jumping &/or navigating, should not post any message/snapshot to front end
+ expect(mockPostMessage).not.toHaveBeenCalled();
+
+ // After navigate, react application should have updateClassPayload
+ mode.jumping = false;
+ await new Promise(onCommitFiberRootDelayed);
+ expect(mockPostMessage).toHaveBeenCalledTimes(1);
+ expect(mockPostMessage).toHaveBeenCalledWith(
+ {
+ action: 'recordSnap',
+ payload: updateClassPayload,
+ },
+ '*',
+ );
+ });
+ });
+});
diff --git a/src/backend/__tests__/linkFiber.test.tsx b/src/backend/__tests__/linkFiber.test.tsx
deleted file mode 100644
index a042b5981..000000000
--- a/src/backend/__tests__/linkFiber.test.tsx
+++ /dev/null
@@ -1,98 +0,0 @@
-/* eslint-disable jest/no-disabled-tests */
-/* eslint-disable react/state-in-constructor */
-/* eslint-disable lines-between-class-members */
-/* eslint-disable @typescript-eslint/no-unused-vars */
-/* eslint-disable @typescript-eslint/no-var-requires */
-/* eslint-disable import/order */
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable react/jsx-filename-extension */
-import { string } from 'prop-types';
-import React, { useState } from 'react';
-import { render } from 'react-dom';
-import linkFiberStart from '../linkFiber';
-
-const puppeteer = require('puppeteer');
-const SERVER = require('../puppeteerServer');
-
-// Apple uses port 5000 for Air Play.
-const APP = 'http://localhost:5001';
-
-let linkFiber;
-let mode;
-let snapShot;
-
-let browser;
-let page;
-
-interface fooState {
- foo: string,
- setFoo?: (string) => void
-}
-function App(): JSX.Element {
- const [fooState, setFooState] = useState({
- foo: 'bar',
- });
- return (
- {fooState}
- );
-}
-
-xdescribe('unit test for linkFiber', () => {
- beforeAll(async () => {
- await SERVER;
- const args = puppeteer.defaultArgs().filter(arg => String(arg).toLowerCase() !== '--disable-extensions');
- browser = await puppeteer.launch({
- args: args.concat(['--no-sandbox', '--disable-setuid-sandbox',
- '---extensions-on-chrome-urls',
- '--whitelisted-extension-id=fmkadmapgofadopljbjfkapdkoienihi',
- '--whitelisted-extension-id=hilpbahfbckghckaiafiiinjkeagmfhn',
- '--load-extension=/mnt/d/Libraries/Documents/codeRepos/reactime/src/extension/build']),
- devtools: true,
- ignoreDefaultArgs: true,
- });
-
- const c = await puppeteer.connect({
- browserWSEndpoint: browser.wsEndpoint(),
- ignoreHTTPSErrors: false,
- });
-
- page = await browser.newPage();
- });
-
- afterAll(async () => {
- await SERVER.close();
-
- await browser.close();
- });
-
- beforeEach(() => {
- snapShot = { tree: null };
- mode = {
- jumping: false,
- paused: false,
- };
- linkFiber = linkFiberStart(snapShot, mode);
-
- page.waitForFunction(async lf => {
- const container = document.createElement('div');
- render( , container);
- lf(container);
- }, {}, linkFiber);
- });
-
- test('type of tree should be an object', () => {
- expect(typeof snapShot.tree).toBe('object');
- });
-
- test.skip('linkFiber should mutate the snapshot tree property', () => {
- expect(snapShot.tree.state).toBe('root');
- expect(snapShot.tree.children).toHaveLength(1);
- expect(snapShot.tree.children[0].component.state.foo).toBe('bar');
- });
-
- test.skip('linkFiber should modify the setState of the stateful component', () => {
- expect(snapShot.tree.children[0].component.setState.linkFiberChanged).toBe(true);
- });
-});
-
-SERVER.close();
diff --git a/src/backend/__tests__/masterState.test.ts b/src/backend/__tests__/masterState.test.ts
index 848df4a37..2bc1c7a59 100644
--- a/src/backend/__tests__/masterState.test.ts
+++ b/src/backend/__tests__/masterState.test.ts
@@ -1,61 +1,84 @@
-import masterState from '../masterState';
-import {
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- HookStateItem,
- HookStates,
-} from '../types/backendTypes';
-
-describe('Testing masterState functionality', () => {
- const hookOne : HookStateItem = { state: 'A', component: 'counter1' };
- const hookTwo : HookStateItem = { state: 'B', component: 'counter2' };
- const hookThree : HookStateItem = { state: 'C', component: 'counter3' };
- const allHooks : HookStates = [hookOne, hookTwo];
-
- describe('saveNew', () => {
- it('Should return the index of the saved component', () => {
- expect(masterState.saveNew(hookOne.state, hookOne.component)).toBe(0);
- expect(masterState.saveNew(hookTwo.state, hookTwo.component)).toBe(1);
- });
- });
+import componentActionRecord from '../models/masterState';
- describe('getComponentByIndex', () => {
- it('Should return the component when given a valid index', () => {
- expect(masterState.getComponentByIndex(0)).toEqual(hookOne.component);
- expect(masterState.getComponentByIndex(1)).toEqual(hookTwo.component);
+describe('Master State unit tests', () => {
+ describe('componentActionRecord unit tests', () => {
+ const component1 = { state: 'dummy state', props: {} };
+ const component2 = { state: 'dummy state2', props: {} };
+ const component3 = { state: 'dummy state3', props: {} };
+ let index1, index2, index3;
+ beforeEach(() => {
+ componentActionRecord.clear();
+ index1 = componentActionRecord.saveNew(component1);
+ index2 = componentActionRecord.saveNew(component2);
+ index3 = componentActionRecord.saveNew(component3);
});
- it('Should return undefined when given an invalid index', () => {
- expect(masterState.getComponentByIndex(2)).toBe(undefined);
- });
- });
- describe('getRecordByIndex', () => {
- it('Should return the record when given a valid index', () => {
- expect(masterState.getRecordByIndex(0)).toEqual(hookOne);
- expect(masterState.getRecordByIndex(1)).toEqual(hookTwo);
- });
- it('Should return undefined when given an invalid index', () => {
- expect(masterState.getRecordByIndex(2)).toBe(undefined);
- });
- });
+ describe('clear', () => {
+ it('should clear componentActionsRecord', () => {
+ componentActionRecord.saveNew(component1);
+ componentActionRecord.clear();
+ expect(componentActionRecord.getAllComponents()).toEqual([]);
- describe('getComponentByIndexHooks', () => {
- it('Should return an array of components when given an a valid array of indices', () => {
- expect(masterState.getComponentByIndexHooks([0, 1])).toEqual([hookOne.component, hookTwo.component]);
+ componentActionRecord.saveNew(component2);
+ componentActionRecord.saveNew(component3);
+ componentActionRecord.clear();
+ expect(componentActionRecord.getAllComponents()).toEqual([]);
+ });
});
- it('Should return an empty array when given an invalid array of indices', () => {
- expect(masterState.getComponentByIndexHooks([2])).toEqual([]);
+
+ describe('saveNew', () => {
+ it('should add a new component to componentActionRecord and return its index', () => {
+ expect(index1).toEqual(0);
+ expect(index2).toEqual(1);
+ expect(index3).toEqual(2);
+
+ expect(componentActionRecord.getAllComponents()).toHaveLength(3);
+
+ expect(componentActionRecord.getAllComponents()[index1]).toBe(component1);
+ expect(componentActionRecord.getAllComponents()[index2]).toBe(component2);
+ expect(componentActionRecord.getAllComponents()[index3]).toBe(component3);
+ });
});
- });
- describe('clear', () => {
- it('Should return undefined', () => {
- expect(masterState.clear()).toBe(undefined);
+ describe('getComponentByIndex', () => {
+ it('should return the component at the specified index', () => {
+ expect(componentActionRecord.getComponentByIndex(index1)).toBe(component1);
+ expect(componentActionRecord.getComponentByIndex(index2)).toBe(component2);
+ expect(componentActionRecord.getComponentByIndex(index3)).toBe(component3);
+ });
+
+ it('should return undefined when passed an index that does not exist', () => {
+ expect(componentActionRecord.getComponentByIndex(3)).toBeUndefined();
+ });
});
- it('Should reset the componentActionRecord index', () => {
- expect(masterState.saveNew(hookThree.state, hookThree.component)).toBe(0);
+
+ describe('getComponentByIndexHooks', () => {
+ it('should return the components at the specified indices', () => {
+ expect(componentActionRecord.getComponentByIndexHooks([index1])).toContain(component1);
+ expect(componentActionRecord.getComponentByIndexHooks([0, 1, 2])).toEqual([
+ component1,
+ component2,
+ component3,
+ ]);
+ });
+
+ it('should return undefined when passed an empty array', () => {
+ expect(componentActionRecord.getComponentByIndexHooks([])).toEqual([]);
+ });
+
+ it('should return undefined when passed an index that does not exist', () => {
+ expect(componentActionRecord.getComponentByIndexHooks([3])).toEqual([]);
+ });
});
- it('Should empty the componentActionRecord array', () => {
- expect(masterState.getComponentByIndex(0)).toEqual(hookThree.component);
+
+ describe('getAllComponents', () => {
+ it('should return all components in componentActionRecord', () => {
+ expect(componentActionRecord.getAllComponents()).toEqual([
+ component1,
+ component2,
+ component3,
+ ]);
+ });
});
});
});
diff --git a/src/backend/__tests__/masterTree.test.tsx b/src/backend/__tests__/masterTree.test.tsx
new file mode 100644
index 000000000..5b3d404f1
--- /dev/null
+++ b/src/backend/__tests__/masterTree.test.tsx
@@ -0,0 +1,608 @@
+import createTree from '../controllers/createTree';
+import componentActionsRecord from '../models/masterState';
+import createComponentActionsRecord from '../controllers/createComponentActionsRecord';
+import {
+ Fiber,
+ FunctionComponent,
+ ClassComponent,
+ IndeterminateComponent,
+ ComponentData,
+ WorkTag,
+} from '../types/backendTypes';
+import { IncrementFuncMultiStates } from './ignore/IncrementFunc';
+import Tree from '../models/tree';
+import {
+ root,
+ functionalComponent,
+ functionalPayload,
+ classComponent,
+ classPayload,
+} from './ignore/stateComponents-testcases';
+
+import { serializeState } from '../models/tree';
+import {
+ allowedComponentTypes,
+ nextJSDefaultComponent,
+ remixDefaultComponents,
+ exclude,
+} from '../models/filterConditions';
+import deepCopy from './ignore/deepCopy';
+import { Children } from 'react';
+import _ from 'lodash';
+
+describe('master tree tests', () => {
+ let treeRoot: Tree;
+ let mockFiberNode: Fiber;
+ const mockComponentData: ComponentData = {
+ actualDuration: 1,
+ actualStartTime: 2,
+ selfBaseDuration: 3,
+ treeBaseDuration: 4,
+ key: null,
+ context: {},
+ hooksIndex: null,
+ hooksState: null,
+ index: null,
+ props: {},
+ state: null,
+ };
+ let mockFiberTree: Tree;
+ /** `mockChildNode` is a CLASS COMPONENT*/
+ let mockChildNode: Fiber;
+ let mockChildTree: Tree;
+
+ /** `mockSibilingNode` is a FUNCTIONAL COMPONENT*/
+ let mockSiblingNode: Fiber;
+ let mockSiblingTree: Tree;
+
+ beforeEach(() => {
+ // create tree root:
+ treeRoot = new Tree('root', 'root');
+ // create a mock Fiber node with relevant properties
+ mockFiberNode = { ...root, tag: IndeterminateComponent };
+ mockFiberTree = new Tree('root', 'root');
+ mockFiberTree.addChild('stateless', 'nameless', mockComponentData, null);
+
+ // create a mock child Fiber node with relevant properties for class component
+ mockChildNode = deepCopy(classComponent);
+ // Since payload will have a root then the component, need to extract the child component
+ mockChildTree = deepCopy(classPayload.children[0]);
+
+ // create a mock sibling Fiber node with relevant properties for class component
+ mockSiblingNode = deepCopy(functionalComponent);
+ // Since payload will have a root then the component, need to extract the child component
+ mockSiblingTree = deepCopy(functionalPayload.children[0]);
+
+ // clear the saved component actions record
+ componentActionsRecord.clear();
+ });
+
+ describe('createTree Unit test', () => {
+ describe('Filter components that are from NextJS, Remix or not from allowed component types', () => {
+ it('should return a Tree if we pass in a empty fiber node', () => {
+ const tree = createTree(mockFiberNode);
+ expect(tree).toEqual(mockFiberTree);
+ });
+
+ it('should filter out NextJS default components with no children or siblings', () => {
+ for (let name of nextJSDefaultComponent) {
+ mockFiberNode.elementType = { name };
+ const tree = createTree(mockFiberNode);
+ expect(tree).toEqual(treeRoot);
+ expect(tree).not.toEqual(mockFiberTree);
+ }
+ });
+ it('should filter out remix default components with no children or siblings', () => {
+ for (let name of remixDefaultComponents) {
+ mockFiberNode.elementType = { name };
+ const tree = createTree(mockFiberNode);
+ expect(tree).toEqual(treeRoot);
+ expect(tree).not.toEqual(mockFiberTree);
+ }
+ });
+
+ it('should only traverse allowed components', () => {
+ for (let tag: any = 1; tag <= 24; tag++) {
+ mockFiberNode.tag = tag;
+ const tree = createTree(mockFiberNode);
+ if (allowedComponentTypes.has(tag)) {
+ expect(tree).toEqual(mockFiberTree);
+ } else {
+ expect(tree).toEqual(treeRoot);
+ }
+ }
+ });
+ it('should filter out NextJS & Remix default components with children and/or siblings', () => {
+ (mockChildTree.componentData as ComponentData).index = 0;
+ (mockSiblingTree.componentData as ComponentData).hooksIndex = [1];
+ treeRoot.children.push(mockChildTree);
+ treeRoot.children.push(mockSiblingTree);
+ for (let name of nextJSDefaultComponent) {
+ componentActionsRecord.clear(); // reset index counts for component actions
+ mockFiberNode.elementType = { name };
+ mockFiberNode.child = mockChildNode;
+ mockFiberNode.sibling = mockSiblingNode;
+ const tree = createTree(mockFiberNode);
+ const children = tree.children;
+ expect(children.length).toEqual(2);
+ expect(children[0]).toEqual(mockChildTree);
+ expect(children[1]).toEqual(mockSiblingTree);
+ expect(tree).toEqual(treeRoot);
+ }
+ for (let name of remixDefaultComponents) {
+ componentActionsRecord.clear(); // reset index counts for component actions
+ mockFiberNode.elementType = { name };
+ mockFiberNode.child = mockChildNode;
+ mockFiberNode.sibling = mockSiblingNode;
+ const tree = createTree(mockFiberNode);
+ const children = tree.children;
+ expect(children.length).toEqual(2);
+ expect(children[0]).toEqual(mockChildTree);
+ expect(children[1]).toEqual(mockSiblingTree);
+ expect(tree).toEqual(treeRoot);
+ }
+ });
+ });
+ describe('Display component props information', () => {
+ const memoizedProps = {
+ propVal: 0,
+ propFunc: jest.fn,
+ propObj: { dummy: 'dummy' },
+ };
+ const props = {
+ propVal: 0,
+ propFunc: 'function',
+ propObj: JSON.stringify({ dummy: 'dummy' }),
+ };
+ it('should display functional props information', () => {
+ mockChildNode.memoizedProps = memoizedProps;
+ (mockChildTree.componentData as ComponentData).props = props;
+ treeRoot.children.push(mockChildTree);
+
+ const tree = createTree(mockChildNode);
+ expect(tree).toEqual(treeRoot);
+ });
+ it('should display class props information', () => {
+ // Assign mock properties to the child node
+ mockChildNode.memoizedProps = memoizedProps;
+ (mockChildTree.componentData as ComponentData).props = props;
+
+ // Set up an isolated copy of the root tree
+ const isolatedTreeRoot = deepCopy(treeRoot);
+ isolatedTreeRoot.children.push(mockChildTree);
+
+ // Generate the tree
+ const tree = createTree(mockChildNode);
+
+ // Debugging: Log actual and expected tree for comparison
+ console.log('Generated Tree:', JSON.stringify(tree, null, 2));
+ console.log('Expected Tree:', JSON.stringify(isolatedTreeRoot, null, 2));
+
+ // Perform the assertion
+ expect(tree).toEqual(isolatedTreeRoot);
+ });
+
+ it('should display React router props information', () => {
+ (mockSiblingTree.componentData as ComponentData) = {
+ ...(mockSiblingTree.componentData as ComponentData),
+ props: { pathname: '/tictactoe' },
+ hooksIndex: null,
+ hooksState: null,
+ };
+ mockSiblingTree.state = 'stateless';
+
+ // For components in react router, there are different way to extract pathname prop
+ const reactRouterProp = {
+ Router: { location: { pathname: '/tictactoe' } },
+ RenderedRoute: { match: { pathname: '/tictactoe' } },
+ };
+
+ for (const componentName in reactRouterProp) {
+ // Router Component
+ mockSiblingNode.memoizedProps = {
+ ...memoizedProps,
+ ...reactRouterProp[componentName],
+ };
+ mockSiblingNode.elementType = { name: componentName };
+ mockSiblingTree.name = componentName;
+ treeRoot.children = [mockSiblingTree];
+
+ const routerTree = createTree(mockSiblingNode);
+ expect(routerTree).toEqual(treeRoot);
+ }
+ });
+ it('should exclude reserved props name', () => {
+ (mockChildTree.componentData as ComponentData).props = props;
+ treeRoot.children.push(mockChildTree);
+
+ for (let propName of exclude) {
+ componentActionsRecord.clear(); // reset index counts for component actions
+ mockChildNode.memoizedProps = { ...memoizedProps, [propName]: 'anything' };
+ const tree = createTree(mockChildNode);
+ expect(tree).toEqual(treeRoot);
+ }
+ });
+ it('should skip circular props', () => {
+ mockChildNode.memoizedProps = {
+ ...memoizedProps,
+ cir: mockChildNode,
+ noCir: 'Not a circular props',
+ };
+ (mockChildTree.componentData as ComponentData).props = {
+ ...props,
+ noCir: 'Not a circular props',
+ };
+ treeRoot.children.push(mockChildTree);
+
+ const tree = createTree(mockChildNode);
+ expect(tree).toEqual(treeRoot);
+ });
+
+ it('should display props information of multiple components', () => {
+ // Set up Fiber Node tree (root => child1 => child2 & sibling1)
+ mockChildNode.memoizedProps = memoizedProps;
+ const child1 = deepCopy(mockChildNode);
+ child1.memoizedProps.name = 'child1';
+ const child2 = deepCopy(mockChildNode);
+ child2.memoizedProps.name = 'child2';
+ mockSiblingNode.memoizedProps = memoizedProps;
+ const sibling1 = deepCopy(mockSiblingNode);
+ sibling1.memoizedProps.name = 'sibling1';
+
+ // Link nodes
+ mockFiberNode.child = child1;
+ child1.child = child2;
+ child2.sibling = sibling1;
+
+ // Set up expected tree structure
+ const isolatedMockFiberTree = deepCopy(mockFiberTree);
+ (mockChildTree.componentData as ComponentData).props = props;
+
+ const childTree1 = deepCopy(mockChildTree);
+ childTree1.name = 'IncrementClass1';
+ (childTree1.componentData as ComponentData).props.name = 'child1';
+ (childTree1.componentData as ComponentData).index = 0;
+
+ const childTree2 = deepCopy(mockChildTree);
+ childTree2.name = 'IncrementClass2';
+ (childTree2.componentData as ComponentData).props.name = 'child2';
+ (childTree2.componentData as ComponentData).index = 1;
+
+ const siblingTree1 = deepCopy(mockSiblingTree);
+ siblingTree1.name = 'IncrementFunc';
+ (siblingTree1.componentData as ComponentData).props.name = 'sibling1';
+ (siblingTree1.componentData as ComponentData).hooksIndex = [2];
+
+ isolatedMockFiberTree.children[0].children = [childTree1];
+ childTree1.children.push(childTree2, siblingTree1);
+
+ // Generate the actual tree
+ const tree = createTree(mockFiberNode);
+
+ // Assertions
+ expect(tree).toEqual(isolatedMockFiberTree);
+ });
+ });
+ describe('Display component states information', () => {
+ const stateNode = {
+ state: {
+ propVal: 0,
+ propObj: { dummy: 'dummy' },
+ },
+ setState: function (cb: Function) {
+ this.state = cb();
+ }.bind(this),
+ };
+ const classState = stateNode.state;
+
+ const memoizedState = {
+ memoizedState: { dummy: 'dummy' },
+ next: null,
+ queue: {
+ dispatch: function (newState) {
+ this.memoizedState = newState;
+ }.bind(this),
+ },
+ };
+ const memoizedState2 = {
+ memoizedState: { dummy2: 'dummy2' },
+ next: null,
+ queue: {
+ dispatch: function (newState) {
+ this.memoizedState = newState;
+ }.bind(this),
+ },
+ };
+ // Note: the key count is the variable state name within the incrementFunction that is assigned to mockSiblingTree
+ const functionalState = { count: memoizedState.memoizedState };
+ const functionalState2 = { count1: memoizedState2.memoizedState };
+ it('should display stateless if functional state empty', () => {
+ // Construct Fiber Node (root => childNode)
+ mockChildNode.stateNode = null;
+ const tree = createTree(mockChildNode);
+
+ // Construct Result Tree (root => childTree)
+ mockChildTree.state = 'stateless';
+ (mockChildTree.componentData as ComponentData).state = null;
+ (mockChildTree.componentData as ComponentData).index = null;
+ treeRoot.children.push(mockChildTree);
+
+ // Compare the two trees:
+ expect(tree).toEqual(treeRoot);
+ });
+
+ it('should display functional state information', () => {
+ // Set up mock Fiber node for functional state
+ mockSiblingNode.memoizedState = {
+ memoizedState: { dummy: 'dummy' },
+ queue: {}, // Required for useState hooks
+ next: null,
+ };
+
+ // Generate the tree
+ const tree = createTree(mockSiblingNode);
+
+ // Set up expected tree structure
+ mockSiblingTree.state = functionalState;
+ (mockSiblingTree.componentData as ComponentData).hooksState = functionalState;
+ (mockSiblingTree.componentData as ComponentData).hooksIndex = [0];
+ treeRoot.children.push(mockSiblingTree);
+
+ // Assertions
+ expect(tree).toBe(treeRoot);
+ });
+
+ it('should keep track of class state index', () => {
+ // Construct Fiber Node (root => FiberNode => child1 => child 2 & 3)
+ mockChildNode.stateNode = stateNode;
+ const child1 = deepCopy(mockChildNode);
+ const child2 = deepCopy(mockChildNode);
+ const child3 = deepCopy(mockChildNode);
+ mockFiberNode.child = child1;
+ child1.child = child2;
+ child2.sibling = child3;
+ const tree = createTree(mockFiberNode);
+
+ // Construct result tree (root => FiberTree => childTree1 => childTree2 & childTree3)
+ (mockChildTree.componentData as ComponentData).state = classState;
+ mockChildTree.state = classState;
+ const childTree1 = deepCopy(mockChildTree);
+ childTree1.name = 'IncrementClass1';
+ (childTree1.componentData as ComponentData).index = 0;
+ const childTree2 = deepCopy(mockChildTree);
+ childTree2.name = 'IncrementClass2';
+ (childTree2.componentData as ComponentData).index = 1;
+ const childTree3 = deepCopy(mockChildTree);
+ childTree3.name = 'IncrementClass3';
+ (childTree3.componentData as ComponentData).index = 2;
+ mockFiberTree.children[0].children = [childTree1];
+ childTree1.children.push(childTree2, childTree3);
+
+ // Compare the two trees:
+ expect(tree).toEqual(mockFiberTree);
+ });
+
+ it('should display stateless if functional state empty', () => {
+ // Construct Fiber Node (root => siblingNode)
+ mockSiblingNode.memoizedState = null;
+ const tree = createTree(mockSiblingNode);
+ // Construct Result Tree (root => siblingTree)
+
+ mockSiblingTree.state = 'stateless';
+ (mockSiblingTree.componentData as ComponentData).hooksState = null;
+ (mockSiblingTree.componentData as ComponentData).hooksIndex = null;
+ treeRoot.children.push(mockSiblingTree);
+
+ // Compare the two trees:
+ expect(tree).toEqual(treeRoot);
+ });
+
+ it('should display functional state information', () => {
+ // Set up mock Fiber node for functional state
+ mockSiblingNode.memoizedState = {
+ memoizedState: { dummy: 'dummy' },
+ queue: {}, // Required for useState hooks
+ next: null,
+ };
+
+ // Create tree
+ const tree = createTree(mockSiblingNode);
+
+ // Set up expected tree structure
+ mockSiblingTree.state = functionalState;
+ (mockSiblingTree.componentData as ComponentData).hooksState = functionalState;
+ (mockSiblingTree.componentData as ComponentData).hooksIndex = [0]; // Single hook index
+ mockSiblingTree.name = 'IncrementFunc'; // Ensure name matches
+ treeRoot.children.push(mockSiblingTree);
+
+ // Compare the actual tree with the expected tree
+ expect(tree).toEqual(treeRoot);
+ });
+
+ it('should keep track of functional state index', () => {
+ // Construct Fiber Node (root => FiberNode => sibling1 => sibling 2 & 3)
+ // sibling 3 will have 2 states
+ mockSiblingNode.memoizedState = memoizedState;
+ const sibling1 = deepCopy(mockSiblingNode);
+ const sibling2 = deepCopy(mockSiblingNode);
+ const sibling3 = deepCopy(mockSiblingNode);
+ sibling3.memoizedState.next = memoizedState2;
+ sibling3.elementType = IncrementFuncMultiStates;
+ mockFiberNode.child = sibling1;
+ sibling1.child = sibling2;
+ sibling2.sibling = sibling3;
+ const tree = createTree(mockFiberNode);
+
+ // Construct result tree (root => FiberTree => siblingTree1 => siblingTree2 & siblingTree3)
+ // sibling 3 will have 2 states
+ mockSiblingTree.state = functionalState;
+ (mockSiblingTree.componentData as ComponentData).hooksState = functionalState;
+ const siblingTree1 = deepCopy(mockSiblingTree);
+ siblingTree1.name = 'IncrementFunc1';
+ (siblingTree1.componentData as ComponentData).hooksIndex = [0];
+ const siblingTree2 = deepCopy(mockSiblingTree);
+ siblingTree2.name = 'IncrementFunc2';
+ (siblingTree2.componentData as ComponentData).hooksIndex = [1];
+ const siblingTree3 = deepCopy(mockSiblingTree);
+ siblingTree3.name = 'IncrementFuncMultiStates';
+ siblingTree3.state = { ...functionalState, ...functionalState2 };
+ Object.assign((siblingTree3.componentData as ComponentData).hooksState!, functionalState2);
+ (siblingTree3.componentData as ComponentData).hooksIndex = [2, 3];
+ mockFiberTree.children[0].children = [siblingTree1];
+ siblingTree1.children.push(siblingTree2, siblingTree3);
+
+ // Compare the two trees:
+ expect(tree).toEqual(mockFiberTree);
+ });
+ });
+ });
+
+ describe('Tree unit test', () => {
+ describe('Serialize state unit test', () => {
+ it('should create a deep copy of state', () => {
+ const dummyState = {
+ counter: 1,
+ playerOne: 'X',
+ board: [
+ ['', 'O', 'X'],
+ ['', 'O', 'X'],
+ ['O', 'X', ''],
+ ],
+ };
+ const serializedState = serializeState(dummyState);
+
+ expect(dummyState).toEqual(serializedState);
+ expect(dummyState).not.toBe(serializedState);
+ });
+
+ it('should detect circular state', () => {
+ const circularState: { [key: string]: any } = {};
+ circularState.circ = circularState;
+ const serializedCircularState = serializeState(circularState);
+
+ expect(serializedCircularState).toEqual('circularState');
+ });
+ });
+
+ describe('Constructing a default tree', () => {
+ const newTree: Tree = new Tree({});
+ it('should be able to create a newTree', () => {
+ expect(newTree).toBeInstanceOf(Tree);
+ expect(newTree.state).toEqual({});
+ });
+
+ it('should have 6 properties', () => {
+ expect(newTree).toHaveProperty('state');
+ expect(newTree).toHaveProperty('name');
+ expect(newTree).toHaveProperty('componentData');
+ expect(newTree).toHaveProperty('children');
+ expect(newTree).toHaveProperty('isExpanded');
+ expect(newTree).toHaveProperty('rtid');
+ });
+
+ it('should have default name, componentData, isExpanded and rtid', () => {
+ expect(newTree.name).toBe('nameless');
+ expect(newTree.componentData).toEqual({});
+ expect(newTree.isExpanded).toBe(true);
+ expect(newTree.rtid).toBe(null);
+ });
+
+ it('should have no children', () => {
+ expect(newTree.children).toHaveLength(0);
+ });
+ });
+
+ describe('Constructing a tree root', () => {
+ const root: Tree = new Tree('root', 'root');
+ it("should have name as 'root' and state as 'root'", () => {
+ expect(root).toBeInstanceOf(Tree);
+ expect(root.state).toBe('root');
+ expect(root.name).toBe('root');
+ expect(root.componentData).toEqual({});
+ expect(root.isExpanded).toBe(true);
+ expect(root.rtid).toBe(null);
+ expect(root.children).toHaveLength(0);
+ });
+ });
+
+ describe('Adding children', () => {
+ let newTree: Tree;
+ let child: Tree;
+ beforeEach(() => {
+ newTree = new Tree('root', 'root');
+ child = newTree.addChild('stateful', 'child', {}, null);
+ });
+
+ it('should return a new tree child', () => {
+ expect(child).toBeInstanceOf(Tree);
+ expect(child).toBeInstanceOf(Tree);
+ expect(child.state).toBe('stateful');
+ expect(child.name).toBe('child');
+ expect(child.componentData).toEqual({});
+ expect(child.isExpanded).toBe(true);
+ expect(child.rtid).toBe(null);
+ expect(child.children).toHaveLength(0);
+ });
+
+ it("should have the child be in the children's array property", () => {
+ expect(newTree.children).toHaveLength(1);
+ expect(newTree.children).toContain(child);
+ expect(newTree.children[0]).toBe(child);
+ });
+
+ it('should have unique name', () => {
+ const nextChild1: Tree = child.addChild('stateful', 'child', {}, null);
+ const nextChild2: Tree = child.addChild('stateful', 'child', {}, null);
+ expect(child.children).toHaveLength(2);
+ expect(child.children[0]).toBe(nextChild1);
+ expect(child.children[1]).toBe(nextChild2);
+ expect(nextChild1.name).toBe('child2');
+ expect(nextChild2.name).toBe('child3');
+ });
+ });
+
+ describe('createComponentActionsRecord unit test', () => {
+ it('should save a new component action record if the Fiber node is a stateful class component', () => {
+ mockFiberNode.tag = ClassComponent;
+ mockFiberNode.stateNode = {
+ state: { counter: 0 }, // a mock state object
+ setState: jest.fn(), // a mock setState method
+ };
+ createComponentActionsRecord(mockFiberNode);
+ expect(componentActionsRecord.getComponentByIndex(0)).toBe(mockFiberNode.stateNode);
+ });
+
+ it('should save a new component action record if the Fiber node is a stateful class component with props', () => {
+ mockFiberNode.tag = ClassComponent;
+ // a mock state object
+ mockFiberNode.stateNode = {
+ state: { counter: 0 },
+ props: { start: 0 },
+ setState: jest.fn(), // a mock setState method
+ };
+ createComponentActionsRecord(mockFiberNode);
+ expect(componentActionsRecord.getComponentByIndex(0)).toMatchObject({
+ props: mockFiberNode.stateNode.props,
+ state: mockFiberNode.stateNode.state,
+ });
+ });
+
+ it('should save a new component action record if the Fiber node is a functional component with state', () => {
+ mockFiberNode.tag = FunctionComponent;
+ mockFiberNode.memoizedState = {
+ queue: [{}, { state: { value: 'test' } }], // a mock memoizedState object
+ };
+ createComponentActionsRecord(mockFiberNode);
+ expect(componentActionsRecord.getComponentByIndex(0)).toBe(
+ mockFiberNode.memoizedState.queue,
+ );
+ });
+
+ it('should not save a new component action record if the Fiber node is not a relevant component type', () => {
+ mockFiberNode.tag = 4; // HostRoot
+ createComponentActionsRecord(mockFiberNode);
+ expect(componentActionsRecord.getAllComponents()).toHaveLength(0);
+ });
+ });
+ });
+});
diff --git a/src/backend/__tests__/routes.test.ts b/src/backend/__tests__/routes.test.ts
index fa701aede..cacde2df9 100644
--- a/src/backend/__tests__/routes.test.ts
+++ b/src/backend/__tests__/routes.test.ts
@@ -1,46 +1,106 @@
-import routes from '../routes';
+/**
+ * @jest-environment node
+ */
+import { JSDOM } from 'jsdom';
-describe('Unit Tests for routes.ts', () => {
- describe('addRoute', () => {
- it('If given a url that doesn\'t match the current route, it should return a new route object and add the route object to its values array.', () => {
- const newRoute = routes.addRoute('http://localhost:8080/');
- expect(newRoute.url).toBe('http://localhost:8080/');
- expect(newRoute.id).toBe(1);
- expect(routes.values[1].url).toBe('http://localhost:8080/');
- expect(routes.values[1].id).toBe(1);
+import { Routes, Route } from '../models/routes';
+
+describe('Route class testing', () => {
+ let routes: Routes;
+ let dom: JSDOM;
+ beforeAll(() => {
+ // Set up a fake DOM environment with JSDOM
+ dom = new JSDOM('', { url: 'http://localhost' });
+ global.window = dom.window as unknown as Window & typeof globalThis;
+ global.document = dom.window._document;
+ });
+
+ afterAll(() => {
+ // Clean up the fake DOM environment
+ dom.window.close();
+ });
+ beforeEach(() => {
+ routes = new Routes();
+ window.history.replaceState = jest.fn();
+ window.history.pushState = jest.fn();
+ });
+
+ describe('Route initialization', () => {
+ it('should create a new instance of Route class', () => {
+ const route = new Route('/home', 1);
+ expect(route.url).toBe('/home');
+ expect(route.id).toBe(1);
});
+ });
- it('If given a url that does match the current route, it should return the current route object and not add anything to its values array.', () => {
- const sameRoute = routes.addRoute('http://localhost:8080/');
- expect(sameRoute).toBe(routes.values[1]);
- expect(routes.values.length).toBe(2);
+ describe('Routes class addRoute and navigate methods', () => {
+ it('should add a new route to the route history array', () => {
+ const route = routes.addRoute('/home');
+ expect(route.url).toBe('/home');
+ expect(route.id).toBe(1);
+ expect(routes.routeHistory).toHaveLength(2);
});
- it('Should give route objects unique ids.', () => {
- routes.addRoute('http://localhost:8080/test');
- expect(routes.values[1].id).not.toBe(routes.values[2].id);
+ it('should add multiple routes to the route history array', () => {
+ const route = routes.addRoute('/home');
+ const route2 = routes.addRoute('/about');
+ expect(route.url).toBe('/home');
+ expect(route.id).toBe(1);
+ expect(route2.url).toBe('/about');
+ expect(route2.id).toBe(2);
+ expect(routes.routeHistory).toHaveLength(3);
});
- it('Should reassign current to point to the last index in the values array.', () => {
- expect(routes.current).toBe(routes.values.length - 1);
+ it('should return the current route if the user has not navigated away from it', () => {
+ const route = routes.addRoute('/home');
+ const currentRoute = routes.addRoute('/home');
+ expect(currentRoute).toEqual(route);
+ expect(routes.routeHistory).toHaveLength(2);
+ });
+
+ it('should navigate to the target route in the route history stack', () => {
+ const homeRoute = routes.addRoute('/home');
+ const aboutRoute = routes.addRoute('/about');
+ const result = routes.navigate(homeRoute);
+ expect(result).toBe(true);
+ expect(routes.current).toBe(1);
+ const result2 = routes.navigate(aboutRoute);
+ expect(result2).toBe(true);
+ expect(routes.current).toBe(2);
});
- });
- describe('navigate', () => {
- it('Should correctly calculate delta between current and target route.', () => {
- routes.addRoute('http://localhost:8080/test1');
- routes.navigate({ url: 'http://localhost:8080/', id: 1 });
+ it('should not navigate to the target route if it is the current route', () => {
+ const homeRoute = routes.addRoute('/home');
+ const result = routes.navigate(homeRoute);
+ expect(result).toBe(false);
expect(routes.current).toBe(1);
- routes.navigate({ url: 'http://localhost:8080/test1', id: 3 });
- expect(routes.current).toBe(3);
});
- it('Should return true if it navigated.', () => {
- expect(routes.navigate({ url: 'http://localhost:8080/', id: 1 })).toBe(true);
+ it('should throw an error if target route is not found', () => {
+ const dummyRoute: Route = new Route('/error', 0);
+ expect(() => routes.navigate(dummyRoute)).toThrowError();
});
+ });
- it('Should return false if it didn\'t navigate.', () => {
- expect(routes.navigate({ url: 'http://localhost:8080/', id: 1 })).toBe(false);
+ describe('Routes rebuildHistory method', () => {
+ describe('rebuildHistory', () => {
+ it('should replace the current URL in the history stack with the given URL', () => {
+ // Mock the `routeHistory` array with three routes
+ const route1 = new Route('/home', 0);
+ const route2 = new Route('/about', 1);
+ const route3 = new Route('/contact', 2);
+ const route4 = new Route('/portfolio', 3);
+ routes.routeHistory = [route1, route2, route3, route4];
+ // Set current route to 2nd page and try to add the home page
+ routes.current = 1;
+ // Add home page
+ routes.addRoute(route1.url);
+ // Expect the `replaceState` method to have been called with the URL of the third route
+ expect(window.history.replaceState).toHaveBeenCalledWith('', '', route3.url);
+ // Expect the `pushState` method to have been called with the URL of the third route
+ expect(window.history.pushState).toHaveBeenCalledWith('', '', route4.url);
+ expect(window.history.pushState).toHaveBeenCalledWith('', '', route1.url);
+ });
});
});
});
diff --git a/src/backend/__tests__/throttle.test.ts b/src/backend/__tests__/throttle.test.ts
new file mode 100644
index 000000000..277d211b4
--- /dev/null
+++ b/src/backend/__tests__/throttle.test.ts
@@ -0,0 +1,64 @@
+import throttle from '../controllers/throttle';
+
+describe('throttle unit tests', () => {
+ const mockCallback = jest.fn();
+
+ beforeEach(() => {
+ jest.useFakeTimers();
+ mockCallback.mockClear();
+ });
+
+ afterEach(() => {
+ jest.runOnlyPendingTimers();
+ jest.useRealTimers();
+ });
+
+ it('should return a function', () => {
+ const result = throttle(mockCallback, 1000);
+ expect(typeof result).toBe('function');
+ });
+
+ it('throttled function should be called with the correct arguments', () => {
+ const throttledFunc = throttle(mockCallback, 1000);
+
+ throttledFunc(1, 2, 3);
+
+ expect(mockCallback).toHaveBeenCalledWith(1, 2, 3);
+ });
+
+ it('should invoke the callback immediately on the first call', () => {
+ const throttledFunc = throttle(mockCallback, 1000);
+
+ throttledFunc();
+ expect(mockCallback).toHaveBeenCalled();
+ });
+
+ it('should invoke the callback only once if called multiple times within the throttling interval', () => {
+ const throttledFunc = throttle(mockCallback, 1000);
+
+ throttledFunc();
+ throttledFunc();
+ throttledFunc();
+ jest.advanceTimersByTime(500);
+
+ expect(mockCallback).toHaveBeenCalledTimes(1);
+ });
+
+ it('should invoke the callback multiple times if called outside of the throttling interval', () => {
+ const throttledFunc = throttle(mockCallback, 1000);
+
+ throttledFunc();
+ jest.advanceTimersByTime(500);
+ expect(mockCallback).toHaveBeenCalledTimes(1);
+
+ throttledFunc();
+ jest.advanceTimersByTime(500);
+ expect(mockCallback).toHaveBeenCalledTimes(2);
+
+ throttledFunc();
+ jest.advanceTimersByTime(100);
+ throttledFunc();
+ jest.advanceTimersByTime(901);
+ expect(mockCallback).toHaveBeenCalledTimes(3);
+ });
+});
diff --git a/src/backend/__tests__/timeJump.test.ts b/src/backend/__tests__/timeJump.test.ts
deleted file mode 100644
index 8688faf25..000000000
--- a/src/backend/__tests__/timeJump.test.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-/* eslint-disable @typescript-eslint/ban-types */
-/* eslint-disable @typescript-eslint/no-unused-vars */
-/* eslint-disable @typescript-eslint/no-empty-function */
-/* eslint-disable @typescript-eslint/no-var-requires */
-/* eslint-disable max-classes-per-file */
-import timeJumpRequire from '../timeJump';
-import componentActionsRecord from '../masterState';
-
-class Component {
- mockfn: (state) => void
-
- state: Record
-
- componentData: {}
-
- constructor(mockfn) {
- this.mockfn = mockfn;
- }
-
- setState(state, func = () => { }) {
- this.mockfn(state);
- func();
- }
-}
-
-class FiberNode {
- private state: Record;
-
- children: FiberNode[];
-
- component: Component;
-
- componentData: {
- index?: number;
- };
-
- constructor(mockfn, state) {
- this.state = state;
- this.children = [];
- this.component = new Component(mockfn);
- this.componentData = { index: 0 };
- }
-}
-
-describe('unit testing for timeJump.ts', () => {
- let timeJump: (target) => void;
- let snapShot: Record;
- let mode;
- let mockFuncs;
-
- beforeEach(() => {
- const mockFunc = jest.fn();
- mode = { jumping: false };
- mockFuncs = [];
- for (let i = 0; i < 4; i += 1) mockFuncs.push(mockFunc);
-
- const tree: FiberNode = new FiberNode(mockFuncs[0], '*');
- tree.children = [
- new FiberNode(mockFuncs[1], '*'),
- new FiberNode(mockFuncs[2], '*'),
- new FiberNode(mockFuncs[3], '*'),
- ];
-
- snapShot = { tree };
- timeJump = timeJumpRequire(mode);
- });
- test('calling the initial require should return a function', () => {
- const funcDef = timeJumpRequire;
- expect(typeof funcDef).toBe('function');
- });
-
- // xdescribe('testing iteration through snapshot tree', () => {
- // const states = ['root', 'firstChild', 'secondChild', 'thirdChild'];
- // const target = new FiberNode(null, states[0]);
- // target.children = [
- // new FiberNode(null, states[1]),
- // new FiberNode(null, states[2]),
- // new FiberNode(null, states[3]),
- // ];
-
- // target.componentData = {index: 0}
-
- // beforeEach((): void => {
- // timeJump(target);
- // });
- // test('timeJump should call setState on each state in origin', () => {
- // mockFuncs.forEach(mockFunc => expect(mockFunc.mock.calls.length).toBe(1));
- // });
-
- // test('timeJump should pass target state to origin setState', () => {
- // mockFuncs.forEach((mockFunc, i) => expect(mockFunc.mock.calls[0][0]).toBe(states[i]));
- // });
- // });
-
- test('jumping mode should be set while timeJumping', () => {
- mode = { jumping: true };
- const logMode = jest.fn();
- logMode.mockImplementation(() => expect(mode.jumping).toBe(true));
-
- snapShot.tree = new FiberNode(logMode, null);
- const target = new FiberNode(null, 'test');
- logMode(target);
- expect(logMode).toHaveBeenCalled();
- });
-});
diff --git a/src/backend/__tests__/tree.test.ts b/src/backend/__tests__/tree.test.ts
deleted file mode 100644
index 3012ab386..000000000
--- a/src/backend/__tests__/tree.test.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import Tree from '../tree';
-
-/**
- * Created new tree under sibling and copy and clean tree describe block --
- * Reason is because other tests are adding properties to tree and affecting the child block,
- * so this was a quick way to test the trees getting reset to initial state
- *
- * Possible fix if more time allowed: Making use of beforeEach or afterEach --
- */
-
-describe('Tree unit test', () => {
- const newTree = new Tree({});
- describe('Constructor', () => {
- it('should be able to create a newTree', () => {
- expect(newTree.state).toEqual({});
- });
-
- it('should have 7 properties', () => {
- expect(newTree).toHaveProperty('state');
- expect(newTree).toHaveProperty('name');
- expect(newTree).toHaveProperty('componentData');
- expect(newTree).toHaveProperty('children');
- expect(newTree).toHaveProperty('parent');
- expect(newTree).toHaveProperty('isExpanded');
- expect(newTree).toHaveProperty('rtid');
- });
-
- it('has name default value as stateless', () => {
- expect(newTree.name).toBe('nameless');
- });
- });
-
- /**
- *
- * making sure to adhere to ts practices when goign through tests
- *
- * ^^
- * the tree should have initial values of state,
- * name, etc to be default as per newly created tree
- * update the add child and add sibling tests
- *
- * update the clean tree copy test to make it test for deep equaltiy? (note:
- * this test may always fail if we make it so because there is no way to have deep equalituy
- * with some shit that isn't allowed)
- */
-
- describe('Adding children', () => {
- const returnChild = newTree.addChild('stateful', 'child', {}, null);
-
- it('should have the child be in the children\'s array property', () => {
- // check if returnChild is in the children array property of tree that invoked addChild
- expect(newTree.children).toContain(returnChild);
- });
-
- it('should have the object that invoked it be it\'s parent', () => {
- // checking parent to be the tree that invoked addChild
- expect(returnChild.parent).toEqual(newTree);
- });
-
- it('parent now contains an array of children and each children is a valid tree', () => {
- expect(newTree.children[0]).toHaveProperty('state');
- expect(newTree.children[0]).toHaveProperty('name');
- expect(newTree.children[0]).toHaveProperty('componentData');
- });
- });
-
- describe('Adding sibling', () => {
- const newTreeCopy = new Tree({});
- const returnChild = newTreeCopy.addChild('stateful', 'child', {}, null);
- const returnSibling = returnChild.addSibling('stateful', 'child', {}, null);
-
- it('the tree now has 2 children', () => {
- expect(newTreeCopy.children.length).toBe(2);
- });
-
- it('both of the children has the parent as this tree', () => {
- expect(returnChild.parent).toEqual(newTreeCopy);
- expect(returnSibling.parent).toEqual(newTreeCopy);
- });
- });
-
- // review this test
- // returnSibling not used?
- // Check Test
-
- describe('Copy & clean tree', () => {
- const newTreeLastCopy = new Tree({});
- const returnChild = newTreeLastCopy.addChild('stateful', 'child', {}, null);
- returnChild.addSibling('stateful', 'child', {}, null);
- const copy = newTreeLastCopy.cleanTreeCopy();
- it('its copy has 2 children', () => {
- expect(copy.children.length).toEqual(2);
- });
- });
-});
diff --git a/src/backend/controllers/createComponentActionsRecord.ts b/src/backend/controllers/createComponentActionsRecord.ts
new file mode 100644
index 000000000..3c40fec4b
--- /dev/null
+++ b/src/backend/controllers/createComponentActionsRecord.ts
@@ -0,0 +1,108 @@
+import { Fiber } from '../types/backendTypes';
+import {
+ FunctionComponent,
+ ClassComponent,
+ IndeterminateComponent,
+ ContextProvider,
+} from '../types/backendTypes';
+import componentActionsRecord from '../models/masterState';
+import { getHooksStateAndUpdateMethod } from './statePropExtractors';
+import {
+ nextJSDefaultComponent,
+ remixDefaultComponents,
+ allowedComponentTypes,
+} from '../models/filterConditions';
+
+// ------------------------CREATE COMPONENT ACTIONS RECORD----------------------
+/**
+ * This is a recursive function that runs after Fiber commit, if user is navigating to a new route during jumping. This function performs the following logic:
+ * 1. Traverse from FiberRootNode
+ * 2. If the component is stateful, extract its update methods & push to the `componentActionRecord` array
+ * @param currentFiberNode A Fiber object
+ */
+export default function createComponentActionsRecord(currentFiberNode: Fiber): void {
+ // ------------------OBTAIN DATA FROM THE CURRENT FIBER NODE----------------
+ // Destructure the current fiber node
+ const {
+ sibling,
+ stateNode,
+ child,
+ // with memoizedState we can grab the root type and construct an Abstract Syntax Tree from the hooks structure using Acorn in order to extract the hook getters and match them with their corresponding setters in an object
+ memoizedState,
+ elementType,
+ tag,
+ } = currentFiberNode;
+
+ // Obtain component name:
+ const componentName =
+ elementType?._context?.displayName || //For ContextProvider
+ elementType?._result?.name || //For lazy Component
+ elementType?.render?.name ||
+ elementType?.name ||
+ 'nameless';
+
+ // --------------------FILTER COMPONENTS/FIBER NODE-------------------------
+ /**
+ * For the snapshot tree,
+ * 1. We are only interested in components that are one of these types: Function Component, Class Component, Indeterminate Component or Context Provider.
+ * NOTE: this list of components may change depending on future use
+ * 2. If user is using Next JS, filter out default NextJS components
+ * 3. If user is using Remix JS, filter out default Remix components
+ */
+
+ if (
+ !allowedComponentTypes.has(tag) ||
+ nextJSDefaultComponent.has(componentName) ||
+ remixDefaultComponents.has(componentName)
+ ) {
+ // -------------------TRAVERSE TO NEXT FIBERNODE------------------------
+ // If currentFiberNode has children, recurse on children
+ if (child) createComponentActionsRecord(child);
+
+ // If currentFiberNode has siblings, recurse on siblings
+ if (sibling) {
+ createComponentActionsRecord(sibling);
+ }
+ // ---------RETURN THE TREE OUTPUT & PASS TO FRONTEND FOR RENDERING-------
+ return;
+ }
+
+ // ---------OBTAIN STATE & SET STATE METHODS FROM CLASS COMPONENT-----------
+ // Check if node is a stateful class component when user use setState.
+ // If user use setState to define/manage state, the state object will be stored in stateNode.state => grab the state object stored in the stateNode.state
+ if ((tag === ClassComponent || tag === IndeterminateComponent) && stateNode?.state) {
+ // Save component setState() method to our componentActionsRecord for use during timeJump
+ componentActionsRecord.saveNew(stateNode);
+ }
+ // --------OBTAIN STATE & DISPATCH METHODS FROM FUNCTIONAL COMPONENT--------
+ // Check if node is a stateful class component when user use setState.
+ // If user use useState to define/manage state, the state object will be stored in memoizedState.queue => grab the state object stored in the memoizedState.queue
+ if (
+ (tag === FunctionComponent || tag === IndeterminateComponent || tag === ContextProvider) &&
+ memoizedState
+ ) {
+ if (memoizedState.queue) {
+ try {
+ // Hooks states are stored as a linked list using memoizedState.next,
+ // so we must traverse through the list and get the states.
+ // We then store them along with the corresponding memoizedState.queue,
+ // which includes the dispatch() function we use to change their state.
+ const hooksStates = getHooksStateAndUpdateMethod(memoizedState);
+ hooksStates.forEach(({ component }) => {
+ // Save component's state and dispatch() function to our record for future time-travel state changing. Add record index to snapshot so we can retrieve later
+ componentActionsRecord.saveNew(component);
+ });
+ } catch (err) {
+ console.log('ERROR: Failed Element during JSX parsing', {
+ componentName,
+ });
+ }
+ }
+ }
+ // ---------------------TRAVERSE TO NEXT FIBERNODE--------------------------
+ // If currentFiberNode has children, recurse on children
+ if (child) createComponentActionsRecord(child);
+
+ // If currentFiberNode has siblings, recurse on siblings
+ if (sibling) createComponentActionsRecord(sibling);
+}
diff --git a/src/backend/controllers/createTree.ts b/src/backend/controllers/createTree.ts
new file mode 100644
index 000000000..d49d134fe
--- /dev/null
+++ b/src/backend/controllers/createTree.ts
@@ -0,0 +1,298 @@
+// --------------------------START OF IMPORT------------------------------------
+import {
+ getHooksNames,
+ getHooksStateAndUpdateMethod,
+ // getStateAndContextData, //COMMENT OUT SINCE EXTRACTING CONTEXT IS STILL IN EXPERIMENT
+ filterAndFormatData,
+} from './statePropExtractors';
+
+import { Fiber, ComponentData } from '../types/backendTypes';
+import {
+ FunctionComponent,
+ ClassComponent,
+ IndeterminateComponent,
+ ContextProvider,
+} from '../types/backendTypes';
+
+import Tree from '../models/tree';
+import componentActionsRecord from '../models/masterState';
+import {
+ nextJSDefaultComponent,
+ remixDefaultComponents,
+ allowedComponentTypes,
+} from '../models/filterConditions';
+
+// -------------------------CREATE TREE TO SEND TO FRONT END--------------------
+/**
+ * This is a function that runs after every Fiber commit using the following logic:
+ * 1. Traverse from FiberRootNode
+ * 2. Create an instance of custom Tree class
+ * 3. Build a new state snapshot
+ * Every time a state change is made in the accompanying app, the extension creates a Tree “snapshot” of the current state, and adds it to the current “cache” of snapshots in the extension
+ * @param currentFiberNode A Fiber object
+ * @return An instance of a Tree object
+ */
+// TODO: Not sure why the ritd need to be outside of the _createTree function. Want to put inside, but in case this need to be keep track for front end.
+export default function createTree(currentFiberNode: Fiber): Tree {
+ let rtidCounter: number = 0;
+ return _createTree(currentFiberNode, new Tree('root', 'root'));
+
+ /**
+ * This is a helper function to recursively traverse the React Fiber Tree and craft the snapshot tree to send to front end
+ * @param currentFiberNode A Fiber object
+ * @param tree A Tree object, default initialized to an instance given 'root' and 'root'
+ * @returns An instance of a Tree Object
+ */
+ function _createTree(currentFiberNode: Fiber, tree: Tree): Tree {
+ // ------------------OBTAIN DATA FROM THE CURRENT FIBER NODE----------------
+ // Destructure the current fiber node:
+ const {
+ sibling,
+ stateNode,
+ child,
+ memoizedState,
+ memoizedProps,
+ elementType,
+ key,
+ tag,
+ actualDuration,
+ actualStartTime,
+ selfBaseDuration,
+ treeBaseDuration,
+ // _debugHookTypes, //COMMENT OUT SINCE EXTRACTING CONTEXT IS STILL IN EXPERIMENT
+ } = currentFiberNode;
+
+ // Obtain component name:
+ /** Name of the current component */
+ let componentName: string =
+ elementType?._context?.displayName || //For ContextProviders like Route, Navigation, Location
+ (elementType?._context && 'ContextProvider') || //Mark's note: useContext providers weren't showing up the way listed in the line above, I actually couldn't find the name of the context provider on the react dev tools fiber tree.
+ elementType?._result?.name || //For lazy Component
+ elementType?.render?.name ||
+ elementType?.name || //For Functional/Class Component
+ 'nameless';
+
+ // --------------------FILTER COMPONENTS/FIBER NODE-------------------------
+ /**
+ * For the snapshot tree,
+ * 1. We will only interested in components that are one of these types: Function Component, Class Component, Indeterminate Component or Context Provider.
+ * NOTE: this list of components may change depending on future use
+ * 2. If user use Next JS, filter out default NextJS components
+ * 3. If user use Remix JS, filter out default Remix components
+ */
+
+ if (
+ !allowedComponentTypes.has(tag) ||
+ nextJSDefaultComponent.has(componentName) ||
+ remixDefaultComponents.has(componentName)
+ ) {
+ // -------------------TRAVERSE TO NEXT FIBERNODE------------------------
+ // If currentFiberNode has children, recurse on children
+ if (child) _createTree(child, tree);
+
+ // If currentFiberNode has siblings, recurse on siblings
+ if (sibling) {
+ _createTree(sibling, tree);
+ }
+ // ---------RETURN THE TREE OUTPUT & PASS TO FRONTEND FOR RENDERING-------
+ return tree;
+ }
+
+ // --------------INITIALIZE OBJECT TO CONTAIN COMPONENT DATA---------------
+ let newState: 'stateless' | object = 'stateless';
+ let componentData: ComponentData = {
+ actualDuration,
+ actualStartTime,
+ selfBaseDuration,
+ treeBaseDuration,
+ key,
+ props: {},
+ context: {},
+ state: null,
+ index: null,
+ hooksState: null,
+ hooksIndex: null,
+ };
+
+ // ---------------APPEND PROP DATA FROM REACT DEV TOOL----------------------
+ // Check to see if the currentFiberNode has any props
+ if (memoizedProps) {
+ switch (elementType.name) {
+ // If component comes from React Router, extract only pathname:
+ case 'Router': {
+ componentData.props = { pathname: memoizedProps?.location?.pathname };
+ break;
+ }
+ case 'RenderedRoute': {
+ componentData.props = { pathname: memoizedProps?.match?.pathname };
+ break;
+ }
+ // For react-router components Route, Navigation, or Location, the elementType won't have a name property, so elementType.name will be undefined.
+ // The following switch case will be entered and will pass limited info to these element's props, but if none of the
+ // "if" statements are entered and a break statements isn't executed, the default case will still be entered
+ case undefined: {
+ if (elementType._context?.displayName === 'Route') {
+ componentData.props = { pathname: memoizedProps?.value?.matches?.[0]?.pathname };
+ break;
+ }
+ if (elementType._context?.displayName === 'Navigation') {
+ componentData.props = { basename: memoizedProps?.value?.basename };
+ break;
+ }
+ if (elementType._context?.displayName === 'Location') {
+ componentData.props = { pathname: memoizedProps?.value?.location?.pathname };
+ break;
+ }
+ }
+ // Else filter & format props data to ensure they are JSON stringify-able, before sending to front end
+ default: {
+ componentData.props = filterAndFormatData(memoizedProps);
+ }
+ }
+ }
+
+ // COMMENT OUT SINCE EXTRACTING CONTEXT IS STILL IN EXPERIMENT
+ // // ------------APPEND CONTEXT DATA FROM REACT DEV TOOL----------------
+ // // memoizedState
+ // // Note: if user use ReactHook, memoizedState.memoizedState can be a falsy value such as null, false, ... => need to specify this data is not undefined
+ // if (
+ // (tag === FunctionComponent || tag === ClassComponent || tag === IndeterminateComponent) &&
+ // memoizedState?.memoizedState !== undefined
+ // ) {
+ // // If user uses Redux, context data will be stored in memoizedState of the Provider component => grab context object stored in the memoizedState
+ // if (elementType.name === 'Provider') {
+ // Object.assign(
+ // componentData.context,
+ // getStateAndContextData(memoizedState, elementType.name, _debugHookTypes),
+ // );
+ // }
+ // // Else if user use ReactHook to define state => all states will be stored in memoizedState => grab all states stored in the memoizedState
+ // // else {
+ // // Object.assign(
+ // // componentData.state,
+ // // getStateAndContextData(memoizedState, elementType.name, _debugHookTypes),
+ // // );
+ // // }
+ // }
+ // // if user uses useContext hook, context data will be stored in memoizedProps.value of the Context.Provider component => grab context object stored in memoizedprops
+ // // Different from other provider, such as Routes, BrowserRouter, ReactRedux, ..., Context.Provider does not have a displayName
+ // // TODO: need to render this context provider when user use useContext hook.
+ //
+ //
+ // if (tag === ContextProvider && !elementType._context.displayName) {
+ // let stateData = memoizedProps.value;
+ // if (stateData === null || typeof stateData !== 'object') {
+ // stateData = { CONTEXT: stateData };
+ // }
+ // componentData.context = filterAndFormatData(stateData);
+ // componentName = 'Context';
+ // }
+
+ // ---------OBTAIN STATE & SET STATE METHODS FROM CLASS COMPONENT-----------
+ // Check if currentFiberNode is a stateful class component when user use setState.
+ // If user use setState to define/manage state, the state object will be stored in stateNode.state => grab the state object stored in the stateNode.state
+ // Example: for tic-tac-toe demo-app: Board is a stateful component that use setState to store state data.
+ if ((tag === ClassComponent || tag === IndeterminateComponent) && stateNode?.state) {
+ componentData.index = componentActionsRecord.saveNew(stateNode);
+ componentData.state = stateNode.state;
+ newState = componentData.state;
+ }
+
+ // --------OBTAIN STATE & DISPATCH METHODS FROM FUNCTIONAL COMPONENT--------
+ // Check if currentFiberNode is a stateful functional component when user use useState hook.
+ // If user use useState to define/manage state, the state object will be stored in memoizedState => grab the state object & its update method (dispatch) from memoizedState
+ // Example: for Stateful buttons demo-app: Increment is a stateful component that use useState hook to store state data.
+ // Inside the _createTree function where we handle functional components
+ if ((tag === FunctionComponent || tag === IndeterminateComponent) && memoizedState) {
+ if (memoizedState.queue) {
+ try {
+ const hooksStates = getHooksStateAndUpdateMethod(memoizedState);
+ const hooksNames = getHooksNames(elementType.toString());
+
+ componentData.hooksState = {};
+ componentData.reducerStates = []; // New array to store reducer states
+ componentData.hooksIndex = [];
+
+ hooksStates.forEach(({ state, component, isReducer, lastAction, reducer }, i) => {
+ componentData.hooksIndex.push(componentActionsRecord.saveNew(component));
+
+ if (isReducer) {
+ // Store reducer-specific information
+ componentData.reducerStates.push({
+ state,
+ lastAction,
+ reducerIndex: i,
+ hookName: hooksNames[i]?.hookName || `Reducer ${i}`,
+ });
+ } else {
+ // Regular useState hook
+ componentData.hooksState[hooksNames[i]?.varName || `State: ${i}`] = state;
+ }
+ });
+ newState = {
+ ...componentData.hooksState,
+ reducers: componentData.reducerStates,
+ };
+ } catch (err) {
+ console.log('Error extracting component state:', {
+ componentName,
+ memoizedState,
+ error: err,
+ });
+ }
+ }
+ }
+ if (tag === ContextProvider && !elementType._context.displayName) {
+ let stateData = memoizedProps.value;
+ if (stateData === null || typeof stateData !== 'object') {
+ stateData = { CONTEXT: stateData };
+ }
+ componentData.context = filterAndFormatData(stateData);
+ componentName = 'Context';
+ }
+
+ // -----------------ADD COMPONENT DATA TO THE OUTPUT TREE-------------------
+
+ /**
+ * `rtid` - The `Root ID` is a unique identifier that is assigned to each React root instance in a React application.
+ */
+ let rtid: string | null = null;
+
+ // Grab JSX Component & replace the 'fromLinkFiber' class value
+ if (currentFiberNode.child?.stateNode?.setAttribute) {
+ rtid = `fromLinkFiber${rtidCounter}`;
+ // rtid = rtidCounter;
+ // check if rtid is already present
+ // remove existing rtid before adding a new one
+ if (currentFiberNode.child.stateNode.classList.length > 0) {
+ const lastClass =
+ currentFiberNode.child.stateNode.classList[
+ currentFiberNode.child.stateNode.classList.length - 1
+ ];
+ if (lastClass.includes('fromLinkFiber')) {
+ currentFiberNode.child.stateNode.classList.remove(lastClass);
+ }
+ }
+ currentFiberNode.child.stateNode.classList.add(rtid);
+ }
+ rtidCounter += 1;
+
+ /**
+ * The updated tree after adding the `componentData` obtained from `currentFiberNode`
+ */
+ const childNode = tree.addChild(newState, componentName, componentData, rtid);
+
+ // ---------------------TRAVERSE TO NEXT FIBERNODE--------------------------
+ // If currentFiberNode has children, recurse on children
+ if (child) _createTree(child, childNode);
+
+ // If currentFiberNode has siblings, recurse on siblings
+ if (sibling) {
+ _createTree(sibling, tree);
+ }
+
+ // ------------RETURN THE TREE OUTPUT & PASS TO FRONTEND FOR RENDERING------
+
+ return tree;
+ }
+}
diff --git a/src/backend/controllers/statePropExtractors.ts b/src/backend/controllers/statePropExtractors.ts
new file mode 100644
index 000000000..0f1a3980f
--- /dev/null
+++ b/src/backend/controllers/statePropExtractors.ts
@@ -0,0 +1,230 @@
+import { parse } from '@babel/parser';
+import { Node, CallExpression, MemberExpression, Identifier } from '@babel/types';
+import { HookStateItem, Fiber } from '../types/backendTypes';
+import { exclude } from '../models/filterConditions';
+
+type ReactimeData = {
+ [key: string]: any;
+};
+// ------------FILTER DATA FROM REACT DEV TOOL && CONVERT TO STRING-------------
+/**
+ * This function receives raw Data from REACT DEV TOOL and filter the Data based on the exclude list. The filterd data is then converted to string (if applicable) before being sent to reacTime front end.
+ * NOTE: the formating is important since Chrome will only accept JSON.stringfiable object. Circular object & function are not JSON stringifiable.
+ *
+ * @param reactDevData - The data object obtained from React Devtool. Ex: memoizedProps, memoizedState
+ * @param reactimeData - The cached data from the current component. This can be data about states, context and/or props of the component.
+ * @returns The update component data object to send to front end of ReactTime
+ */
+export function filterAndFormatData(
+ reactDevData: { [key: string]: any },
+ reactimeData: ReactimeData = {},
+): ReactimeData {
+ for (const key in reactDevData) {
+ try {
+ // If key is in exclude set or if there is no value at key, skip
+ if (exclude.has(key) || reactDevData[key] === undefined) {
+ continue;
+ }
+ // If value at key is a function, assign key with value 'function' to reactimeData object
+ else if (typeof reactDevData[key] === 'function') {
+ reactimeData[key] = 'function';
+ }
+ // If value at key is an object/array and not null => JSON stringify the value
+ else if (typeof reactDevData[key] === 'object' && reactDevData[key] !== null) {
+ reactimeData[key] = JSON.stringify(reactDevData[key]);
+ }
+ // Else assign the primitive value
+ else {
+ reactimeData[key] = reactDevData[key];
+ }
+ } catch (err) {
+ // COMMENT OUT TO AVOID PRINTTING ON THE CONSOLE OF USER - KEEP IT FOR DEBUGGING PURPOSE
+ // console.log({
+ // Message: 'Error in createTree during obtaining props information',
+ // potentialRootCause: 'circular component/failed during JSON stringify',
+ // reactDevData,
+ // key,
+ // err,
+ // });
+ // we will skip any props that cause an error
+ continue;
+ }
+ }
+ return reactimeData;
+}
+
+// ----------------------GET HOOK STATE AND DISPATCH METHOD---------------------
+/**
+ * Helper function to:
+ * - traverse through memoizedState
+ * - extract the state data & the dispatch method, which is stored in memoizedState.queue.
+ *
+ * During time jump, dispatch method will be used to re-render historical state.
+ * @param memoizedState - The current state of the component associated with the current Fiber node.
+ * @return An array of array of HookStateItem objects
+ *
+ */
+export function getHooksStateAndUpdateMethod(
+ memoizedState: Fiber['memoizedState'],
+): Array {
+ const hooksStates: Array = [];
+ while (memoizedState) {
+ if (memoizedState.queue) {
+ // Check if this is a reducer hook by looking at the lastRenderedReducer
+ const isReducer = memoizedState.queue.lastRenderedReducer?.name !== 'basicStateReducer';
+
+ if (isReducer) {
+ // For useReducer hooks, we want to store:
+ // 1. The current state
+ // 2. The last action that was dispatched (if available)
+ // 3. The reducer function itself
+ hooksStates.push({
+ component: memoizedState.queue,
+ state: memoizedState.memoizedState,
+ isReducer: true,
+ lastAction: memoizedState.queue.lastRenderedAction || null,
+ reducer: memoizedState.queue.lastRenderedReducer || null,
+ });
+ } else {
+ // Regular useState hook
+ hooksStates.push({
+ component: memoizedState.queue,
+ state: memoizedState.memoizedState,
+ isReducer: false,
+ });
+ }
+ }
+ memoizedState = memoizedState.next;
+ }
+ return hooksStates;
+}
+
+// ---------------------GET STATE VAR NAME & HOOK NAME--------------------------
+/**
+ * This function receive a string representation of a functional component. This function then use JSX parser to traverse through the function string, and extract the state variable name and its corresponding setState method.
+ * @param elementType - The string representation of a functional component
+ * @returns - An array of objects with key: hookName (the name of setState method) | value: varName (the state variable name)
+ */
+export function getHooksNames(elementType: string): { hookName: string; varName: string }[] {
+ try {
+ const AST = parse(elementType, {
+ sourceType: 'module',
+ plugins: ['jsx', 'typescript'],
+ });
+
+ const statements: { hookName: string; varName: string }[] = [];
+
+ const isIdentifierWithName = (node: any, name: string): boolean => {
+ return node?.type === 'Identifier' && node.name === name;
+ };
+
+ const processArrayPattern = (pattern: any): { setter: string; getter: string } | null => {
+ if (pattern.type === 'ArrayPattern' && pattern.elements.length === 2) {
+ const result = {
+ getter: pattern.elements[0].name,
+ setter: pattern.elements[1].name,
+ };
+ return result;
+ }
+ return null;
+ };
+
+ const extractReducerName = (node: any): string | null => {
+ if (node.type === 'Identifier') {
+ return node.name;
+ }
+
+ if (node.type === 'ArrowFunctionExpression' && node.body.type === 'CallExpression') {
+ if (node.body.callee.type === 'Identifier') {
+ return node.body.callee.name;
+ }
+ }
+
+ return null;
+ };
+
+ function traverse(node: Node) {
+ if (!node) return;
+
+ if (node.type === 'VariableDeclaration') {
+ node.declarations.forEach((declaration) => {
+ if (declaration.init?.type === 'CallExpression') {
+ // Check for Webpack transformed pattern
+ const isWebpackPattern =
+ declaration.init.callee?.type === 'SequenceExpression' &&
+ declaration.init.callee.expressions?.[1]?.type === 'MemberExpression';
+
+ // Get the hook name for Webpack pattern
+ let webpackHookName: string | null = null;
+ if (isWebpackPattern && declaration.init.callee?.type === 'SequenceExpression') {
+ const memberExpr = declaration.init.callee.expressions[1] as any;
+ if (memberExpr?.property?.type === 'Identifier') {
+ webpackHookName = memberExpr.property.name;
+ }
+ }
+
+ // Check for direct pattern
+ const directCallee = declaration.init.callee as any;
+ const isDirectPattern =
+ directCallee?.type === 'Identifier' &&
+ (directCallee.name === 'useState' || directCallee.name === 'useReducer');
+
+ // Check for namespaced pattern
+ const isNamespacedPattern =
+ declaration.init.callee?.type === 'MemberExpression' &&
+ (declaration.init.callee as any).property?.type === 'Identifier' &&
+ ((declaration.init.callee as any).property.name === 'useState' ||
+ (declaration.init.callee as any).property.name === 'useReducer');
+
+ if (isWebpackPattern || isDirectPattern || isNamespacedPattern) {
+ const arrayPattern = processArrayPattern(declaration.id);
+ if (arrayPattern) {
+ const isReducer =
+ webpackHookName === 'useReducer' ||
+ (isDirectPattern && directCallee?.name === 'useReducer') ||
+ (isNamespacedPattern &&
+ (declaration.init.callee as any).property?.name === 'useReducer');
+
+ if (isReducer) {
+ // Handle useReducer
+ if (declaration.init.arguments?.length > 0) {
+ const reducerName = extractReducerName(declaration.init.arguments[0]);
+ if (reducerName) {
+ statements.push({
+ hookName: reducerName,
+ varName: arrayPattern.getter,
+ });
+ }
+ }
+ } else {
+ // Handle useState
+ statements.push({
+ hookName: arrayPattern.setter,
+ varName: arrayPattern.getter,
+ });
+ }
+ }
+ }
+ }
+ });
+ }
+
+ // Recursively traverse
+ for (const key in node) {
+ if (node[key] && typeof node[key] === 'object') {
+ if (Array.isArray(node[key])) {
+ node[key].forEach((child: Node) => traverse(child));
+ } else {
+ traverse(node[key] as Node);
+ }
+ }
+ }
+ }
+
+ traverse(AST);
+ return statements;
+ } catch (err) {
+ console.error('AST Parsing Error:', err);
+ throw new Error('getHooksNameError: ' + err.message);
+ }
+}
diff --git a/src/backend/controllers/throttle.ts b/src/backend/controllers/throttle.ts
new file mode 100644
index 000000000..d4c9c9709
--- /dev/null
+++ b/src/backend/controllers/throttle.ts
@@ -0,0 +1,80 @@
+/**
+ * @method throttle
+ * @param callback A function to throttle
+ * @param MIN_TIME_BETWEEN_UPDATE A number of milliseconds to use as throttling interval
+ * @returns A function that limits input function, `callback`, from being called more than once every `MIN_TIME_BETWEEN_UPDATE` milliseconds
+ *
+ */
+export default function throttle any>(
+ callback: T,
+ MIN_TIME_BETWEEN_UPDATE: number,
+): (...arg: Parameters) => ReturnType {
+ // Initialize boolean flags for callback, throttledFunc
+ /**
+ * A boolean variable tracking if MIN_TIME_BETWEEN_UPDATE has passed
+ *
+ * This value turns TRUE after a callback function is invoked. While this value is true, no additional callback function can be invoked.
+ *
+ * This value turns FALSE after MIN_TIME_BETWEEN_UPDATE has passed => additional callback can now be invoked.
+ *
+ * @default false
+ */
+ let isOnCooldown: boolean = false;
+ /**
+ * A boolean variable tracking if there is a request to invoke the callback in the queue.
+ *
+ * This value turns TRUE if a request to invoke the callback is sent before the MIN_TIME_BETWEEN_UPDATE passes.
+ *
+ * This value turns FALSE after the callback is invoked.
+ *
+ * @default false
+ *
+ */
+ let isCallQueued: boolean = false;
+
+ let timeout: NodeJS.Timeout;
+ // Wrap the passed-in function callback in a callback function that "throttles" (puts a limit on) the number of calls that can be made to function in a given period of time (ms)
+ return function throttledFunc(...args: Parameters): ReturnType {
+ // CASE 1: In cooldown mode and we have a function waiting to be executed, so do nothing
+ if (isOnCooldown && isCallQueued) return;
+
+ // CASE 2: In cooldown mode, but we have no functions waiting to be executed, so just make note that we now have a callback waiting to be executed and then return
+ if (isOnCooldown) {
+ isCallQueued = true;
+ return;
+ }
+
+ // CASE 3: If we are ready to "fire":
+ // Execute the function callback immediately
+ callback(...args);
+ // Initiate a new cooldown period and reset the "call queue"
+ isOnCooldown = true;
+ isCallQueued = false;
+ // Set timeout to end the cooldown period after MIN_TIME_BETWEEN_UPDATE has passed
+ clearTimeout(timeout);
+ timeout = setTimeout(runAfterTimeout, MIN_TIME_BETWEEN_UPDATE);
+
+ /**
+ * @function runAfterTimeout - a function that end the cooldown mode & checks whether we have another function to be executed right after.
+ * @returns void
+ */
+ function runAfterTimeout() {
+ // If there is callback in the queue, execute callback immediately
+ if (isCallQueued) {
+ // Execute callback
+ callback(...args);
+ // Initiate a new cooldown period and reset the "call queue"
+ isOnCooldown = true;
+ isCallQueued = false;
+ // End the cooldown period after MIN_TIME_BETWEEN_UPDATE
+ clearTimeout(timeout);
+ setTimeout(runAfterTimeout, MIN_TIME_BETWEEN_UPDATE);
+ }
+ // If no callback in queue, end the cooldown period
+ else {
+ // End cooldown period after MIN_TIME_BETWEEN_UPDATE has passed
+ isOnCooldown = false;
+ }
+ }
+ };
+}
diff --git a/src/backend/controllers/timeJump.ts b/src/backend/controllers/timeJump.ts
new file mode 100644
index 000000000..bf7a1e85c
--- /dev/null
+++ b/src/backend/controllers/timeJump.ts
@@ -0,0 +1,91 @@
+import componentActionsRecord from '../models/masterState';
+import { Status } from '../types/backendTypes';
+import Tree from '../models/tree';
+import { update } from 'lodash';
+
+export default function timeJumpInitiation(mode: Status) {
+ const resetJumpingMode = (): void => {
+ mode.jumping = false;
+ };
+
+ return async function timeJump(targetSnapshot: Tree): Promise {
+ mode.jumping = true;
+ delete mode.navigating;
+ updateReactFiberTree(targetSnapshot).then(() => {
+ document.removeEventListener('mouseover', resetJumpingMode);
+ document.addEventListener('mouseover', resetJumpingMode, { once: true });
+ });
+ };
+}
+
+async function updateReactFiberTree(
+ targetSnapshot,
+ circularComponentTable: Set = new Set(),
+): Promise {
+ if (!targetSnapshot) return;
+ if (circularComponentTable.has(targetSnapshot)) return;
+
+ circularComponentTable.add(targetSnapshot);
+
+ if (targetSnapshot.state === 'stateless' || targetSnapshot.state === 'root') {
+ targetSnapshot.children.forEach((child) => updateReactFiberTree(child, circularComponentTable));
+ return;
+ }
+
+ const { index, state, hooksIndex, hooksState, reducerStates } = targetSnapshot.componentData;
+
+ // Handle class components
+ if (index !== null) {
+ const classComponent = componentActionsRecord.getComponentByIndex(index);
+ if (classComponent !== undefined) {
+ await classComponent.setState(() => state);
+ }
+ targetSnapshot.children.forEach((child) => updateReactFiberTree(child, circularComponentTable));
+ return;
+ }
+
+ // Handle hooks
+ if (hooksIndex !== null) {
+ const functionalComponent = componentActionsRecord.getComponentByIndexHooks(hooksIndex);
+
+ // Handle regular useState hooks
+ if (hooksState) {
+ const stateEntries = Object.entries(hooksState);
+ for (let i = 0; i < stateEntries.length; i++) {
+ const [key, value] = stateEntries[i];
+ if (functionalComponent[i]?.dispatch) {
+ await functionalComponent[i].dispatch(value);
+ }
+ }
+ }
+
+ // Handle reducer hooks
+ if (reducerStates && reducerStates.length > 0) {
+ for (const reducerState of reducerStates) {
+ const { state: targetState, reducerIndex, hookName } = reducerState;
+ const reducer = functionalComponent[reducerIndex];
+
+ if (reducer?.dispatch) {
+ try {
+ // Use SET_STATE action to update the state
+ const setStateAction = {
+ type: 'SET_STATE',
+ payload: targetState,
+ };
+
+ await reducer.dispatch(setStateAction);
+ } catch (error) {
+ console.error('Error updating reducer state:', {
+ hookName,
+ error,
+ componentName: targetSnapshot.name,
+ });
+ }
+ }
+ }
+ }
+
+ targetSnapshot.children.forEach((child) => updateReactFiberTree(child, circularComponentTable));
+ return;
+ }
+}
diff --git a/src/backend/helpers.ts b/src/backend/helpers.ts
deleted file mode 100644
index d190e628b..000000000
--- a/src/backend/helpers.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-/* eslint-disable linebreak-style */
-/* eslint-disable no-shadow */
-/* eslint-disable max-len */
-/* eslint-disable no-console */
-/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-/* eslint-disable @typescript-eslint/no-var-requires */
-/* eslint-disable linebreak-style */
-/* eslint-disable no-inner-declarations, no-loop-func */
-// eslint-disable-next-line import/newline-after-import
-const acorn = require('acorn');
-const jsx = require('acorn-jsx');
-
-const JSXParser = acorn.Parser.extend(jsx());
-
-/**
- * @method throttle
- * @param callback A function to throttle
- * @param ms A number of milliseconds to use as throttling interval
- * @returns A function that limits input function, `callback`, from being called more than once every `ms` milliseconds
- *
- */
-export const throttle = (callback: Function, ms: number): Function => {
- // Initialize boolean flags for callback, throttledFunc
- let isOnCooldown = false;
- let isCallQueued = false;
-
- // Wrap the passed-in function callback in a callback function that "throttles"
- // (puts a limit on) the number of calls that can be made to function
- // in a given period of time (ms)
- const throttledFunc = (): any => {
- // CASE 1: In cooldown mode and we already have a function waiting to be executed,
- // so do nothing
- if (isOnCooldown && isCallQueued) return;
-
- // CASE 2: In cooldown mode, but we have no functions waiting to be executed,
- // so just make note that we now have a call waiting to be executed and return
- if (isOnCooldown) {
- isCallQueued = true;
- return;
- }
-
- // CASE 3: If we are ready to "fire":
- // Execute the function callback immediately
- callback();
- // Initiate a new cooldown period and reset the "call queue"
- isOnCooldown = true;
- isCallQueued = false;
-
- // Declare a function that checks whether we have
- // another function to be executed right after.
- const runAfterTimeout = (): any => {
- if (isCallQueued) {
- isCallQueued = false;
- isOnCooldown = true;
- callback();
- setTimeout(runAfterTimeout, ms);
- return;
- }
- isOnCooldown = false;
- };
-
- setTimeout(runAfterTimeout, ms);
- };
-
- return throttledFunc;
-};
-
-// Helper function to grab the getters/setters from `elementType`
-/**
- * @method getHooksNames
- * @param elementType The fiber `type`, A stringified function of the component, the Fiber whose hooks we want corresponds to
- * @returns An array of strings
- */
-export const getHooksNames = (elementType: string): Array => {
- // Initialize empty object to store the setters and getter
- let ast: any;
- try {
- ast = JSXParser.parse(elementType);
- } catch (e) {
- return ['unknown'];
- }
-
- // hookNames will contain an object with methods (functions)
- const hooksNames: any = {};
-
- // Begin search for hook names, only if ast has a body property.
- while (Object.hasOwnProperty.call(ast, 'body')) {
- let tsCount = 0; // Counter for the number of TypeScript hooks seen (to distinguish in masterState)
- ast = ast.body;
-
- // Statements get all the names of the hooks. For example: useCount, useWildcard, ...
- const statements: Array = [];
- /** All module exports always start off as a single 'FunctionDeclaration' type
- * Other types: "BlockStatement" / "ExpressionStatement" / "ReturnStatement"
- * Iterate through AST of every function declaration
- * Check within each function declaration if there are hook declarations */
- ast.forEach(functionDec => {
- let declarationBody: any;
- if (functionDec.expression?.body) declarationBody = functionDec.expression.body.body; // check if functionDec.expression.body exists, then set declarationBody to functionDec's body
- else declarationBody = functionDec.body?.body ?? [];
- // Traverse through the function's funcDecs and Expression Statements
- declarationBody.forEach((elem: any) => {
- // Hooks will always be contained in a variable declaration
- if (elem.type === 'VariableDeclaration') {
- elem.declarations.forEach((hook: any) => {
- // Parse destructured statements pair
- if (hook.id.type === 'ArrayPattern') {
- hook.id.elements.forEach(hook => {
- statements.push(`_useWildcard${tsCount}`);
- statements.push(hook.name);
- tsCount += 1;
- });
- // Process hook function invocation ?
- } else {
- // hook.init.object is '_useState2', '_useState4', etc.
- // eslint-disable-next-line no-lonely-if
- if (hook?.init?.object?.name) {
- const varName: any = hook.init.object.name;
- if (!hooksNames[varName] && varName.match(/_use/)) {
- hooksNames[varName] = hook.id.name;
- }
- }
- if (hook.id.name !== undefined) {
- statements.push(hook.id.name);
- }
- }
- });
- }
- });
- statements.forEach((el, i) => {
- if (el.match(/_use/)) hooksNames[el] = statements[i + 1];
- });
- });
- return Object.values(hooksNames);
- }
-};
diff --git a/src/backend/index.d.ts b/src/backend/index.d.ts
index d3a3bd998..44b187e1e 100644
--- a/src/backend/index.d.ts
+++ b/src/backend/index.d.ts
@@ -42,9 +42,7 @@
*
*/
-declare module "reactime" {
- function linkFiber(
- container: HTMLElement,
- ): void;
+declare module 'reactime' {
+ function linkFiber(container: HTMLElement): void;
export = linkFiber;
}
diff --git a/src/backend/index.ts b/src/backend/index.ts
index a66e510a4..6f68440e8 100644
--- a/src/backend/index.ts
+++ b/src/backend/index.ts
@@ -1,51 +1,102 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable consistent-return */
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable import/order */
-/* eslint-disable @typescript-eslint/no-unused-vars */
/**
* 'reactime' module has a single export
* @function linkFiber
-*/
-// regenerator runtime supports async functionality
+ */
+// --------------------------START OF IMPORT------------------------------------
+// regenerator runtime supports async functionality : This package implements a fully-functional source transformation that takes the syntax for generators/yield from ECMAScript 2015 or ES2015 and Asynchronous Iteration proposal and spits out efficient JS-of-today (ES5) that behaves the same way.
import 'regenerator-runtime/runtime';
-import linkFiberStart from './linkFiber';
-import timeJumpStart from './timeJump';
-import {
- Snapshot, Mode, MsgData,
-} from './types/backendTypes';
+// linkFiberInitialization (actually uses the function linkFiber but is labeled here as linkFiberInitialization, returns a function). When this returned function is invoked, it checks if devTools is installed, checks if the website is a reactApp, adds event listeners for timetravel, and allows us to obtain the initial FiberRoot Node from react dev tool
+import linkFiber from './routers/linkFiber';
+// timeJumpInitialization (actually uses the function timeJumpInitiation but is labeled here as linkFiberInitialization, returns a function) returns a function that sets jumping to false and handles timetravel feature
+import timeJumpInitialization from './controllers/timeJump';
+import { Snapshot, Status, MsgData } from './types/backendTypes';
+import routes from './models/routes';
-// * State snapshot object initialized here
-const snapShot: Snapshot = {
- tree: null,
- unfilteredTree: null,
-};
-
-const mode: Mode = {
+// -------------------------INITIALIZE MODE--------------------------
+/** Indicate if mode is jumping/not jumping or navigating during jumping */
+const mode: Status = {
jumping: false,
- paused: false,
};
-// linkFiber is now assigned the default function exported from the file linkFiber.ts
-const linkFiber = linkFiberStart(snapShot, mode);
-// timeJump is now assigned the default function exported from the file timeJump.ts
-const timeJump = timeJumpStart(mode);
+// ---------------------INITIALIZE LINKFIBER & TIMEJUMP-------------------------
+// linkFiber is now assigned the default ASYNC function exported from the file linkFiber.ts
+const linkFiberInit = linkFiber(mode);
+// timeJump is now assigned the default ASYNC function exported from the file timeJump.ts
+const timeJump = timeJumpInitialization(mode);
+
+/**
+ * Invoke linkFiber to perform the following:
+ * 1. Check for ReactDev installation, valid target React App
+ * 2. Obtain the initial ReactFiber Tree from target React App
+ * 3. Send a snapshot of ReactFiber Tree to frontend/Chrome Extension
+ */
+linkFiberInit();
-// * Event listener for time-travel actions
-window.addEventListener('message', ({ data: { action, payload } }: MsgData) => {
+// --------------INITIALIZE EVENT LISTENER FOR TIME TRAVEL----------------------
+/**
+ * On the chrome extension, if user click left/right arrow or the play button (a.k.a time travel functionality), frontend will send a message `jumpToSnap` with payload of the cached snapShot tree at the current step
+ * 1. Set jumping mode to true => dictate we are jumping => no new snapshot will be sent to frontend
+ * 2. If navigate to a new route during jumping => cache timeJump in navigate.
+ * 3. If not navigate during jumping => invoke timeJump to update ReactFiber tree with cached data from the snapshot payload
+ */
+window.addEventListener('message', async ({ data: { action, payload } }: MsgData) => {
switch (action) {
case 'jumpToSnap':
- timeJump(payload, true); // * This sets state with given payload
+ // Set mode to jumping to prevent snapShot being sent to frontEnd
+ // NOTE: mode.jumping is set to false inside the timeJump.ts
+ mode.jumping = true;
+ // Check if we are navigating to another route
+ const navigating: boolean = routes.navigate(payload.route);
+ // If need to navigate
+ if (navigating) {
+ // Cache timeJump function in mode.navigating => which will be invoked during onCommitFiberRoot:
+ mode.navigating = () => timeJump(payload);
+ }
+ // If not navitating, invoke timeJump immediately to update React Application FiberTree based on the snapshotTree payload
+ else {
+ await timeJump(payload); // * This sets state with given payload
+ }
break;
+ // case 'reinitialize':
+ // console.log('backend reinitialize received, performing checks again');
+ // let devTools;
+ // while (!devTools) {
+ // devTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
+ // }
+ // console.log('backend react devtools: ', devTools);
+ // // If React Devtools is not installed, object will be undefined.
+ // if (!devTools) return;
+ // // If React Devtools is installed, send a message to front end.
- case 'setPause':
- mode.paused = payload;
- break;
+ // console.log(
+ // 'backend react devtools check passed, sending devToolsInstalled to contentScript',
+ // );
+ // window.postMessage(
+ // {
+ // action: 'devToolsInstalled',
+ // payload: 'devToolsInstalled',
+ // },
+ // '*',
+ // );
+ // const reactInstance = devTools.renderers.get(1);
+ // // If target application is not a React App, this will return undefined.
+ // if (!reactInstance) {
+ // return;
+ // }
+ // console.log('backend react instance check passed, sending aReactApp to contentScript');
+ // // If target application is a React App, send a message to front end.
+ // window.postMessage(
+ // {
+ // action: 'aReactApp',
+ // payload: 'aReactApp',
+ // },
+ // '*',
+ // );
+
+ linkFiberInit();
+ break;
default:
break;
}
});
-// connect to dev tools and new fiber,
-// invokes anonymous function from linkFiber.ts set to linkFiber on line 30
-linkFiber();
diff --git a/src/backend/linkFiber.ts b/src/backend/linkFiber.ts
deleted file mode 100644
index 4ee60c6ed..000000000
--- a/src/backend/linkFiber.ts
+++ /dev/null
@@ -1,414 +0,0 @@
-/* eslint-disable guard-for-in */
-/* eslint-disable no-restricted-syntax */
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable max-len */
-/* eslint-disable indent */
-/* eslint-disable brace-style */
-/* eslint-disable comma-dangle */
-/* eslint-disable no-underscore-dangle */
-/* eslint-disable func-names */
-/* eslint-disable no-use-before-define */
-/* eslint-disable no-param-reassign */
-/* eslint-disable-next-line no-mixed-operators */
-
-// import typescript types
-import {
- // tree
- Snapshot,
- // jump, pause
- Mode,
- // array of state and component
- HookStates,
- // object with tree structure
- Fiber,
-} from './types/backendTypes';
-// import function that creates a tree
-import Tree from './tree';
-// passes the data down to its components
-import componentActionsRecord from './masterState';
-import routes from './routes';
-
-// throttle returns a function that can be called any number of times (possibly in quick succession) but will only invoke the callback at most once every x ms
-// getHooksNames - helper function to grab the getters/setters from `elementType`
-import { throttle, getHooksNames } from './helpers';
-
-// Set global variables to use in exported module and helper functions
-declare global {
- interface Window {
- __REACT_DEVTOOLS_GLOBAL_HOOK__?: any;
- __REDUX_DEVTOOLS_EXTENSION__?: any;
- }
-}
-let fiberRoot = null;
-let doWork = true;
-const circularComponentTable = new Set();
-let rtidCounter = 0;
-let rtid = null;
-
-/**
- * @method sendSnapshot
- * @param snap The current snapshot
- * @param mode The current mode (i.e. jumping, time-traveling, or paused)
- * @return Nothing.
- *
- * Middleware: Gets a copy of the current snap.tree and posts a recordSnap message to the window
- */
-function sendSnapshot(snap: Snapshot, mode: Mode): void {
- // Don't send messages while jumping or while paused
- if (mode.jumping || mode.paused) return;
- // If there is no current tree creates a new one
- if (!snap.tree) {
- snap.tree = new Tree('root', 'root');
- }
- const payload = snap.tree.cleanTreeCopy();
- payload.route = routes.addRoute(window.location.href);
- // method safely enables cross-origin communication between Window objects;
- // e.g., between a page and a pop-up that it spawned, or between a page
- // and an iframe embedded within it.
- // this postMessage will be sending the most up-to-date snapshot of the current React Fiber Tree
- // the postMessage action will be received on the content script to later update the tabsObj
- // this will fire off everytime there is a change in test application
-
- window.postMessage(
- {
- action: 'recordSnap',
- payload,
- },
- '*'
- );
-}
-
-/**
- * @function updateSnapShotTree
- * @param snap The current snapshot
- * @param mode The current mode (i.e. jumping, time-traveling, or paused)
- * Middleware: Updates snap object with latest snapshot, using @sendSnapshot
- */
-
-// updating tree depending on current mode on the panel (pause, etc)
-function updateSnapShotTree(snap: Snapshot, mode: Mode): void {
- // this is the currently active root fiber(the mutable root of the tree)
- if (fiberRoot) {
- const { current } = fiberRoot;
- // Clears circular component table
- circularComponentTable.clear();
- // creates snapshot that is a tree based on properties in fiberRoot object
- componentActionsRecord.clear();
- snap.tree = createTree(current);
- }
- // sends the updated tree back
- sendSnapshot(snap, mode);
-}
-
-/**
- * @method traverseHooks
- * @param memoizedState memoizedState property on a stateful functional component's FiberNode object
- * @return An array of array of HookStateItem objects
- *
- * Helper function to traverse through memoizedState and inject instrumentation to update our state tree
- * every time a hooks component changes state
- */
-function traverseHooks(memoizedState: any): HookStates {
- const hooksStates: HookStates = [];
- while (memoizedState?.queue) {
- // the !== null conditional is necessary here for correctly displaying react hooks because TypeScript recognizes 0 and "" as null - DO NOT REMOVE
- if (memoizedState.memoizedState !== null) {
- hooksStates.push({
- component: memoizedState.queue,
- state: memoizedState.memoizedState,
- });
- }
- memoizedState = memoizedState.next !== memoizedState ? memoizedState.next : null;
- }
- return hooksStates;
-}
-
-/**
- * @method createTree
- * @param currentFiber A Fiber object
- * @param tree A Tree object, default initialized to an instance given 'root' and 'root'
- * @param fromSibling A boolean, default initialized to false
- * @return An instance of a Tree object
- * This is a recursive function that runs after every Fiber commit using the following logic:
- * 1. Traverse from FiberRootNode
- * 2. Create an instance of custom Tree class
- * 3. Build a new state snapshot
- */
-// This runs after every Fiber commit. It creates a new snapshot
-const exclude = ['alternate', '_owner', '_store', 'get key', 'ref', '_self', '_source', 'firstBaseUpdate', 'updateQueue', 'lastBaseUpdate', 'shared', 'responders', 'pending', 'lanes', 'childLanes', 'effects', 'memoizedState', 'pendingProps', 'lastEffect', 'firstEffect', 'tag', 'baseState', 'baseQueue', 'dependencies', 'Consumer', 'context', '_currentRenderer', '_currentRenderer2', 'mode', 'flags', 'nextEffect', 'sibling', 'create', 'deps', 'next', 'destroy', 'parentSub', 'child', 'key', 'return', 'children', '$$typeof', '_threadCount', '_calculateChangedBits', '_currentValue', '_currentValue2', 'Provider', '_context', 'stateNode', 'elementType', 'type'];
-
-// This recursive function is used to grab the state of children components
-// and push them into the parent componenent
-// react elements throw errors on client side of application - convert react/functions into string
-function convertDataToString(newObj, oldObj, depth = 0) {
- const newPropData = oldObj || {};
- for (const key in newObj) {
- if (typeof newObj[key] === 'function') {
- newPropData[key] = 'function';
- } else if (exclude.includes(key) === true) {
- newPropData[key] = 'reactFiber';
- return newPropData;
- } else if (typeof newObj[key] === 'object' && exclude.includes(key) !== true) {
- newPropData[key] = depth > 10 ? 'convertDataToString reached max depth' : convertDataToString(newObj[key], null, depth + 1);
- } else if (exclude.includes(key) !== true) {
- newPropData[key] = newObj[key];
- }
- }
- return newPropData;
-}
-// Every time a state change is made in the accompanying app, the extension creates a
-// Tree “snapshot” of the current state, and adds it to the current “cache” of snapshots in the extension
-function createTree(
- currentFiber: Fiber,
- tree: Tree = new Tree('root', 'root'),
- fromSibling = false
-) {
- // Base case: child or sibling pointed to null
- if (!currentFiber) return null;
- if (!tree) return tree;
- // These have the newest state. We update state and then
- // called updateSnapshotTree()
- const {
- sibling,
- stateNode,
- child,
- // with memoizedState we can grab the root type and construct an Abstract Syntax Tree from the hooks structure using Acorn in order to extract the hook getters and match them with their corresponding setters in an object
- memoizedState,
- memoizedProps,
- elementType,
- tag,
- actualDuration,
- actualStartTime,
- selfBaseDuration,
- treeBaseDuration,
- dependencies,
- _debugHookTypes,
- } = currentFiber;
-
-// if (currentFiber.tag === 10) {
-// const queue = [currentFiber];
-// while (queue.length > 0) {
-// const tempFiber = queue.shift();
-// if (tempFiber.tag === 0) console.log(tempFiber);
-// if (tempFiber.sibling) {
-// queue.push(tempFiber.sibling);
-// }
-// if (tempFiber.child) {
-// queue.push(tempFiber.child);
-// }
-// }
-// }
-
-// check to see if we can get the information we were looking for
-// need to figure out what tag is
- if (tag === 5) {
- try {
- if (memoizedProps.children && memoizedProps.children[0]?._owner?.memoizedProps !== undefined) {
- const propsData = memoizedProps.children[0]._owner.memoizedProps;
- const newPropData = convertDataToString(propsData, tree.componentData.props ? tree.componentData.props : null);
- tree.componentData = {
- ...tree.componentData,
- props: newPropData
- };
- }
- } catch (error) {
- console.log(error);
- }
- }
-
- let newState: any | { hooksState?: any[] } = {};
- let componentData: {
- hooksState?: any[];
- hooksIndex?: number;
- index?: number;
- actualDuration?: number;
- actualStartTime?: number;
- selfBaseDuration?: number;
- treeBaseDuration?: number;
- props?: any,
- context?: any,
- } = {};
- let componentFound = false;
-
- // check to see if the parent component has any state/props
- if (memoizedProps) {
- componentData.props = convertDataToString(memoizedProps, null);
- }
-
- // if the component uses the useContext hook, we want to grab the co text object and add it to the componentData object for that fiber
- if (tag === 0 && _debugHookTypes) {
- componentData.context = convertDataToString(dependencies?.firstContext?.memoizedValue, null);
- }
- // Check if node is a stateful class component
- if (stateNode && stateNode.state && (tag === 0 || tag === 1 || tag === 2)) {
- // Save component's state and setState() function to our record for future
- // time-travel state changing. Add record index to snapshot so we can retrieve.
- componentData.index = componentActionsRecord.saveNew(
- stateNode.state,
- stateNode,
- );
- newState = stateNode.state;
- componentFound = true;
- }
- let hooksIndex;
-
- // Check if node is a hooks useState function
- // REGULAR REACT HOOKS
- if (
- memoizedState
- && (tag === 0 || tag === 1 || tag === 2 || tag === 10)
- ) {
- if (memoizedState.queue) {
- // Hooks states are stored as a linked list using memoizedState.next,
- // so we must traverse through the list and get the states.
- // We then store them along with the corresponding memoizedState.queue,
- // which includes the dispatch() function we use to change their state.
- const hooksStates = traverseHooks(memoizedState);
- const hooksNames = getHooksNames(elementType.toString());
-
-
- hooksStates.forEach((state, i) => {
- hooksIndex = componentActionsRecord.saveNew(
- state.state,
- state.component,
- );
- componentData.hooksIndex = hooksIndex;
- if (!newState) {
- newState = { hooksState: [] };
- } else if (!newState.hooksState) {
- newState.hooksState = [];
- }
- newState.hooksState.push({ [hooksNames[i]]: state.state });
- componentFound = true;
- });
- }
- }
-
- // This grabs stateless components
- if (!componentFound && (tag === 0 || tag === 1 || tag === 2)) {
- newState = 'stateless';
- }
-
- // Adds performance metrics to the component data
- componentData = {
- ...componentData,
- actualDuration,
- actualStartTime,
- selfBaseDuration,
- treeBaseDuration,
- };
-
- let newNode = null;
-
- // We want to add this fiber node to the snapshot
- if (componentFound || newState === 'stateless' && !newState.hooksState) {
- if (currentFiber.child?.stateNode?.setAttribute) {
- rtid = `fromLinkFiber${rtidCounter}`;
- // rtid = rtidCounter;
- // check if rtid is already present
- // remove existing rtid before adding a new one
- if (currentFiber.child.stateNode.classList.length > 0) {
- const lastClass = currentFiber.child.stateNode.classList[
- currentFiber.child.stateNode.classList.length - 1
- ];
- if (lastClass.includes('fromLinkFiber')) {
- currentFiber.child.stateNode.classList.remove(lastClass);
- }
- }
- currentFiber.child.stateNode.classList.add(rtid);
- }
- rtidCounter += 1;
- // checking if tree fromSibling is true
- if (fromSibling) {
- newNode = tree.addSibling(
- newState,
- elementType ? elementType.name : 'nameless',
- componentData,
- rtid,
- );
- } else {
- newNode = tree.addChild(
- newState,
- elementType ? elementType.name : 'nameless',
- componentData,
- rtid,
- );
- }
- } else {
- newNode = tree;
- }
-
- // Recurse on children
-
- if (child && !circularComponentTable.has(child)) {
- // If this node had state we appended to the children array,
- // so attach children to the newly appended child.
- // Otherwise, attach children to this same node.
- circularComponentTable.add(child);
- createTree(child, newNode);
- }
-
- // Recurse on siblings
- if (sibling && !circularComponentTable.has(sibling)) {
- circularComponentTable.add(sibling);
- createTree(sibling, newNode, true);
- }
- return tree;
-}
-
-/**
- * @method linkFiber
- * @param snap The current snapshot
- * @param mode The current mode (i.e. jumping, time-traveling, or paused)
- * @return a function to be invoked by index.js that initiates snapshot monitoring
- * linkFiber contains core module functionality, exported as an anonymous function.
- */
- export default (snap: Snapshot, mode: Mode): (() => void) => {
- // checks for visiblity of document
- function onVisibilityChange(): void {
- // hidden property = background tab/minimized window
- doWork = !document.hidden;
- }
- return () => {
- // react devtools global hook is a global object that was injected by the React Devtools content script, allows access to fiber nodes and react version
- const devTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
- // check if reactDev Tools is installed
- if (!devTools) { return; }
- window.postMessage({
- action: 'devToolsInstalled',
- payload: 'devToolsInstalled'
- }, '*');
- // reactInstance returns an object of the react, 1st element in map
- const reactInstance = devTools.renderers.get(1);
- // if no React Instance found then target is not a compatible app
- if (!reactInstance) { return; }
- window.postMessage({
- action: 'aReactApp',
- payload: 'aReactApp'
- }, '*');
-
- const throttledUpdateSnapshot = throttle(() => { updateSnapShotTree(snap, mode); }, 70);
- document.addEventListener('visibilitychange', onVisibilityChange);
-
- if (reactInstance && reactInstance.version) {
- fiberRoot = devTools.getFiberRoots(1).values().next().value;
- // React has inherent methods that are called with react fiber
- // we attach new functionality without compromising the original work that onCommitFiberRoot does
- const addOneMoreStep = function (original) {
- return function (...args) {
- // eslint-disable-next-line prefer-destructuring
- fiberRoot = args[1];
- // this is the additional functionality we added
- if (doWork) {
- throttledUpdateSnapshot();
- }
- // after our added work is completed we invoke the original function
- return original(...args);
- };
- };
- devTools.onCommitFiberRoot = addOneMoreStep(devTools.onCommitFiberRoot);
-
- throttledUpdateSnapshot(); // only runs on start up
- }
- };
-};
diff --git a/src/backend/masterState.ts b/src/backend/masterState.ts
deleted file mode 100644
index ef538e84c..000000000
--- a/src/backend/masterState.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-
-/* eslint-disable no-plusplus */
-/* eslint-disable guard-for-in */
-/* eslint-disable no-restricted-syntax */
-
-import {
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- HookStateItem, // obj with state and component
- HookStates, // array of hook state items
-} from './types/backendTypes';
-
-// HookState is an array that contains a "component" for
-// every single state change that occurs in the app
-// Information on these components include ComponentData as well as state
-// For class components, there will be one "component" for each snapshot
-// For functional components that utilize Hooks, there will be one "component"
-// for each setter/getter every time we have a new snapshot
-let componentActionsRecord: HookStates = [];
-let index: number;
-index = 0;
-
-export default {
- clear: () => {
- componentActionsRecord = [];
- index = 0;
- },
- // adds new component to ComponentActionsRecord
- saveNew: (state, component): number => {
- componentActionsRecord[index] = { state, component };
- index++;
-
- return index - 1;
- },
- getRecordByIndex: (inputIndex: number): HookStateItem => componentActionsRecord[inputIndex],
- // this is used for class components -
- /* inputIndex will always be a fixed number (coming in timeJump.ts) */
- getComponentByIndex: (inputIndex: number): any => (
- componentActionsRecord[inputIndex]
- ? componentActionsRecord[inputIndex].component
- : undefined),
- // this is used for react hooks - hooks will be passed in as an array from timeJump.ts
- getComponentByIndexHooks: (inputIndex: Array = []): Array => {
- const multiDispatch = [];
- for (let i = 0; i < inputIndex.length; i++) {
- if (componentActionsRecord[inputIndex[i]]) {
- multiDispatch.push(componentActionsRecord[inputIndex[i]].component);
- }
- }
- return multiDispatch;
- },
-};
diff --git a/src/backend/models/filterConditions.ts b/src/backend/models/filterConditions.ts
new file mode 100644
index 000000000..cf043a2b7
--- /dev/null
+++ b/src/backend/models/filterConditions.ts
@@ -0,0 +1,125 @@
+import {
+ FunctionComponent,
+ ClassComponent,
+ IndeterminateComponent, // Before we know whether it is function or class
+ ContextProvider,
+ WorkTag,
+} from '../types/backendTypes';
+
+export const allowedComponentTypes: Set = new Set([
+ FunctionComponent,
+ ClassComponent,
+ ContextProvider,
+ IndeterminateComponent,
+]);
+export const nextJSDefaultComponent = new Set([
+ 'Root',
+ 'Head',
+ 'AppContainer',
+ 'Container',
+ 'ReactDevOverlay',
+ 'ErrorBoundary',
+ 'AppRouterContext',
+ 'SearchParamsContext',
+ 'PathnameContextProviderAdapter',
+ 'PathnameContext',
+ 'RouterContext',
+ 'HeadManagerContext',
+ 'ImageConfigContext',
+ 'RouteAnnouncer',
+ 'Portal',
+]);
+
+export const remixDefaultComponents = new Set([
+ 'RemixBrowser',
+ 'Remix',
+ 'RemixErrorBoundary',
+ 'RouterProvider',
+ 'DataRouter',
+ 'DataRouterState',
+ 'RenderErrorBoundary',
+ 'Meta',
+ 'V1Meta',
+ 'Links',
+ 'RemixRoute',
+ 'Outlet',
+ 'ScrollRestoration2',
+ 'script',
+ 'Scripts',
+ 'LiveReload2',
+]);
+/**
+ * A set of excluded props and variable name
+ */
+export const exclude = new Set([
+ 'alternate',
+ 'basename',
+ 'baseQueue',
+ 'baseState',
+ 'child',
+ 'childLanes',
+ 'children',
+ 'Consumer',
+ 'context',
+ 'create',
+ 'deps',
+ 'dependencies',
+ 'destroy',
+ 'dispatch',
+ 'location',
+ 'effects',
+ 'element',
+ 'elementType',
+ 'firstBaseUpdate',
+ 'firstEffect',
+ 'flags',
+ 'get key',
+ 'getState',
+ 'hash',
+ 'key',
+ 'lanes',
+ 'lastBaseUpdate',
+ 'lastEffect',
+ 'liftedStore',
+ 'navigator',
+ 'memoizedState',
+ 'mode',
+ 'navigationType',
+ 'next',
+ 'nextEffect',
+ 'pending',
+ 'parentSub',
+ 'pathnameBase',
+ 'pendingProps',
+ 'Provider',
+ 'updateQueue',
+ 'ref',
+ 'replaceReducer',
+ 'responders',
+ 'return',
+ 'route',
+ 'routeContext',
+ 'search',
+ 'shared',
+ 'sibling',
+ 'state',
+ 'store',
+ 'subscribe',
+ 'subscription',
+ 'stateNode',
+ 'tag',
+ 'type',
+ '_calculateChangedBits',
+ '_context',
+ '_currentRenderer',
+ '_currentRenderer2',
+ '_currentValue',
+ '_currentValue2',
+ '_owner',
+ '_self',
+ '_source',
+ '_store',
+ '_threadCount',
+ '$$typeof',
+ '@@observable',
+]);
diff --git a/src/backend/models/masterState.ts b/src/backend/models/masterState.ts
new file mode 100644
index 000000000..ec5789186
--- /dev/null
+++ b/src/backend/models/masterState.ts
@@ -0,0 +1,53 @@
+// The HookState data structure is an array that holds the current value of a hook's state, as well as a dispatch function that is used to update that state.
+// Information on these components include ComponentData as well as state
+// For class components, there will be one "component" for each snapshot
+// For functional components that utilize Hooks, there will be one "component"
+
+// for each setter/getter every time we have a new snapshot
+let componentActionsRecord = [];
+
+export default {
+ /**
+ * @function clear - Clears componentActionsRecord
+ */
+ clear: (): void => {
+ // console.log(componentActionsRecord);
+ componentActionsRecord = [];
+ },
+
+ /**
+ * @function saveNew - Adds a new component to the componentActionsRecord array and returns its index.
+ * @param component - An object that contains bound update method. For class component, the udpate method is `setState`. For functional component, the update method is `dispatch`.
+ * @returns - the index of the newly added component
+ */
+ saveNew: (component): number => {
+ return componentActionsRecord.push(component) - 1;
+ },
+ // ----------------------------CLASS COMPONENT--------------------------------
+ /**
+ * @function getComponentByIndex - This function is used for stateful Class Component to retrieve an object that has the bound setState method
+ * @param inputIndex - index of component inside `componentActionsRecord` coming from `timeJump.ts`
+ * @returns - an object containing the bound setState method
+ */
+ getComponentByIndex: (inputIndex: number): any | undefined => componentActionsRecord[inputIndex],
+
+ //---------------------------FUNCTIONAL COMPONENT-----------------------------
+ /**
+ * @function getComponentByIndexHooks - This function is used for Functional Component to retrieve an array of objects that have the bound dispatch methods.
+ * @param inputIndex - index of component inside `componentActionsRecord` coming from `timeJump.ts`
+ * @returns - an array of objects containing the bound dispatch methods
+ */
+ getComponentByIndexHooks: (inputIndex: Array): any[] =>
+ inputIndex
+ // filter for only index exists in componentActionsRecord
+ .filter((index) => index in componentActionsRecord)
+ // get the corresponding dispath method at position index
+ .map((index) => componentActionsRecord[index]),
+
+ // ----------------------------------DEBUGGING--------------------------------
+ /**
+ * @function getAllComponents - This method is used for debugging purpose to access the array of setState/dispatch methods
+ * @returns - an array of objects containing the bound methods for updating state
+ */
+ getAllComponents: (): any[] => componentActionsRecord,
+};
diff --git a/src/backend/models/routes.ts b/src/backend/models/routes.ts
new file mode 100644
index 000000000..60f57d98e
--- /dev/null
+++ b/src/backend/models/routes.ts
@@ -0,0 +1,123 @@
+/**
+ * @class Route instances are created by the addRoute method on Routes. A Route instance has two properties: the url of the route and a unique id.
+ */
+
+export class Route {
+ constructor(
+ public url: string,
+ public id: number,
+ ) {
+ this.url = url;
+ this.id = id;
+ }
+}
+
+/**
+ * @class An instance of this class is the default export from routes.ts. It includes the logic that allows Reactime to work with target applications built with React Router. The addRoute method is invoked in linkFiber.ts within the sendSnapshot function. The navigate method is invoked in timeJump.ts immediately before invoking jump.
+ */
+
+export class Routes {
+ /**
+ * @property A stack of visited routes that matches the browser history stack.
+ * The dummyURL is used to initialize the routeHistory array with a default route at index 0, which serves as
+ a placeholder. This is necessary because the routeHistory array needs to mirror the browser's history
+ stack, and the browser's history stack always has at least one entry when the page is loaded. Once the user
+ navigates to a new route, the dummyURL will be replaced with the first real route.
+ */
+
+ routeHistory: Route[] = [new Route('dummyURL', 0)];
+
+ /**
+ * @property When a new route is added to the history, a new Route object is created with a unique id value, which is incremented for each new route. This is useful because it allows us to compare routes in a more robust way, using both the URL and the ID to ensure that we're looking at the correct route in the history array. In the navigate method, for example, the targetIndex is found by searching for the index of the route with the matching url and id
+ */
+ id = 0;
+
+ /**
+ * @property Tracks the index of the current route in the routeHistory stack. This property is used to ensure that the routeHistory stack always matches the browser history stack. When a user navigates to a new route, the current property is updated to reflect the new index of the current route in the routeHistory stack. When a user performs a time jump, the current property is updated to reflect the new index of the current route in the routeHistory stack as well.
+ */
+ current = 0;
+
+ /**
+ * @method addRoute - Method to add a new route to the route history array. Also ensures that the `routeHistory` stack always matches the browser history stack.
+ * @param url - A url string.
+ * @returns Either the current route if the user has not navigated away from it or a new instance of a route constructed from the url.
+ *
+ *
+ */
+
+ addRoute(url: string): Route {
+ // Get the current route
+ const currentRoute: Route = this.routeHistory[this.current];
+ // Check if the new url is different from the current url
+ const isNavigating = currentRoute.url !== url;
+ if (isNavigating) {
+ // Check if current is not equal to routeHistory.length - 1 becuase if it doesnt, we need to rebuild history
+ if (this.current !== this.routeHistory.length - 1) {
+ // Rebuild the browser history with the new url
+ this.rebuildHistory(url);
+ }
+ // Create a new Route object with the new url and id
+ const newRoute = new Route(url, ++this.id);
+ // Add the new Route object to the route history array
+ this.routeHistory.push(newRoute);
+ // Update the current index to pointer to the new Route object
+ this.current = this.routeHistory.length - 1;
+ // Return the new Route object
+ return newRoute;
+ }
+ // If the new url is the same as the current url, return the current route
+ return currentRoute;
+ }
+
+ /**
+ * @method rebuildHistory
+ * @param url - A url string.
+ *
+ * Rebuilds the browser history stack using the copy of the stack maintained in the `routeHistory` stack. https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState, https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
+ */
+ private rebuildHistory(url: string): void {
+ // Replace window history with the next route
+ window.history.replaceState('', '', this.routeHistory[this.current + 1].url);
+ // For each route in routeHistory after the next route, add to window history
+ for (let i = this.current + 2; i < this.routeHistory.length; i += 1) {
+ window.history.pushState('', '', this.routeHistory[i].url);
+ }
+ // Add the new url to window history
+ window.history.pushState('', '', url);
+ }
+
+ /**
+ * This method will perform the following:
+ * 1. Evaluate if user need to navigate to another route
+ * 2. If navigation is needed, perform navigation and return true
+ * 3. Else return false
+ * @param route - The target route in the `routeHistory` stack that is being navigated to.
+ * @returns A boolean indicating whether or not a new route was navigated to.
+ *
+ * Invokes history.go passing in the delta between the current route and the target route. https://developer.mozilla.org/en-US/docs/Web/API/History/go
+ */
+ navigate(targetRoute: Route): boolean {
+ // Find the index of the target route in the route history array
+ const targetIndex: number = this.routeHistory.findIndex(
+ (route) => route.url === targetRoute.url && route.id === targetRoute.id,
+ );
+ // If the target route is not found, throw an error
+ if (targetIndex === -1) {
+ throw new Error('Error at Routes.navigate: targetIndex is undefined');
+ }
+ // Calculate the difference in index between the current route and the target route
+ const delta: number = targetIndex - this.current;
+ // Update the current route index to the index of the target route
+ this.current += delta;
+ // If the difference is not 0, navigate to the target route using window.history.go() method
+ if (delta !== 0) {
+ window.history.go(delta);
+ // Return true to indicate that the navigation was successful
+ return true;
+ }
+ // If the difference is 0, return false to indicate that no navigation occurred
+ return false;
+ }
+}
+
+export default new Routes();
diff --git a/src/backend/models/tree.ts b/src/backend/models/tree.ts
new file mode 100644
index 000000000..c17397d6c
--- /dev/null
+++ b/src/backend/models/tree.ts
@@ -0,0 +1,145 @@
+import { Route } from './routes';
+import { ComponentData } from '../types/backendTypes';
+
+/** ComponentNames is used to store a mapping between a component's unique identifier and its name. This mapping is used to reconstruct the component instances during deserialization.*/
+let componentNames = {};
+let rootTree;
+
+// Making a deep clone of state becuase we want to make a copy
+/**
+ * @function serializeState - In the context of React, state is often used to store data that determines the behavior and appearance of a component. By serializing the state, we can preserve the component's data across page refreshes, server-side rendering, and other transitions. Additionally, by serializing the state and passing it to a child component, we can create a deep clone of the state, which allows the child component to manipulate the state without affecting the original component. This is useful in situations where we want to keep the state of the parent component immutable, but still allow child components to modify a copy of the state.
+ * @param state - Object that contains the current state of the application or system that needs to be serialized.
+ * @returns - Depclone of the passed in state. If there is any circulate state, return 'circularState'
+ */
+export function serializeState(state) {
+ try {
+ // makes a deep clone
+ return JSON.parse(JSON.stringify(state));
+ } catch (e) {
+ // if there is an error, that means there is circular state i.e state that depends on itself
+ return 'circularState';
+ }
+}
+
+/**
+ * Tree.name's come from the name of the component, but these names should be unique. When a second component
+ * is used in a single tree, this function is called in checkForDuplicates to the change the Tree.name of the
+ * first component to have a "1" at the end.
+ *
+ * @param tree A tree class instance
+ * @param name The name being checked
+ */
+function changeFirstInstanceName(tree: Tree, name: string): void {
+ for (const child of tree.children) {
+ if (child.name === name) {
+ child.name += 1;
+ return;
+ } else {
+ changeFirstInstanceName(child, name);
+ }
+ }
+}
+
+/**
+ * This is the current snapshot that is being sent to the snapshots array.
+ * Creates a Tree
+ * @param state - the current state of the component represented by this node.
+ * @param name - the name of the component represented by this node.
+ * @param componentData - an object containing the props of the component represented by this node.
+ * @param chilren - an array of child nodes.
+ * @param parent - a reference to the parent node.
+ * @param isExpanded - a boolean value indicating whether the node is expanded in the UI.
+ * @param rtid - a unique identifier for the node.
+ * @param route - an object representing the route associated with the node.
+ */
+class Tree {
+ state: string | {}; // TODO: should change this to stateless | statefull | root
+
+ name: string;
+
+ componentData: ComponentData | {};
+
+ children: Tree[];
+
+ isExpanded: boolean = true;
+
+ rtid: string | null;
+
+ route?: Route;
+
+ // Duplicate names: add a unique number ID
+ // Create an object 'componentNames' to store each component name as a key and it's frequency of use as its value
+ // When a new component is made on the tree, check if the new component's name already exists in 'componentNames' (possibly with the .hasOwnProperty method)
+ // If the name already exists, add its value (an integer) to the name
+ // Also, increment the value after
+ // If not, create the new component and also a new key: value pair in 'componentNames' with the component's name as the key and 0 as its value
+ // EXAMPLE OF COMPONENTNAMES OBJECT: {editableInput: 1, Provider: 0, etc}
+
+ constructor(
+ state: string | {},
+ name = 'nameless',
+ componentData: ComponentData | {} = {},
+ rtid: string | null = null,
+ ) {
+ this.children = [];
+ this.componentData = componentData;
+ this.state = state === 'root' ? 'root' : serializeState(state);
+ this.name = name;
+ this.rtid = rtid;
+ }
+
+ // Returns a unique name ready to be used for when new components gets added to the tree
+ /**
+ * @function checkForDuplicates - Generates a unique name for a component that is being added to the component tree
+ * @param name Component name
+ * @returns Unique name for Tree.name
+ */
+ checkForDuplicates(name: string): string {
+ if (this.name === 'root') {
+ componentNames = {};
+ rootTree = this;
+ }
+
+ /**
+ * If a duplicate name is found, adds a number to the end of the name so it'll show up uniquely
+ * in the component map. For example, if only one "Box" component is found, it's name will be "Box".
+ * However, after a second "Box" component is found, the first box will be renamed "Box1" and the
+ * second box will be named "Box2". When the third box is found it'll be named "Box3", and so on.
+ */
+ componentNames[name] = componentNames[name] + 1 || 1;
+
+ if (componentNames[name] === 2) {
+ changeFirstInstanceName(rootTree, name);
+ }
+
+ if (componentNames[name] > 1) name += componentNames[name];
+
+ return name;
+ }
+
+ /**
+ *
+ * @param state - string if root, serialized state otherwise
+ * @param name - name of child
+ * @param componentData - props
+ * @param rtid - ??
+ * @returns - return new tree instance that is child
+ */
+ addChild(
+ state: Tree['state'],
+ name: Tree['name'],
+ componentData: Tree['componentData'],
+ rtid: Tree['rtid'],
+ ): Tree {
+ // Get unique name by invoking checkForDuplicates method
+ const uniqueName = this.checkForDuplicates(name);
+ // Instantiates new child Tree with state, uniqueName, componentData and rtid
+ const newChild: Tree = new Tree(state, uniqueName, componentData, rtid);
+ // adds newChild to children array
+ this.children.push(newChild);
+ // return newChild
+ return newChild;
+ }
+}
+
+export default Tree;
diff --git a/src/backend/module.d.ts b/src/backend/module.d.ts
index 4a40bcdeb..5f8abd83e 100644
--- a/src/backend/module.d.ts
+++ b/src/backend/module.d.ts
@@ -10,9 +10,3 @@ declare module 'core-js';
// the resulting code uses regen runtime to run
// https://stackoverflow.com/questions/65378542/what-is-regenerator-runtime-npm-package-used-for
declare module 'regenerator-runtime/runtime';
-// Acorn is a jsx parser that was experimental to be faster than than the react.js jsx parser,
-// however is not maintained at this time, last update was more than one year ago 10-5-21
-declare module 'acorn-jsx';
-// Traspiler to traspile code to JSX AST but to use with regular es5 compliant js,
-// still needs babel and buble trasnpilers which use acorn-jsx under the hood
-declare module 'acorn';
diff --git a/src/backend/package-lock.json b/src/backend/package-lock.json
deleted file mode 100644
index 2a04c66d3..000000000
--- a/src/backend/package-lock.json
+++ /dev/null
@@ -1,491 +0,0 @@
-{
- "name": "dev-reactime",
- "version": "4.0.0",
- "lockfileVersion": 2,
- "requires": true,
- "packages": {
- "": {
- "name": "dev-reactime",
- "version": "4.0.0",
- "license": "MIT",
- "dependencies": {
- "acorn": "^7.1.0",
- "acorn-jsx": "^5.0.2",
- "cookie-parser": "^1.4.5",
- "core-js": "^3.6.5",
- "fs": "0.0.1-security"
- },
- "peerDependencies": {
- "react": "~16.0.0",
- "react-dom": "~16.0.0"
- }
- },
- "node_modules/acorn": {
- "version": "7.4.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
- "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
- "peer": true
- },
- "node_modules/cookie": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
- "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-parser": {
- "version": "1.4.5",
- "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
- "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
- "dependencies": {
- "cookie": "0.4.0",
- "cookie-signature": "1.0.6"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
- },
- "node_modules/core-js": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.0.tgz",
- "integrity": "sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ==",
- "hasInstallScript": true,
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
- }
- },
- "node_modules/encoding": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
- "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
- "peer": true,
- "dependencies": {
- "iconv-lite": "^0.6.2"
- }
- },
- "node_modules/fbjs": {
- "version": "0.8.18",
- "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz",
- "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==",
- "peer": true,
- "dependencies": {
- "core-js": "^1.0.0",
- "isomorphic-fetch": "^2.1.1",
- "loose-envify": "^1.0.0",
- "object-assign": "^4.1.0",
- "promise": "^7.1.1",
- "setimmediate": "^1.0.5",
- "ua-parser-js": "^0.7.30"
- }
- },
- "node_modules/fbjs/node_modules/core-js": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
- "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
- "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.",
- "peer": true
- },
- "node_modules/fs": {
- "version": "0.0.1-security",
- "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
- "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
- },
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "peer": true,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "peer": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/isomorphic-fetch": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
- "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
- "peer": true,
- "dependencies": {
- "node-fetch": "^1.0.1",
- "whatwg-fetch": ">=0.10.0"
- }
- },
- "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==",
- "peer": true
- },
- "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==",
- "peer": true,
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/node-fetch": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
- "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
- "peer": true,
- "dependencies": {
- "encoding": "^0.1.11",
- "is-stream": "^1.0.1"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "peer": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/promise": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
- "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
- "peer": true,
- "dependencies": {
- "asap": "~2.0.3"
- }
- },
- "node_modules/prop-types": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
- "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "peer": true,
- "dependencies": {
- "loose-envify": "^1.4.0",
- "object-assign": "^4.1.1",
- "react-is": "^16.13.1"
- }
- },
- "node_modules/react": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/react/-/react-16.0.0.tgz",
- "integrity": "sha1-zn348ZQbA28Cssyp29DLHw6FXi0=",
- "peer": true,
- "dependencies": {
- "fbjs": "^0.8.16",
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "prop-types": "^15.6.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "16.0.1",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.0.1.tgz",
- "integrity": "sha512-gGJNmuS0VpkJsNStpzplcgc4iuHJ2X8rjiiaY/5YfHrsAd2cw1JkMXD6Z1kBOed8rDUNrRYrnDYptnhFghFFhA==",
- "peer": true,
- "dependencies": {
- "fbjs": "^0.8.16",
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "prop-types": "^15.6.0"
- },
- "peerDependencies": {
- "react": "^16.0.0"
- }
- },
- "node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "peer": true
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "peer": true
- },
- "node_modules/setimmediate": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
- "peer": true
- },
- "node_modules/ua-parser-js": {
- "version": "0.7.31",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz",
- "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/ua-parser-js"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/faisalman"
- }
- ],
- "peer": true,
- "engines": {
- "node": "*"
- }
- },
- "node_modules/whatwg-fetch": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
- "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==",
- "peer": true
- }
- },
- "dependencies": {
- "acorn": {
- "version": "7.4.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
- "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
- },
- "acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "requires": {}
- },
- "asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
- "peer": true
- },
- "cookie": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
- "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
- },
- "cookie-parser": {
- "version": "1.4.5",
- "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
- "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
- "requires": {
- "cookie": "0.4.0",
- "cookie-signature": "1.0.6"
- }
- },
- "cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
- },
- "core-js": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.0.tgz",
- "integrity": "sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ=="
- },
- "encoding": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
- "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
- "peer": true,
- "requires": {
- "iconv-lite": "^0.6.2"
- }
- },
- "fbjs": {
- "version": "0.8.18",
- "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz",
- "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==",
- "peer": true,
- "requires": {
- "core-js": "^1.0.0",
- "isomorphic-fetch": "^2.1.1",
- "loose-envify": "^1.0.0",
- "object-assign": "^4.1.0",
- "promise": "^7.1.1",
- "setimmediate": "^1.0.5",
- "ua-parser-js": "^0.7.30"
- },
- "dependencies": {
- "core-js": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
- "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
- "peer": true
- }
- }
- },
- "fs": {
- "version": "0.0.1-security",
- "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
- "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
- },
- "iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "peer": true,
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- }
- },
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "peer": true
- },
- "isomorphic-fetch": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
- "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
- "peer": true,
- "requires": {
- "node-fetch": "^1.0.1",
- "whatwg-fetch": ">=0.10.0"
- }
- },
- "js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "peer": 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==",
- "peer": true,
- "requires": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- }
- },
- "node-fetch": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
- "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
- "peer": true,
- "requires": {
- "encoding": "^0.1.11",
- "is-stream": "^1.0.1"
- }
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "peer": true
- },
- "promise": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
- "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
- "peer": true,
- "requires": {
- "asap": "~2.0.3"
- }
- },
- "prop-types": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
- "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "peer": true,
- "requires": {
- "loose-envify": "^1.4.0",
- "object-assign": "^4.1.1",
- "react-is": "^16.13.1"
- }
- },
- "react": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/react/-/react-16.0.0.tgz",
- "integrity": "sha1-zn348ZQbA28Cssyp29DLHw6FXi0=",
- "peer": true,
- "requires": {
- "fbjs": "^0.8.16",
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "prop-types": "^15.6.0"
- }
- },
- "react-dom": {
- "version": "16.0.1",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.0.1.tgz",
- "integrity": "sha512-gGJNmuS0VpkJsNStpzplcgc4iuHJ2X8rjiiaY/5YfHrsAd2cw1JkMXD6Z1kBOed8rDUNrRYrnDYptnhFghFFhA==",
- "peer": true,
- "requires": {
- "fbjs": "^0.8.16",
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "prop-types": "^15.6.0"
- }
- },
- "react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "peer": true
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "peer": true
- },
- "setimmediate": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
- "peer": true
- },
- "ua-parser-js": {
- "version": "0.7.31",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz",
- "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==",
- "peer": true
- },
- "whatwg-fetch": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
- "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==",
- "peer": true
- }
- }
-}
diff --git a/src/backend/package.json b/src/backend/package.json
deleted file mode 100644
index dd7817867..000000000
--- a/src/backend/package.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "name": "dev-reactime",
- "version": "4.0.0",
- "description": "A library that helps debug React by memorizing the state of components with every render.",
- "main": "index.js",
- "repository": {
- "type": "git",
- "url": "https://github.com/open-source-labs/reactime"
- },
- "scripts": {
- "test": "echo \"Error: no test specified\""
- },
- "types": "./index.d.ts",
- "peerDependencies": {
- "react": "~16.0.0",
- "react-dom": "~16.0.0"
- },
- "keywords": [
- "react",
- "state",
- "useState",
- "setState",
- "debug",
- "reactime",
- "react devtool"
- ],
- "contributors": [
- "Abaas Khorrami",
- "Andy Wong",
- "Bryan Lee",
- "Carlos Perez",
- "Chris Flannery",
- "David Chai",
- "Edwin Menendez",
- "Ergi Shehu",
- "Gabriela Jardim Aquino",
- "Gregory Panciera",
- "Josh Kim",
- "Joshua Howard",
- "Nathanael Wa Mwenze",
- "Prasanna Malla",
- "Rajeeb Banstola",
- "Raymond Kwan",
- "Rocky Lin",
- "Ruth Anam",
- "Ryan Dang",
- "Sierra Swaby",
- "Yujin Kang"
- ],
- "license": "MIT",
- "dependencies": {
- "acorn": "^7.1.0",
- "acorn-jsx": "^5.0.2",
- "cookie-parser": "^1.4.5",
- "core-js": "^3.6.5",
- "fs": "0.0.1-security"
- }
-}
diff --git a/src/backend/puppeteerServer.js b/src/backend/puppeteerServer.ts
similarity index 80%
rename from src/backend/puppeteerServer.js
rename to src/backend/puppeteerServer.ts
index 98a20e43a..342c22347 100644
--- a/src/backend/puppeteerServer.js
+++ b/src/backend/puppeteerServer.ts
@@ -1,14 +1,14 @@
-/* eslint-disable linebreak-style */
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable @typescript-eslint/no-var-requires */
-const express = require('express');
-const path = require('path');
-
-const app = express();
-
-app.use(express.static(path.resolve(__dirname)));
-
-// Apple uses port 5000 for Air Play.
-const server = app.listen(5001);
-
-module.exports = server;
+/* eslint-disable linebreak-style */
+/* eslint-disable import/no-extraneous-dependencies */
+/* eslint-disable @typescript-eslint/no-var-requires */
+import express from 'express';
+import path from 'path';
+
+const app = express();
+
+app.use(express.static(path.resolve(__dirname)));
+
+// Apple uses port 5000 for Air Play.
+const server = app.listen(5001);
+
+module.exports = server;
diff --git a/src/backend/routers/linkFiber.ts b/src/backend/routers/linkFiber.ts
new file mode 100644
index 000000000..edf594308
--- /dev/null
+++ b/src/backend/routers/linkFiber.ts
@@ -0,0 +1,145 @@
+import { Snapshot, Status, FiberRoot } from '../types/backendTypes';
+import { DevTools } from '../types/linkFiberTypes';
+import updateAndSendSnapShotTree from './snapShot';
+import throttle from '../controllers/throttle';
+import componentActionsRecord from '../models/masterState';
+import createComponentActionsRecord from '../controllers/createComponentActionsRecord';
+
+// Set global variables to use in exported module and helper functions
+declare global {
+ interface Window {
+ __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevTools;
+ __REDUX_DEVTOOLS_EXTENSION__?: any;
+ }
+}
+
+/**
+ * @constant MIN_TIME_BETWEEN_UPDATE - The minimum time (ms) between each re-render/update of the snapShot tree being displayed on the Chrome Extension.
+ */
+const MIN_TIME_BETWEEN_UPDATE = 70;
+/**
+ * @function throttledUpdateSnapshot - a function that will wait for at least MIN_TIME_BETWEEN_UPDATE ms, before updating the tree snapShot being displayed on the Chrome Extension.
+ * @param fiberRoot - the root of ReactFiber Tree
+ * @param mode - mode is jumping/not jumping or navigating during jumping
+ * @param snapShot - the tree snapshot to send to Front End or obtained from Front End during timeJump
+ */
+const throttledUpdateSnapshot = throttle(async (fiberRoot: FiberRoot, mode: Status) => {
+ // If not jumping
+ if (!mode.jumping) {
+ // Update and Send SnapShot tree to front end
+ updateAndSendSnapShotTree(fiberRoot);
+ }
+
+ // If navigating to another route during jumping:
+ else if (mode.navigating) {
+ // Reset the array containing update methods:
+ componentActionsRecord.clear();
+ // Obtain new update methods for the current route:
+ const { current } = fiberRoot;
+ createComponentActionsRecord(current);
+ // Invoke timeJump, which is stored in mode.navigating, to update React Application FiberTree based on the snapshotTree
+ await mode.navigating();
+ }
+ // NOTE: if not navigating during jumping, timeJump is invoked in index.ts file.
+}, MIN_TIME_BETWEEN_UPDATE);
+
+/**
+ * @function linkFiber - linkFiber contains core module functionality, exported as an anonymous function, perform the following logic:
+ * 1. Check if React Dev Tool is installed.
+ * 2. Check if the target application (on the browser) is a valid react application.
+ * 3. Initiate a event listener for visibility update of the target React Application.
+ * 4. Obtain the initial fiberRootNode, which is the root node of the fiber tree
+ * 5. Initialize the fiber tree snapShot to send to Front End, later rendered on Chrome Extension.
+ * 6. Monkey patching the onCommitFiberRoot from REACT DEV TOOL to obtain updated data after React Applicaiton is re-rendered.
+ * @param snapShot The current snapshot (i.e fiber tree)
+ * @param mode The current mode (i.e. jumping, time-traveling, or paused)
+ * @return a function to be invoked by index.js that initiates snapshot monitoring
+ */
+export default function linkFiber(mode: Status): () => Promise {
+ /** A boolean value indicate if the target React Application is visible */
+ let isVisible: boolean = true;
+ /**
+ * Every React application has one or more DOM elements that act as containers. React creates a fiber root object for each of those containers.
+ * This fiber root is where React holds reference to a fiber tree
+ * The `fiberRootNode`, which is the root node of the fiber tree is stored in the current property of the fiber root object
+ */
+ let fiberRoot: FiberRoot;
+
+ // Return a function to be invoked by index.js that initiates snapshot monitoring
+ return async function linkFiberInitialization() {
+ // -------------------CHECK REACT DEVTOOL INSTALLATION----------------------
+ // react devtools global hook is a global object that was injected by the React Devtools content script, allows access to fiber nodes and react version
+ // Obtain React Devtools Object:
+ let devTools; // changed to a different version of getting hook (08/04/2023)
+ while (!devTools) {
+ devTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
+ }
+ // If React Devtools is not installed, object will be undefined.
+ if (!devTools) return;
+ // If React Devtools is installed, send a message to front end.
+ window.postMessage(
+ {
+ action: 'devToolsInstalled',
+ payload: 'devToolsInstalled',
+ },
+ '*',
+ );
+
+ // --------------------CHECK VALID REACT APPLICATION------------------------
+ // Obtain React Application information:
+ const reactInstance = devTools.renderers.get(1);
+ // If target application is not a React App, this will return undefined.
+ if (!reactInstance) {
+ return;
+ }
+ // If target application is a React App, send a message to front end.
+ window.postMessage(
+ {
+ action: 'aReactApp',
+ payload: 'aReactApp',
+ },
+ '*',
+ );
+ // --------------INITIATE EVENT LISTENER FOR VISIBILITY CHANGE--------------
+ /**
+ * Initiate an event listener for when there is a change to the visibility of the react target application (the browser tab)
+ * @example If tic-tac-toe demo app is loaded on a tab with localhost:8080, whenever user switch tab or switch to another software => 'visibilityChange' => invoke the callback to update doWork boolean value
+ */
+ document.addEventListener('visibilitychange', () => {
+ // Hidden property = background tab/minimized window
+ isVisible = !document.hidden;
+ });
+
+ // ---------OBTAIN THE INITIAL FIBEROOTNODE FROM REACT DEV TOOL-------------
+ // Obtain the FiberRootNode, which is the first value in the FiberRoot Set:
+ fiberRoot = devTools.getFiberRoots(1).values().next().value;
+
+ // console.log('Initial fiber root', fiberRoot);
+
+ // ----------INITIALIZE THE TREE SNAP SHOT ON CHROME EXTENSION--------------
+ await throttledUpdateSnapshot(fiberRoot, mode); // only runs on start up
+
+ // --------MONKEY PATCHING THE onCommitFiberRoot FROM REACT DEV TOOL--------
+ // React has inherent methods that are called with react fiber
+ // One of which is the onCommitFiberRoot method, which is invoked after the React application re-render its component(s).
+ // we attach new functionality without compromising the original work that onCommitFiberRoot does
+ // Money Patching the onCommitFiberRoot method from REACT DEV TOOL
+ /**
+ * @param onCommitFiberRoot - is a callback provided by React that is automatically invoked by React Fiber after the target React application re-renders its components. This callback is used by REACT DEV TOOL to receive updated data about the component tree and its state. See {@link https://medium.com/@aquinojardim/react-fiber-reactime-4-0-f200f02e7fa8}
+ * @returns an anonymous function, which will have the same parameters as onCommitFiberRoot and when invoked will update the fiberRoot value & post a request to update the snapShot tree on Chrome Extension
+ */
+ function addOneMoreStep(onCommitFiberRoot: DevTools['onCommitFiberRoot']) {
+ return function (...args: Parameters) {
+ // Obtain the updated FiberRootNode, after the target React application re-renders
+ const fiberRoot = args[1];
+ // If the target React application is visible, send a request to update the snapShot tree displayed on Chrome Extension
+ if (isVisible) {
+ throttledUpdateSnapshot(fiberRoot, mode);
+ }
+ // After our added work is completed we invoke the original onComitFiberRoot function
+ return onCommitFiberRoot(...args);
+ };
+ }
+ devTools.onCommitFiberRoot = addOneMoreStep(devTools.onCommitFiberRoot);
+ };
+}
diff --git a/src/backend/routers/snapShot.ts b/src/backend/routers/snapShot.ts
new file mode 100644
index 000000000..41a5cb7f7
--- /dev/null
+++ b/src/backend/routers/snapShot.ts
@@ -0,0 +1,40 @@
+import { Snapshot, FiberRoot } from '../types/backendTypes';
+import componentActionsRecord from '../models/masterState';
+import routes from '../models/routes';
+import createTree from '../controllers/createTree';
+
+// -------------------------UPDATE & SEND TREE SNAP SHOT------------------------
+/**
+ * This function creates a new `snapShot` fiber tree with the provided `fiberRoot`, then send the updated snapshot to front end.
+ * This runs after every Fiber commit if mode is not jumping.
+ * This
+ * @param snapshot The current snapshot of the fiber tree
+ * @param fiberRoot The `fiberRootNode`, which is the root node of the fiber tree is stored in the current property of the fiber root object which we can use to traverse the tree
+ */
+// updating tree depending on current mode on the panel (pause, etc)
+export default function updateAndSendSnapShotTree(fiberRoot: FiberRoot): void {
+ // This is the currently active root fiber(the mutable root of the tree)
+ const { current } = fiberRoot;
+ // Clear all of the legacy actions from old fiber tree because we are about to create a new one
+ componentActionsRecord.clear();
+ // Calls the createTree function which creates the new snapshot tree and store new state update method to compoenActionsRecord
+ /** The snapshot of the current ReactFiber tree */
+ const payload = createTree(current);
+ // Save the current window url to route
+ payload.route = routes.addRoute(window.location.href);
+ // method safely enables cross-origin communication between Window objects;
+ // e.g., between a page and a pop-up that it spawned, or between a page
+ // and an iframe embedded within it.
+ // this postMessage will be sending the most up-to-date snapshot of the current React Fiber Tree
+ // the postMessage action will be received on the content script to later update the tabsObj
+ // this will fire off everytime there is a change in test application
+ // convert the payload from a fiber tree to an object to avoid a data clone error when postMessage processes the argument
+ const obj = JSON.parse(JSON.stringify(payload));
+ window.postMessage(
+ {
+ action: 'recordSnap',
+ payload: obj,
+ },
+ '*',
+ );
+}
diff --git a/src/backend/routes.ts b/src/backend/routes.ts
deleted file mode 100644
index c537bc5dd..000000000
--- a/src/backend/routes.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-/* eslint-disable max-classes-per-file */
-/* eslint-disable max-len */
-
-/**
- * @class Route instances are created by the addRoute method on Routes. A Route instance has two properties: the url of the route and a unique id.
- */
-class Route {
- url: string;
-
- id: number;
-
- constructor(url: string, id: number) {
- this.url = url;
- this.id = id;
- }
-}
-
-/**
- * @class An instance of this class is the default export from routes.ts. It includes the logic that allows Reactime to work with target applications built with React Router. The addRoute method is invoked in linkFiber.ts within the sendSnapshot function. The navigate method is invoked in timeJump.ts immediately before invoking jump.
- */
-
-class Routes {
- /**
- * @property A stack of visited routes that matches the browser history stack.
- */
- values: Route[] = [new Route(null, null)];
-
- /**
- * @property Used to assign unique ids to routes in the values stack in case the same route is added to the stack more than once.
- */
- id = 0;
-
- /**
- * @property The index of the current route in the values stack.
- */
- current: number | null = 0;
-
- /**
- * @method addRoute
- * @param url - A url string.
- * @returns Either the current route if the user has not navigated away from it or a new instance of a route constructed from the url.
- *
- * Ensures that the values stack always matches the browser history stack.
- */
-
- addRoute(url: string): Route {
- let route: Route = this.values[this.current];
-
- if (this.values[this.current].url !== url) {
- if (this.current !== this.values.length - 1) {
- this.rebuildHistory(url);
- }
-
- route = new Route(url, (this.id += 1));
- this.values.push(route);
-
- this.current = this.values.length - 1;
- }
-
- return route;
- }
-
- /**
- * @method rebuildHistory
- * @param url - A url string.
- *
- * Rebuilds the browser history stack using the copy of the stack maintained in the values stack. https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState, https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
- */
- private rebuildHistory(url: string): void {
- window.history.replaceState('', '', this.values[this.current + 1].url);
-
- for (let i = this.current + 2; i < this.values.length; i += 1) {
- window.history.pushState('', '', this.values[i].url);
- }
-
- window.history.pushState('', '', url);
- }
-
- /**
- * @method navigate
- * @param route - The target route in the values stack that is being navigated to.
- * @returns A boolean indicating whether or not a new route was navigated to.
- *
- * Invokes history.go passing in the delta between the current route and the target route. https://developer.mozilla.org/en-US/docs/Web/API/History/go
- */
- navigate(route: Route): boolean {
- let targetIndex: number | null = null;
-
- for (let i = 0; i < this.values.length; i += 1) {
- if (this.values[i].url === route.url && this.values[i].id === route.id) {
- targetIndex = i;
- }
- }
-
- const delta: number = targetIndex - this.current;
-
- this.current += delta;
-
- if (delta !== 0) {
- window.history.go(delta);
- return true;
- }
- return false;
- }
-}
-
-export default new Routes();
diff --git a/src/backend/timeJump.ts b/src/backend/timeJump.ts
deleted file mode 100644
index daaf2ab07..000000000
--- a/src/backend/timeJump.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import routes from './routes';
-
-/* eslint-disable @typescript-eslint/no-unused-vars */
-/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-/* eslint-disable max-len */
-/**
- * This file contains necessary functionality for time-travel feature
- *
- * It exports an anonymous
- * @function timeJump
- * @param origin The latest snapshot, linked to the fiber (changes to origin will change app)
- * @param mode The current mode (i.e. jumping, time-traveling, or paused)
- * @returns A function that takes a target snapshot and a boolean flag checking for firstCall, then invokes `jump` on that target snapshot
- *
- * The target snapshot portrays some past state we want to travel to.
- * `jump` recursively sets state for any stateful components.
- */
-
-/* eslint-disable no-param-reassign */
-import componentActionsRecord from './masterState';
-
-const circularComponentTable = new Set();
-export default mode => {
- // Recursively change state of tree
- // Set the state of the origin tree if the component is stateful
- function jump(target) {
- if (!target) return;
- if (target.state === 'stateless') {
- target.children.forEach(child => jump(child));
- return;
- }
- // for stateful class components
- const component = componentActionsRecord.getComponentByIndex(
- target.componentData.index,
- );
-
- // check if it is a stateful class component
- // if yes, find the component by its index and assign it to a variable
- // call that components setState method to reset state to the state at the time of the jump snapshot
- if (component && component.setState) {
- component.setState(
- // prevState contains the states of the snapshots we are jumping FROM, not jumping TO
- prevState => {
- Object.keys(prevState).forEach(key => {
- // the if conditional below does not appear to ever be reached if all states are defined - leaving code in just in case codebases do have undefined states
- // if (target.state[key] !== undefined) {
- // target.state[key] = undefined;
- // }
- });
- return target.state;
- },
- // Iterate through new children after state has been set
- () => target.children.forEach(child => jump(child)),
- );
- }
-
- target.children.forEach(child => {
- if (!circularComponentTable.has(child)) {
- circularComponentTable.add(child);
- jump(child);
- }
- });
-
- // REACT HOOKS
- // check if component states are set with hooks
- // if yes, grab all relevant components for this snapshot in numArr
- // call dispatch on each component passing in the corresponding currState value
- if (target.state && target.state.hooksState) {
- const currState = target.state.hooksState;
- const numArr: Array = [];
- let counter = 1;
- while (counter < currState.length + 1) {
- numArr.push(target.componentData.hooksIndex - currState.length + counter);
- counter += 1;
- }
- const hooksComponent = componentActionsRecord.getComponentByIndexHooks(numArr);
- for (let i = 0; i < currState.length; i += 1) {
- hooksComponent[i].dispatch(Object.values(currState[i])[0]);
- }
- }
- }
-
- // payload from index.ts is assigned to target
- return (target, firstCall = false) => {
- // * Setting mode disables setState from posting messages to window
- mode.jumping = true;
- if (firstCall) circularComponentTable.clear();
- const navigating: boolean = routes.navigate(target.route);
- if (navigating) {
- addEventListener('popstate', event => {
- jump(target);
- document.body.onmouseover = () => {
- mode.jumping = false;
- };
- });
- } else {
- jump(target);
- document.body.onmouseover = () => {
- mode.jumping = false;
- };
- }
- };
-};
diff --git a/src/backend/tree.ts b/src/backend/tree.ts
deleted file mode 100644
index 6ef656234..000000000
--- a/src/backend/tree.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-/* eslint-disable no-plusplus */
-/* eslint-disable max-len */
-/* eslint-disable @typescript-eslint/ban-types */
-/* eslint-disable no-multiple-empty-lines */
-/* eslint-disable max-classes-per-file */
-/* eslint-disable no-console */
-/* eslint-disable no-param-reassign */
-
-let copyInstances = 0;
-const circularComponentTable = new Set();
-let componentNames = {};
-
-// Removes unserializable state data such as functions
-function scrubUnserializableMembers(tree: Tree): Tree {
- Object.entries(tree.state).forEach(keyValuePair => {
- if (typeof keyValuePair[1] === 'function') tree.state[keyValuePair[0]] = 'function';
- });
- return tree;
-}
-
-function serializeState(state) {
- try {
- return JSON.parse(JSON.stringify(state));
- } catch (e) {
- return 'circularState';
- }
-}
-
-
-/**
- * This is the current snapshot that is being sent to the snapshots array.
- * Creates a Tree
- * @param state : the tree's current state
- * @param name : the tree's name
- * @param componentData : Data in the component tree
- * @parent generates a new tree (recursive call)
- */
-class Tree {
- state: string | {};
-
- name: string;
-
- componentData: {
- props: {},
- };
-
- children: (Tree | string)[];
-
- parent: Tree;
-
- isExpanded: boolean;
-
- rtid: any;
-
- route: {};
-
- // Duplicate names: add a unique number ID
- // Create an object 'componentNames' to store each component name as a key and it's frequency of use as its value
- // When a new component is made on the tree, check if the new component's name already exists in 'componentNames' (possibly with the .hasOwnProperty method)
- // If the name already exists, add its value (an integer) to the name
- // Also, increment the value after
- // If not, create the new component and also a new key: value pair in 'componentNames' with the component's name as the key and 0 as its value
- // EXAMPLE OF COMPONENTNAMES OBJECT: {editableInput: 1, Provider: 0, etc}
-
- constructor(state: string | {}, name = 'nameless', componentData: {} = {}, rtid: any = null, string: any = null) {
- this.state = state === 'root' ? 'root' : serializeState(state);
- this.name = name;
- this.componentData = componentData ? { ...JSON.parse(JSON.stringify(componentData)) } : { };
- this.children = [];
- this.parent = null; // ref to parent so we can add siblings
- this.isExpanded = true;
- this.rtid = rtid;
- }
-
- // Returns a unique name ready to be used
- checkForDuplicates(name: string): string {
- // check for empty name
- if (name === '' && typeof this.rtid === 'string') {
- name = this.rtid.replace('fromLinkFiber', '');
- }
- if (this.state === 'root') componentNames = {};
- // check for duplicate
- else if (componentNames[name] !== undefined) {
- const count = componentNames[name] + 1;
- const newName = name + count;
- componentNames[name] = count;
- return newName;
- }
- componentNames[name] = 0;
- return name;
- }
-
- addChild(state: string | {}, name: string, componentData: {}, rtid: any): Tree {
- const uniqueName = this.checkForDuplicates(name);
- const newChild: Tree = new Tree(state, uniqueName, componentData, rtid);
- newChild.parent = this;
- this.children.push(newChild);
- return newChild;
- }
-
- addSibling(state: string | {}, name: string, componentData: {}, rtid: any): Tree {
- const uniqueName = this.checkForDuplicates(name);
- const newSibling: Tree = new Tree(state, uniqueName, componentData, rtid);
- newSibling.parent = this.parent;
- this.parent.children.push(newSibling);
- return newSibling;
- }
-
- /**
- * @function cleanTreeCopy : Adds a sibling to the current tree
- */
- cleanTreeCopy(): Tree {
- /**
- * @object circularComponentTable : Clears circular component table only on first call, not recursive ones
- *
- */
- if (copyInstances === 0) {
- copyInstances++;
- circularComponentTable.clear();
- }
- // creates copy of present node
- let copy: Tree = new Tree(this.state, this.name, this.componentData, this.rtid);
- delete copy.parent;
- circularComponentTable.add(this);
- copy = scrubUnserializableMembers(copy);
-
- // creates copy of each child of the present node
- copy.children = this.children.map((child: Tree): Tree | string => {
- if (!circularComponentTable.has(child)) {
- return child.cleanTreeCopy();
- }
- return 'circular';
- });
-
- copyInstances--;
- return copy;
- }
-}
-
-export default Tree;
diff --git a/src/backend/types/backendTypes.ts b/src/backend/types/backendTypes.ts
index eaa50ad98..863a4d38d 100644
--- a/src/backend/types/backendTypes.ts
+++ b/src/backend/types/backendTypes.ts
@@ -1,181 +1,254 @@
-/* eslint-disable linebreak-style */
-/* eslint-disable @typescript-eslint/ban-types */
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import Tree from '../tree';
-
-export interface Snapshot {
- tree: Tree;
- unfilteredTree: null;
-}
-
-export interface Mode {
- jumping: boolean;
- paused: boolean;
-}
-
-export interface SnapshotNode {
- name: string;
- state: {
- location?: any;
- };
- children: any[];
-}
-
-export interface MsgData {
- data: {
- action: string;
- payload: any;
- };
-}
-
-export interface ComponentData {
- index?: number;
- hooksIndex?: number;
- actualDuration?: number;
- actualStartTime?: number;
- selfBaseDuration?: number;
- treeBaseDuration?: number;
- props?: any,
-}
-
-export interface HookStateItem {
- state: any;
- component: any;
-}
-
-export type HookStates = Array;
-
-export interface State {
- state?: {} | number;
- hooksState?: HookStates;
-}
-
-export type WorkTag =
- | 0
- | 1
- | 2
- | 3
- | 4
- | 5
- | 6
- | 7
- | 8
- | 9
- | 10
- | 11
- | 12
- | 13
- | 14
- | 15
- | 16
- | 17
- | 18
- | 19
- | 20
- | 21
- | 22
- | 23
- | 24;
-
-export const FunctionComponent = 0;
-export const ClassComponent = 1;
-export const IndeterminateComponent = 2; // Before we know whether it is function or class
-export const HostRoot = 3; // Root of a host tree. Could be nested inside another node.
-export const HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
-export const HostComponent = 5; // has stateNode of html elements
-export const HostText = 6;
-export const Fragment = 7;
-export const Mode = 8;
-export const ContextConsumer = 9;
-export const ContextProvider = 10;
-export const ForwardRef = 11;
-export const Profiler = 12;
-export const SuspenseComponent = 13;
-export const MemoComponent = 14;
-export const SimpleMemoComponent = 15; // A higher order component where if the component renders the same result given the same props, react skips rendering the component and uses last rendered result. Has memoizedProps/memoizedState but no stateNode
-export const LazyComponent = 16;
-export const IncompleteClassComponent = 17;
-export const DehydratedFragment = 18;
-export const SuspenseListComponent = 19;
-export const FundamentalComponent = 20;
-export const ScopeComponent = 21;
-export const Block = 22;
-export const OffscreenComponent = 23;
-export const LegacyHiddenComponent = 24;
-
-export type Fiber = {
- // Tag identifying the type of fiber.
- tag: WorkTag;
-
- // Unique identifier of this child.
- key: null | string;
-
- // The value of element.type which is used to preserve the identity during
- // reconciliation of this child.
- elementType: any;
-
- // The resolved function/class/ associated with this fiber.
- type: any;
-
- // The local state associated with this fiber.
- stateNode: any;
-
- // Conceptual aliases
- // parent : Instance -> return The parent happens to be the same as the
- // return fiber since we've merged the fiber and instance.
-
- // Remaining fields belong to Fiber
-
- // The Fiber to return to after finishing processing this one.
- // This is effectively the parent, but there can be multiple parents (two)
- // so this is only the parent of the thing we're currently processing.
- // It is conceptually the same as the return address of a stack frame.
- // return: Fiber | null,
-
- // Singly Linked List Tree Structure.
- child: Fiber | null;
- sibling: Fiber | null;
- index: number;
-
- // Input is the data coming into process this fiber. Arguments. Props.
- // pendingProps: any, // This type will be more specific once we overload the tag.
- // memoizedProps: any, // The props used to create the output.
-
- // The state used to create the output
- memoizedState: any;
-
- memoizedProps: any;
-
- // Singly linked list fast path to the next fiber with side-effects.
- // nextEffect: Fiber | null,
-
- // This is a pooled version of a Fiber. Every fiber that gets updated will
- // eventually have a pair. There are cases when we can clean up pairs to save
- // memory if we need to.
- // alternate: Fiber | null,
-
- // Time spent rendering this Fiber and its descendants for the current update.
- // This tells us how well the tree makes use of sCU for memoization.
- // It is reset to 0 each time we render and only updated when we don't bailout.
- // This field is only set when the enableProfilerTimer flag is enabled.
- actualDuration?: number;
-
- // If the Fiber is currently active in the "render" phase,
- // This marks the time at which the work began.
- // This field is only set when the enableProfilerTimer flag is enabled.
- actualStartTime?: number;
-
- // Duration of the most recent render time for this Fiber.
- // This value is not updated when we bailout for memoization purposes.
- // This field is only set when the enableProfilerTimer flag is enabled.
- selfBaseDuration?: number;
-
- // Sum of base times for all descendants of this Fiber.
- // This value bubbles up during the "complete" phase.
- // This field is only set when the enableProfilerTimer flag is enabled.
- treeBaseDuration?: number;
-
- dependencies: any;
-
- _debugHookTypes: any;
-};
+import Tree from '../models/tree';
+
+/**
+ * Contain snapshot of the current ReactFiber tree
+ * @member tree - A snapshot of ReactFiber Tree to send to front end
+ */
+export interface Snapshot {
+ /** A snapshot of ReactFiber Tree to send to front end */
+ tree: Tree;
+}
+
+/**
+ * Indicate if mode is jumping/not jumping or navigating during jumping
+ * @member jumping - Describe whether we are jumping
+ *
+ * When `jumping = true`, no new snapShot will be sent to front end.
+ * @member navigating - Cache timeJump function to be invoked after ReactFibe tree update with new states from new route
+ * @example if user uses click left/right arrow or play button, front end will post a message `jumpToSnap` and a payload of the cached snapShot tree, we will set `jumping = true`
+ * @example if during jumping, we navigate to another route, such as from buttons to tictactoe, backend will set `navigating = cache of timeJump function`
+ */
+export interface Status {
+ /**
+ * Describe whether we are jumping
+ *
+ * When `jumping = true`, no new snapShot will be sent to front end.
+ */
+ jumping: boolean;
+ /** Cache timeJump function to be invoked after ReactFibe tree update with new states from new route*/
+ navigating?: Function;
+}
+
+/**
+ * @type MsgData - obj with data object that will be sent to window?
+ * @member data - an object with action & payload properties
+ */
+export interface MsgData {
+ data: {
+ action: string;
+ payload: any;
+ };
+}
+
+/**
+ * @type ComponentData -
+ * @member actualDuration - The time taken to render the current Fiber node and its descendants during the previous render cycle. This value is used to optimize the rendering of components and to provide performance metrics to developers.
+ * @member actualStartTime - The time at which the rendering of the current Fiber node started during the previous render cycle.
+ * @member key - The key a user assigned to the component or null if they didn't assign one
+ * @member context - {in experiment} - An object contains all context information of the current component
+ * @member index - {class component only} - The index of the bound setState method stored in `componentActionsRecord`
+ * @member hooksState - {functional component only} - An object contains all states of the current functional component
+ * @member hooksIndex - {functional component only} - An array of index of the bound dispatch method stored in `componentActionsRecord`
+ * @member props - An object contains all props of the current component
+ * @member selfBaseDuration - The base duration of the current Fiber node's render phase (excluding the time taken to render its children). This field is only set when the enableProfilerTimer flag is enabled.
+ * @member state - {class component only} - An object contains all states of the current class component
+ * @member treeBaseDuration - The total base duration of the current Fiber node's subtree. This field is only set when the enableProfilerTimer flag is enabled.
+ */
+export interface ComponentData {
+ /** The time taken to render the current Fiber node and its descendants during the previous render cycle. */
+ actualDuration?: number;
+ /** The time at which the rendering of the current Fiber node started during the previous render cycle. */
+ actualStartTime?: number;
+ /**The key a user assigned to the component or null if they didn't assign one */
+ key: string | null;
+ /** {in experiment} - An object contains all context information of the current component */
+ context: {};
+ /** {class component only} - The index of the bound setState method stored in `componentActionsRecord` */
+ index: number | null;
+ /** {functional component only} - An object contains all states of the current functional component */
+ hooksState: {} | null;
+ reducerStates?: Array<{
+ state: any;
+ lastAction: any;
+ reducerIndex: number;
+ hookName: string;
+ }> /** {functional component only} - An array of index of the bound dispatch method stored in `componentActionsRecord` */;
+ hooksIndex: number[] | null;
+ /** An object contains all props of the current component */
+ props: { [key: string]: any };
+ /** The base duration of the current Fiber node's render phase (excluding the time taken to render its children). */
+ selfBaseDuration?: number;
+ /** An object contains all states of the current class component */
+ state: { [key: string]: any } | null;
+ /** The total base duration of the current Fiber node's subtree. */
+ treeBaseDuration?: number;
+}
+
+/**
+ * @member state - states within the current functional component
+ * @member component - contains bound dispatch method to update state of the current functional component
+ */
+export interface HookStateItem {
+ component: any;
+ state: any;
+ isReducer: boolean;
+ lastAction?: any;
+ reducer?: Function;
+}
+
+export type WorkTag =
+ | 0
+ | 1
+ | 2
+ | 3
+ | 4
+ | 5
+ | 6
+ | 7
+ | 8
+ | 9
+ | 10
+ | 11
+ | 12
+ | 13
+ | 14
+ | 15
+ | 16
+ | 17
+ | 18
+ | 19
+ | 20
+ | 21
+ | 22
+ | 23
+ | 24;
+
+export const FunctionComponent = 0;
+export const ClassComponent = 1;
+/** Before we know whether it is function or class */
+export const IndeterminateComponent = 2;
+/** Root of a host tree. Could be nested inside another node. */
+export const HostRoot = 3;
+/** A subtree. Could be an entry point to a different renderer. */
+export const HostPortal = 4;
+/**
+ * Host Component: a type of component that represents a native DOM element in the browser environment, such as div, span, input, h1 etc.
+ */
+export const HostComponent = 5; // has stateNode of html elements
+export const HostText = 6;
+export const Fragment = 7;
+export const Mode = 8;
+export const ContextConsumer = 9;
+export const ContextProvider = 10;
+export const ForwardRef = 11;
+export const Profiler = 12;
+export const SuspenseComponent = 13;
+export const MemoComponent = 14;
+export const SimpleMemoComponent = 15; // A higher order component where if the component renders the same result given the same props, react skips rendering the component and uses last rendered result. Has memoizedProps/memoizedState but no stateNode
+export const LazyComponent = 16;
+export const IncompleteClassComponent = 17;
+export const DehydratedFragment = 18;
+export const SuspenseListComponent = 19;
+export const FundamentalComponent = 20;
+export const ScopeComponent = 21;
+export const Block = 22;
+export const OffscreenComponent = 23;
+export const LegacyHiddenComponent = 24;
+
+/**
+ * @type Fiber - The internal data structure that represents a `fiberNode` or a component in the React component tree
+ *
+ * {@link https://indepth.dev/posts/1008/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react}
+ * @member actualDuration - The time taken to render the current Fiber node and its descendants during the previous render cycle. This value is used to optimize the rendering of components and to provide performance metrics to developers.
+ * @member actualStartTime - The time at which the rendering of the current Fiber node started during the previous render cycle.
+ * @member child - Pointer to the first child.
+ * @member elementType - The type of the current Fiber node's element (e.g. the component function or class, or the DOM element type). For class/functional component, elmementType stores the function definition.
+ * @member key - The key a user assigned to the component or null if they didn't assign one
+ * @member memoizedProps - The current props of the component associated with the current Fiber node.
+ * @member memoizedState - The current state of the component associated with the current Fiber node.
+ * @member selfBaseDuration - The base duration of the current Fiber node's render phase (excluding the time taken to render its children). This field is only set when the enableProfilerTimer flag is enabled.
+ * @member sibling - Pointer to next sibling
+ * @member stateNode - The local state associated with this fiber. For classComponent, stateNode contains current state and the bound update methods of the component
+ * @member tag - The type of the current Fiber node, such as FunctionComponent, ClassComponent, or HostComponent (for DOM elements).
+ * @member treeBaseDuration - The total base duration of the current Fiber node's subtree. This field is only set when the enableProfilerTimer flag is enabled.
+ * @member _debugHookTypes - An array of hooks used for debugging purposes.
+ */
+export type Fiber = {
+ /**
+ * Time spent rendering this Fiber and its descendants for the current update.
+ *
+ * This tells us how well the tree makes use of sCU for memoization. It is reset to 0 each time we render and only updated when we don't bailout.
+ *
+ * This field is only set when the enableProfilerTimer flag is enabled.
+ */
+ actualDuration?: number;
+
+ /**
+ * If the Fiber is currently active in the "render" phase, this marks the time at which the work began.
+ *
+ * This field is only set when the enableProfilerTimer flag is enabled.
+ */
+ actualStartTime?: number;
+
+ // Singly Linked List Tree Structure.
+ /** Pointer to the first child. */
+ child: Fiber | null;
+
+ /**
+ * The type of the current Fiber node's element (e.g. the component function or class, or the DOM element type).
+ *
+ * For class/functional component, elmementType stores the function definition.
+ */
+ elementType: any;
+
+ /**
+ * Unique key string assigned by the user when making component on null if they didn't assign one
+ */
+ key: string | null;
+
+ /** The current state for a functional component associated with the current Fiber node. */
+ memoizedState: any;
+
+ /** The current props of the component associated with the current Fiber node. */
+ memoizedProps: any;
+
+ /**
+ * Duration of the most recent render time for this Fiber. This value is not updated when we bailout for memoization purposes.
+ *
+ * This field is only set when the enableProfilerTimer flag is enabled.
+ */
+ selfBaseDuration?: number;
+
+ // Singly Linked List Tree Structure.
+ /** Pointer to next sibling */
+ sibling: Fiber | null;
+
+ /**
+ * The local state associated with this fiber.
+ *
+ * For classComponent, stateNode contains current state and the bound update methods of the component.
+ */
+ stateNode: any;
+
+ /** The type of the current Fiber node, such as FunctionComponent, ClassComponent, or HostComponent (for DOM elements). */
+ tag: WorkTag;
+
+ /**
+ * Sum of base times for all descendants of this Fiber. This value bubbles up during the "complete" phase.
+ *
+ * This field is only set when the enableProfilerTimer flag is enabled.
+ */
+ treeBaseDuration?: number;
+
+ /** An array of hooks used for debugging purposes. */
+ _debugHookTypes: string[] | null;
+};
+
+/**
+ * @type FiberRoot - The internal data structure that represents a fiberRootNode or the top-level node of a single component tree
+ *
+ * FiberRoot data structure has several properties. For Reactime, we only access the `current` property which contains the tree structure made of `fiberNode`. Each `fiberNode` contains a component data in the React component tree.
+ */
+export type FiberRoot = {
+ current: Fiber;
+};
diff --git a/src/backend/types/linkFiberTypes.ts b/src/backend/types/linkFiberTypes.ts
new file mode 100644
index 000000000..d06ee0e9e
--- /dev/null
+++ b/src/backend/types/linkFiberTypes.ts
@@ -0,0 +1,26 @@
+import { FiberRoot } from './backendTypes';
+
+/**
+ * @interface DevTools - A global object provided by the React Developer Tools extension. It provides a set of methods that allow developers to inspect and manipulate React components in the browser.
+ */
+export interface DevTools {
+ /**
+ * @property renderers - an Map object containing information about the React renders that are currently active on the page. The react version being used can be obtained at key = 1.
+ */
+ renderers: Map<1, undefined | { version: string }>;
+ /**
+ * @method getFiberRoots - get the Set of fiber roots that are currently mounted for the given rendererID. If not found, initalize a new empty Set at renderID key.
+ * @param renderID - a unique identifier for a specific instance of a React renderer. When a React application is first mounted, it will receive a rendererID. This rendererID will remain the same for the entire lifecycle of the application, even if the state is updated and the components are re-rendered/unmounted/added. However, if the application is unmounted and re-mounted again, it will receive a new rendererID.
+ * @return A set of fiberRoot.
+ */
+ getFiberRoots: (rendererID: number) => Set;
+
+ /**
+ * @method onCommitFiberRoot - After the state of a component in a React Application is updated, the virtual DOM will be updated. When a render has been commited for a root, onCommitFiberRoot will be invoked to determine if the component is being mounted, updated, or unmounted. After that, this method will send update information to the React DevTools to update its UI to reflect the change.
+ * @param rendererID - a unique identifier for a specific instance of a React renderer
+ * @param root - root of the rendered tree (a.k.a the root of the React Application)
+ * @param priorityLevel
+ * @return void
+ */
+ onCommitFiberRoot: (rendererID: number, root: FiberRoot, priorityLevel: any) => void;
+}
diff --git a/src/extension/background.js b/src/extension/background.js
index 6b7c93693..42bba411b 100644
--- a/src/extension/background.js
+++ b/src/extension/background.js
@@ -1,17 +1,224 @@
-// Import snapshots from "../app/components/snapshots".
-// import 'core-js';
-
// Store ports in an array.
const portsArr = [];
const reloaded = {};
const firstSnapshotReceived = {};
+// Toggle for recording accessibility snapshots
+let toggleAxRecord = false;
+
// There will be the same number of objects in here as there are
// Reactime tabs open for each user application being worked on.
let activeTab;
const tabsObj = {};
// Will store Chrome web vital metrics and their corresponding values.
const metrics = {};
+
+// Helper function to check if a URL is localhost
+function isLocalhost(url) {
+ return url?.startsWith('http://localhost:') || url?.startsWith('https://localhost:');
+}
+
+// Helper function to find localhost tab
+async function findLocalhostTab() {
+ try {
+ // First check current window
+ const currentWindowTabs = await chrome.tabs.query({ currentWindow: true });
+ const localhostTab = currentWindowTabs.find((tab) => tab.url && isLocalhost(tab.url));
+
+ if (localhostTab) {
+ return localhostTab;
+ }
+
+ // If not found in current window, check all windows
+ const allTabs = await chrome.tabs.query({});
+ const localhostTabAnyWindow = allTabs.find((tab) => tab.url && isLocalhost(tab.url));
+
+ if (localhostTabAnyWindow) {
+ // Focus the window containing the localhost tab
+ await chrome.windows.update(localhostTabAnyWindow.windowId, { focused: true });
+ return localhostTabAnyWindow;
+ }
+
+ return null;
+ } catch (error) {
+ console.error('Error finding localhost tab:', error);
+ return null;
+ }
+}
+
+//keep alive functionality to address port disconnection issues
+function setupKeepAlive() {
+ // Clear any existing keep-alive alarms to prevent duplicates
+ chrome.alarms.clear('keepAlive', (wasCleared) => {
+ if (wasCleared) {
+ console.log('Cleared existing keep-alive alarm.');
+ }
+ });
+
+ // Create a new keep-alive alarm, we found .5 min to resolve the idle time port disconnection
+ chrome.alarms.create('keepAlive', { periodInMinutes: 0.5 });
+
+ // Log active alarms for debugging
+ chrome.alarms.getAll((alarms) => {
+ console.log(
+ 'Active alarms:',
+ alarms.map((alarm) => alarm.name),
+ );
+ });
+
+ // Listen for the keep-alive alarm
+ chrome.alarms.onAlarm.addListener((alarm) => {
+ if (alarm.name === 'keepAlive') {
+ console.log('Keep-alive alarm triggered.');
+ pingServiceWorker();
+ }
+ });
+}
+
+// Ping the service worker to keep it alive
+function pingServiceWorker() {
+ try {
+ chrome.runtime.getPlatformInfo(() => {
+ console.log('Service worker pinged successfully.');
+ });
+ } catch (error) {
+ console.error('Failed to ping service worker:', error);
+
+ // Fallback: Trigger an empty event to wake up the service worker
+ chrome.runtime.sendMessage({ type: 'ping' }, (response) => {
+ if (chrome.runtime.lastError) {
+ console.error('Fallback message failed:', chrome.runtime.lastError.message);
+ } else {
+ console.log('Fallback message sent successfully:', response);
+ }
+ });
+ }
+}
+
+// function pruning the chrome ax tree and pulling the relevant properties
+const pruneAxTree = (axTree) => {
+ const axArr = [];
+ let orderCounter = 0;
+
+ for (const node of axTree) {
+ let {
+ backendDOMNodeId,
+ childIds,
+ ignored,
+ name,
+ nodeId,
+ ignoredReasons,
+ parentId,
+ properties,
+ role,
+ } = node;
+
+ if (!name) {
+ if (ignored) {
+ name = { value: 'ignored node' };
+ } else {
+ name = { value: 'no name' };
+ }
+ }
+ if (!name.value) {
+ name.value = 'no name';
+ }
+ //if the node is ignored, it should be given an order number as it won't be read at all
+ if (role.type === 'role') {
+ const axNode = {
+ backendDOMNodeId: backendDOMNodeId,
+ childIds: childIds,
+ ignored: ignored,
+ ignoredReasons: ignoredReasons,
+ name: name,
+ nodeId: nodeId,
+ ignoredReasons: ignoredReasons,
+ parentId: parentId,
+ properties: properties,
+ };
+ axArr.push(axNode);
+ }
+ }
+
+ // Sort nodes by backendDOMNodeId in ascending order
+
+ // Assign order based on sorted position
+ for (const axNode of axArr) {
+ if (!axNode.ignored) {
+ // Assuming you only want to assign order to non-ignored nodes
+ axNode.order = orderCounter++;
+ } else {
+ axNode.order = null; // Or keep it undefined, based on your requirement
+ }
+ }
+ return axArr;
+};
+
+// attaches Chrome Debugger API to tab for running future commands
+function attachDebugger(tabId, version) {
+ return new Promise((resolve, reject) => {
+ chrome.debugger.attach({ tabId: tabId }, version, () => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError);
+ } else {
+ resolve();
+ }
+ });
+ });
+}
+
+// sends commands with Chrome Debugger API
+function sendDebuggerCommand(tabId, command, params = {}) {
+ return new Promise((resolve, reject) => {
+ chrome.debugger.sendCommand({ tabId: tabId }, command, params, (response) => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError);
+ } else {
+ resolve(response);
+ }
+ });
+ });
+}
+
+// detaches Chrome Debugger API from tab
+function detachDebugger(tabId) {
+ return new Promise((resolve, reject) => {
+ chrome.debugger.detach({ tabId: tabId }, () => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError);
+ } else {
+ resolve();
+ }
+ });
+ });
+}
+
+// returns a pruned accessibility tree obtained using the Chrome Debugger API
+async function axRecord(tabId) {
+ try {
+ await attachDebugger(tabId, '1.3');
+ await sendDebuggerCommand(tabId, 'Accessibility.enable');
+ const response = await sendDebuggerCommand(tabId, 'Accessibility.getFullAXTree');
+ const pruned = pruneAxTree(response.nodes);
+ await detachDebugger(tabId);
+ return pruned;
+ } catch (error) {
+ console.error('axRecord debugger command failed:', error);
+ }
+}
+
+// Chrome Debugger API is unused unless accessibility features are toggled on with UI.
+// This function will replace the current empty snapshot if accessibility features are toggled on and the current location's accessibility snapshot has not yet been recorded.
+async function replaceEmptySnap(tabsObj, tabId, toggleAxRecord) {
+ if (tabsObj[tabId].currLocation.axSnapshot === 'emptyAxSnap' && toggleAxRecord === true) {
+ // add new ax snapshot to currlocation
+ const addedAxSnap = await axRecord(tabId);
+ tabsObj[tabId].currLocation.axSnapshot = addedAxSnap;
+ // modify array to include the new recorded ax snapshot
+ tabsObj[tabId].axSnapshots[tabsObj[tabId].currLocation.index] = addedAxSnap;
+ }
+}
+
// This function will create the first instance of the test app's tabs object
// which will hold test app's snapshots, link fiber tree info, chrome tab info, etc.
function createTabObj(title) {
@@ -25,9 +232,11 @@ function createTabObj(title) {
// snapshots is an array of ALL state snapshots for stateful and stateless
// components the Reactime tab working on a specific user application
snapshots: [],
+ // axSnapshots is an array of the chrome accessibility tree at different points for state and stateless applications
+ axSnapshots: [],
// index here is the tab index that shows total amount of state changes
index: 0,
- //* this is our pointer so we know what the current state the user is checking
+ //* currLocation points to the current state the user is checking
// (this accounts for time travel aka when user clicks jump on the UI)
currLocation: null,
// points to the node that will generate the next child set by newest node or jump
@@ -42,10 +251,9 @@ function createTabObj(title) {
reactDevToolsInstalled: false,
targetPageisaReactApp: false,
},
- // Note: Persist is a now defunct feature. Paused = Locked
+ // Note: Paused = Locked
mode: {
- persist: false,
- paused: false,
+ paused: true,
},
// stores web metrics calculated by the content script file
webMetrics: {},
@@ -53,8 +261,11 @@ function createTabObj(title) {
}
// Each node stores a history of the link fiber tree.
-class Node {
- constructor(obj, tabObj) {
+// In practice, new Nodes are passed the following arguments:
+// 1. param 'obj' : arg request.payload, which is an object containing a tree from snapShot.ts and a route property
+// 2. param tabObj: arg tabsObj[tabId], which is an object that holds info about a specific tab. Should change the name of tabObj to tabCollection or something
+class HistoryNode {
+ constructor(tabObj, newStateSnapshot, newAxSnapshot) {
// continues the order of number of total state changes
this.index = tabObj.index;
tabObj.index += 1;
@@ -63,7 +274,8 @@ class Node {
this.name = tabObj.currParent;
// marks from what branch this node is originated
this.branch = tabObj.currBranch;
- this.stateSnapshot = obj;
+ this.stateSnapshot = newStateSnapshot;
+ this.axSnapshot = newAxSnapshot;
this.children = [];
}
}
@@ -76,7 +288,7 @@ function countCurrName(rootNode, name) {
return 1;
}
let branch = 0;
- rootNode.children.forEach(child => {
+ rootNode.children.forEach((child) => {
branch += countCurrName(child, name);
});
return branch;
@@ -84,7 +296,11 @@ function countCurrName(rootNode, name) {
// Adds a new node to the current location.
// Invoked in the case 'recordSnap'.
+// In practice, sendToHierarchy is passed the following arguments:
+// 1. param tabObj : arg tabObj[tabId]
+// 2. param newNode : arg an instance of the Node class
function sendToHierarchy(tabObj, newNode) {
+ // newNode.axSnapshot = tabObj.axSnapshots[tabObj.axSnapshots.length - 1];
if (!tabObj.currLocation) {
tabObj.currLocation = newNode;
tabObj.hierarchy = newNode;
@@ -121,26 +337,109 @@ function changeCurrLocation(tabObj, rootNode, index, name) {
}
if (rootNode.children) {
- rootNode.children.forEach(child => {
+ rootNode.children.forEach((child) => {
changeCurrLocation(tabObj, child, index, name);
});
}
}
+async function getActiveTab() {
+ try {
+ // First try to find a localhost tab
+ const localhostTab = await findLocalhostTab();
+ if (localhostTab) {
+ return localhostTab.id;
+ }
+
+ // If no localhost tab is found, provide a more informative error
+ const errorMessage =
+ 'No localhost tab found. Please ensure:\n' +
+ '1. A React development server is running\n' +
+ '2. The server is using localhost\n' +
+ '3. The development page is open in Chrome';
+
+ console.warn(errorMessage);
+
+ // Fallback to current active tab
+ const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
+ if (tabs.length > 0) {
+ return tabs[0].id;
+ }
+
+ throw new Error(errorMessage);
+ } catch (error) {
+ console.error('Error in getActiveTab:', error);
+ throw error;
+ }
+}
+
+/*
+ The 'chrome.runtime' API allows a connection to the background service worker (background.js).
+ This allows us to set up listener's for when we connect, message, and disconnect the script.
+*/
+
+// INCOMING CONNECTION FROM FRONTEND (MainContainer) TO BACKGROUND.JS
// Establishing incoming connection with Reactime.
-chrome.runtime.onConnect.addListener(port => {
- // port is one end of the connection - an object
- // push every port connected to the ports array
- portsArr.push(port);
- // On Reactime launch: make sure RT's active tab is correct
- if (portsArr.length > 0) {
- portsArr.forEach(bg => bg.postMessage({
- action: 'changeTab',
- payload: { tabId: activeTab.id, title: activeTab.title },
- }));
+chrome.runtime.onConnect.addListener(async (port) => {
+ /*
+ On initial connection, there is an onConnect event emitted. The 'addlistener' method provides a communication channel object ('port') when we connect to the service worker ('background.js') and applies it as the argument to it's 1st callback parameter.
+
+ the 'port' (type: communication channel object) is the communication channel between different components within our Chrome extension, not to a port on the Chrome browser tab or the extension's port on the Chrome browser.
+
+ The port object facilitates communication between the Reactime front-end and this 'background.js' script. This allows you to:
+ 1. send messages and data
+ (look for 'onMessage'/'postMessage' methods within this page)
+ 2. receive messages and data
+ (look for 'addListener' methods within this page)
+ between the front-end and the background.
+
+ To establish communication between different parts of your extension:
+ for the connecting end: use chrome.runtime.connect()
+ for the listening end: use chrome.runtime.onConnect.
+ Once the connection is established, a port object is passed to the addListener callback function, allowing you to start exchanging data.
+
+ Again, this port object is used for communication within your extension, not for communication with external ports or tabs in the Chrome browser. If you need to interact with specific tabs or external ports, you would use other APIs or methods, such as chrome.tabs or other Chrome Extension APIs.
+ */
+ portsArr.push(port); // push each Reactime communication channel object to the portsArr
+ // sets the current Title of the Reactime panel
+
+ /**
+ * Sends messages to ports in the portsArr array, triggering a tab change action.
+ */
+ function sendMessagesToPorts() {
+ portsArr.forEach((bg, index) => {
+ bg.postMessage({
+ action: 'changeTab',
+ payload: { tabId: activeTab.id, title: activeTab.title },
+ });
+ });
+ }
+ if (port.name === 'keepAlivePort') {
+ console.log('Keep-alive port connected:', port);
+
+ // Keep the port open by responding to any message
+ port.onMessage.addListener((msg) => {
+ console.log('Received message from content script:', msg);
+ });
+
+ port.onDisconnect.addListener(() => {
+ console.warn('Keep-alive port disconnected.');
+ });
+ }
+ if (portsArr.length > 0 && Object.keys(tabsObj).length > 0) {
+ //if the activeTab is not set during the onActivate API, run a query to get the tabId and set activeTab
+ if (!activeTab) {
+ const tabId = await getActiveTab();
+ chrome.tabs.get(tabId, (tab) => {
+ // never set a reactime instance to the active tab
+ if (!tab.pendingUrl?.match('^chrome-extension')) {
+ activeTab = tab;
+ sendMessagesToPorts();
+ }
+ });
+ }
}
- // send tabs obj to the connected devtools as soon as connection to devtools is made
if (Object.keys(tabsObj).length > 0) {
port.postMessage({
action: 'initialConnectSnapshots',
@@ -148,89 +447,158 @@ chrome.runtime.onConnect.addListener(port => {
});
}
- // every time devtool is closed, remove the port from portsArr
- port.onDisconnect.addListener(e => {
- for (let i = 0; i < portsArr.length; i += 1) {
- if (portsArr[i] === e) {
- portsArr.splice(i, 1);
- break;
- }
+ // Handles port disconnection by removing the disconnected port
+ port.onDisconnect.addListener(() => {
+ const index = portsArr.indexOf(port);
+ if (index !== -1) {
+ console.warn(`Port at index ${index} disconnected. Removing it.`);
+ portsArr.splice(index, 1);
+
+ // Notify remaining ports about the disconnection
+ portsArr.forEach((remainingPort) => {
+ try {
+ remainingPort.postMessage({
+ action: 'portDisconnect',
+ });
+ } catch (error) {
+ console.warn('Failed to notify port of disconnection:', error);
+ }
+ });
}
});
+ // INCOMING MESSAGE FROM FRONTEND (MainContainer) TO BACKGROUND.js
// listen for message containing a snapshot from devtools and send it to contentScript -
// (i.e. they're all related to the button actions on Reactime)
- port.onMessage.addListener(msg => {
- // msg is action denoting a time jump in devtools
- // ---------------------------------------------------------------
- // message incoming from devTools should look like this:
- // {
- // action: 'emptySnap',
- // payload: tabsObj,
- // tabId: 101
- // }
- // ---------------------------------------------------------------
+ port.onMessage.addListener(async (msg) => {
const { action, payload, tabId } = msg;
+ console.log(`Received message - Action: ${action}, Payload:`, payload);
+ if (!payload && ['import', 'setPause', 'jumpToSnap'].includes(action)) {
+ console.error(`Invalid payload received for action: ${action}`, new Error().stack);
+ }
switch (action) {
+ // import action comes through when the user uses the "upload" button on the front end to import an existing snapshot tree
case 'import': // create a snapshot property on tabId and set equal to tabs object
// may need do something like filter payload from stateless
- tabsObj[tabId].snapshots = payload;
- return true;
+ tabsObj[tabId].snapshots = payload.snapshots; // reset snapshots to page last state recorded
+ tabsObj[tabId].axSnapshots = payload.axSnapshots; // TRYING to import axsnapshots
+ // tabsObj[tabId].hierarchy = savedSnapshot.hierarchy; // why don't we just use hierarchy? Because it breaks everything...
+ tabsObj[tabId].hierarchy.children = payload.hierarchy.children; // resets hierarchy to last state recorded
+ tabsObj[tabId].hierarchy.stateSnapshot = payload.hierarchy.stateSnapshot; // resets hierarchy to last state recorded
+ tabsObj[tabId].hierarchy.axSnapshot = payload.hierarchy.axSnapshot; // TRYING to import hierarchy axsnapshot
+ tabsObj[tabId].currLocation = payload.currLocation; // resets currLocation to last state recorded
+ tabsObj[tabId].index = payload.index; //reset index to last state recorded
+ tabsObj[tabId].currParent = payload.currParent; // reset currParent to last state recorded
+ tabsObj[tabId].currBranch = payload.currBranch; // reset currBranch to last state recorded
+
+ return true; // return true so that port remains open
+
+ // emptySnap actions comes through when the user uses the 'clear' button on the front end to clear the snapshot history and move slider back to 0 position
case 'emptySnap':
- // reset snapshots to page last state recorded
- tabsObj[tabId].snapshots = [
- tabsObj[tabId].snapshots[tabsObj[tabId].snapshots.length - 1],
- ];
- // resets hierarchy
- tabsObj[tabId].hierarchy.children = [];
- // resets hierarchy to page last state recorded
+ tabsObj[tabId].snapshots = [tabsObj[tabId].snapshots[tabsObj[tabId].currLocation.index]]; // reset snapshots to current page state
+ tabsObj[tabId].hierarchy.children = []; // resets hierarchy
tabsObj[tabId].hierarchy.stateSnapshot = {
+ // resets hierarchy to current page state
+ // not sure why they are doing a "shallow" deep copy
...tabsObj[tabId].snapshots[0],
};
- // resets currLocation to page last state recorded
- tabsObj[tabId].currLocation = tabsObj[tabId].hierarchy;
- tabsObj[tabId].index = 1;
- tabsObj[tabId].currParent = 0;
- tabsObj[tabId].currBranch = 1;
- return true;
- // Pause = lock on tab
- case 'setPause':
+ tabsObj[tabId].axSnapshots = [
+ tabsObj[tabId].axSnapshots[tabsObj[tabId].currLocation.index],
+ ]; // resets axSnapshots to current page state
+ tabsObj[tabId].hierarchy.axSnapshot = tabsObj[tabId].axSnapshots[0]; // resets hierarchy to accessibility tree of current page state
+ tabsObj[tabId].index = 1; //reset index
+ tabsObj[tabId].currParent = 0; // reset currParent
+ tabsObj[tabId].currBranch = 1; // reset currBranch
+ tabsObj[tabId].currLocation = tabsObj[tabId].hierarchy; // reset currLocation
+
+ return true; // return true so that port remains open
+
+ case 'setPause': // Pause = lock on tab
tabsObj[tabId].mode.paused = payload;
+ return true; // return true so that port remains open
+
+ // Handling the launchContentScript case with proper validation
+ case 'launchContentScript': {
+ if (!tabId) {
+ console.error('No tabId provided for content script injection');
+ return false;
+ }
+
+ try {
+ // Validate the tab exists before injecting
+ chrome.tabs.get(tabId, async (tab) => {
+ if (chrome.runtime.lastError) {
+ console.error('Error getting tab:', chrome.runtime.lastError);
+ return;
+ }
+
+ // Skip injection for chrome:// URLs
+ if (tab.url?.startsWith('chrome://')) {
+ console.warn('Cannot inject scripts into chrome:// URLs');
+ return;
+ }
+
+ try {
+ await chrome.scripting.executeScript({
+ target: { tabId: tab.id },
+ files: ['bundles/content.bundle.js'],
+ });
+ console.log('Content script injected successfully');
+ } catch (err) {
+ console.error('Error injecting content script:', err);
+ }
+ });
+ } catch (err) {
+ console.error('Error in launchContentScript:', err);
+ }
return true;
- // persist is now depreacted
- case 'setPersist':
- tabsObj[tabId].mode.persist = payload;
- return true;
- case 'launchContentScript':
- chrome.scripting.executeScript({
- target: { tabId },
- files: ['bundles/content.bundle.js'],
- });
- return true;
+ }
+
case 'jumpToSnap':
chrome.tabs.sendMessage(tabId, msg);
return true; // attempt to fix message port closing error, consider return Promise
+
case 'toggleRecord':
chrome.tabs.sendMessage(tabId, msg);
return true;
+
+ case 'toggleAxRecord':
+ toggleAxRecord = !toggleAxRecord;
+
+ await replaceEmptySnap(tabsObj, tabId, toggleAxRecord);
+ // sends new tabs obj to devtools
+ if (portsArr.length > 0) {
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'sendSnapshots',
+ payload: tabsObj,
+ tabId,
+ }),
+ );
+ }
+ return true; // return true so that port remains open
+
+ case 'reinitialize':
+ chrome.tabs.sendMessage(tabId, msg);
+ return true;
+
default:
return true;
}
});
});
+// INCOMING MESSAGE FROM CONTENT SCRIPT TO BACKGROUND.JS
// background.js listening for a message from contentScript.js
-chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
+chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
// AUTOMATIC MESSAGE SENT BY CHROME WHEN CONTENT SCRIPT IS FIRST LOADED: set Content
if (request.type === 'SIGN_CONNECT') {
return true;
}
const tabTitle = sender.tab.title;
const tabId = sender.tab.id;
- const {
- action, index, name, value,
- } = request;
+ const { action, index, name, value } = request;
let isReactTimeTravel = false;
if (name) {
@@ -239,45 +607,78 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// Filter out tabs that don't have reactime, tabs that dont use react?
if (
- action === 'tabReload'
- || action === 'recordSnap'
- || action === 'jumpToSnap'
- || action === 'injectScript'
- || action === 'devToolsInstalled'
- || action === 'aReactApp'
+ action === 'tabReload' ||
+ action === 'recordSnap' ||
+ action === 'jumpToSnap' ||
+ action === 'injectScript' ||
+ action === 'devToolsInstalled' ||
+ action === 'aReactApp'
) {
isReactTimeTravel = true;
} else {
return true;
}
- // everytime we get a new tabid, add it to the object
+ // everytime we get a new tabId, add it to the object
if (isReactTimeTravel && !(tabId in tabsObj)) {
tabsObj[tabId] = createTabObj(tabTitle);
}
-
switch (action) {
+ case 'attemptReconnect': {
+ const success = 'portSuccessfullyConnected';
+ sendResponse({ success });
+ break;
+ }
case 'jumpToSnap': {
changeCurrLocation(tabsObj[tabId], tabsObj[tabId].hierarchy, index, name);
+ // hack to test without message from mainSlice
+ // toggleAxRecord = true;
+ // record ax tree snapshot of the state that has now been jumped to if user did not toggle button on
+ await replaceEmptySnap(tabsObj, tabId, toggleAxRecord);
+
+ // sends new tabs obj to devtools
if (portsArr.length > 0) {
- portsArr.forEach(bg => bg.postMessage({
- action: 'setCurrentLocation',
- payload: tabsObj,
- }));
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'sendSnapshots',
+ payload: tabsObj,
+ tabId,
+ }),
+ );
+ }
+
+ if (portsArr.length > 0) {
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'setCurrentLocation',
+ payload: tabsObj,
+ }),
+ );
}
break;
}
+
// Confirmed React Dev Tools installed, send this info to frontend
case 'devToolsInstalled': {
tabsObj[tabId].status.reactDevToolsInstalled = true;
- portsArr.forEach(bg => bg.postMessage({
- action: 'devTools',
- payload: tabsObj,
- }));
+
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'devTools',
+ payload: tabsObj,
+ }),
+ );
break;
}
- // Confirmed target is a react app. No need to send to frontend
+
case 'aReactApp': {
tabsObj[tabId].status.targetPageisaReactApp = true;
+ // JR 12.20.23 9.53pm added a message action to send to frontend
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'aReactApp',
+ payload: tabsObj,
+ }),
+ );
break;
}
// This injects a script into the app that you're testing Reactime on,
@@ -289,13 +690,12 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', file);
// eslint-disable-next-line prefer-template
- // document.title = tab + '-' + document.title; // error of injecting random number
htmlBody.appendChild(script);
};
chrome.scripting.executeScript({
target: { tabId },
- function: injectScript,
+ func: injectScript,
args: [chrome.runtime.getURL('bundles/backend.bundle.js'), tabId],
});
break;
@@ -303,53 +703,102 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
case 'recordSnap': {
const sourceTab = tabId;
tabsObj[tabId].webMetrics = metrics;
+
if (!firstSnapshotReceived[tabId]) {
firstSnapshotReceived[tabId] = true;
reloaded[tabId] = false;
tabsObj[tabId].webMetrics = metrics;
tabsObj[tabId].snapshots.push(request.payload);
+
+ // check if accessibility recording has been toggled on
+ let addedAxSnap;
+ if (toggleAxRecord === true) {
+ addedAxSnap = await axRecord(tabId);
+ tabsObj[tabId].axSnapshots.push(addedAxSnap);
+ } else {
+ addedAxSnap = 'emptyAxSnap';
+ tabsObj[tabId].axSnapshots.push(addedAxSnap);
+ }
sendToHierarchy(
tabsObj[tabId],
- new Node(request.payload, tabsObj[tabId]),
+ new HistoryNode(tabsObj[tabId], request.payload, addedAxSnap),
);
+
if (portsArr.length > 0) {
- portsArr.forEach(bg => bg.postMessage({
- action: 'initialConnectSnapshots',
- payload: tabsObj,
- }));
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'initialConnectSnapshots',
+ payload: tabsObj,
+ }),
+ );
}
+
break;
}
// DUPLICATE SNAPSHOT CHECK
- const previousSnap = tabsObj[tabId].currLocation.stateSnapshot.children[0].componentData
- .actualDuration;
- const incomingSnap = request.payload.children[0].componentData.actualDuration;
- if (previousSnap === incomingSnap) break;
+ const isDuplicateSnapshot = (previous, incoming) => {
+ if (!previous || !incoming) return false;
+ const prevData = previous?.componentData;
+ const incomingData = incoming?.componentData;
+
+ // Check if both snapshots have required data
+ if (!prevData || !incomingData) return false;
+
+ const timeDiff = Math.abs(
+ (incomingData.timestamp || Date.now()) - (prevData.timestamp || Date.now()),
+ );
+ return prevData.actualDuration === incomingData.actualDuration && timeDiff < 1000;
+ };
+
+ const previousSnap = tabsObj[tabId]?.currLocation?.stateSnapshot?.children[0];
+ const incomingSnap = request.payload.children[0];
+
+ if (isDuplicateSnapshot(previousSnap, incomingSnap)) {
+ console.warn('Duplicate snapshot detected, skipping');
+ break;
+ }
- // Or if it is a snap after a jump, we don't record it.
+ // Or if it is a snapShot after a jump, we don't record it.
if (reloaded[tabId]) {
// don't add anything to snapshot storage if tab is reloaded for the initial snapshot
reloaded[tabId] = false;
} else {
tabsObj[tabId].snapshots.push(request.payload);
- //! INVOKING buildHierarchy FIGURE OUT WHAT TO PASS IN!!!!
+ // INVOKING buildHierarchy FIGURE OUT WHAT TO PASS IN
if (!tabsObj[tabId][index]) {
+ // check if accessibility recording has been toggled on
+ let addedAxSnap;
+ if (toggleAxRecord === true) {
+ addedAxSnap = await axRecord(tabId);
+ tabsObj[tabId].axSnapshots.push(addedAxSnap);
+ } else {
+ addedAxSnap = 'emptyAxSnap';
+ tabsObj[tabId].axSnapshots.push(addedAxSnap);
+ }
sendToHierarchy(
tabsObj[tabId],
- new Node(request.payload, tabsObj[tabId]),
+ new HistoryNode(tabsObj[tabId], request.payload, addedAxSnap),
);
}
}
+
// sends new tabs obj to devtools
if (portsArr.length > 0) {
- portsArr.forEach(bg => bg.postMessage({
- action: 'sendSnapshots',
- payload: tabsObj,
- sourceTab,
- }));
+ portsArr.forEach((bg, index) => {
+ try {
+ bg.postMessage({
+ action: 'sendSnapshots',
+ payload: tabsObj,
+ sourceTab,
+ });
+ } catch (error) {
+ console.warn(`Failed to send snapshots to port at index ${index}:`, error);
+ }
+ });
+ } else {
+ console.warn('No active ports to send snapshots to.');
}
- break;
}
default:
break;
@@ -357,14 +806,16 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
return true; // attempt to fix close port error
});
-// when tab is closed, remove the tabid from the tabsObj
-chrome.tabs.onRemoved.addListener(tabId => {
+// when tab is closed, remove the tabId from the tabsObj
+chrome.tabs.onRemoved.addListener((tabId) => {
// tell devtools which tab to delete
if (portsArr.length > 0) {
- portsArr.forEach(bg => bg.postMessage({
- action: 'deleteTab',
- payload: tabId,
- }));
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'deleteTab',
+ payload: tabId,
+ }),
+ );
}
// delete the tab from the tabsObj
@@ -381,10 +832,12 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
if (changeInfo.title && changeInfo.title !== tabsObj[tabId].title) {
// tell devtools which tab to delete
if (portsArr.length > 0) {
- portsArr.forEach(bg => bg.postMessage({
- action: 'deleteTab',
- payload: tabId,
- }));
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'deleteTab',
+ payload: tabId,
+ }),
+ );
}
// delete the tab from the tabsObj
@@ -398,21 +851,65 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
}
});
-// when tab view is changed, put the tabid as the current tab
-chrome.tabs.onActivated.addListener(info => {
- // get info about tab information from tabId
- chrome.tabs.get(info.tabId, tab => {
- // never set a reactime instance to the active tab
- if (!tab.pendingUrl?.match('^chrome-extension')) {
- activeTab = tab;
- if (portsArr.length > 0) {
- portsArr.forEach(bg => bg.postMessage({
- action: 'changeTab',
- payload: { tabId: tab.id, title: tab.title },
- }));
+// When tab view is changed, put the tabId as the current tab
+chrome.tabs.onActivated.addListener(async (info) => {
+ // Get info about the tab information from tabId
+ try {
+ const tab = await chrome.tabs.get(info.tabId);
+
+ // Only update activeTab if:
+ // 1. It's not a Reactime extension tab
+ // 2. We don't already have a localhost tab being tracked
+ // 3. Or if it is a localhost tab (prioritize localhost)
+ if (!tab.url?.match('^chrome-extension')) {
+ if (isLocalhost(tab.url)) {
+ // Always prioritize localhost tabs
+ activeTab = tab;
+ if (portsArr.length > 0) {
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'changeTab',
+ payload: { tabId: tab.id, title: tab.title },
+ }),
+ );
+ }
+ } else if (!activeTab || !isLocalhost(activeTab.url)) {
+ // Only set non-localhost tab as active if we don't have a localhost tab
+ activeTab = tab;
+ if (portsArr.length > 0) {
+ portsArr.forEach((bg) =>
+ bg.postMessage({
+ action: 'changeTab',
+ payload: { tabId: tab.id, title: tab.title },
+ }),
+ );
+ }
}
}
- });
+ } catch (error) {
+ console.error('Error in tab activation handler:', error);
+ }
+});
+
+// Ensure keep-alive is set up when the extension is installed
+chrome.runtime.onInstalled.addListener(() => {
+ console.log('Extension installed. Setting up keep-alive...');
+ setupKeepAlive();
+});
+
+// Ensure keep-alive is set up when the browser starts
+chrome.runtime.onStartup.addListener(() => {
+ console.log('Browser started. Setting up keep-alive...');
+ setupKeepAlive();
+});
+
+// Optional: Reset keep-alive when a message is received (to cover edge cases)
+chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
+ if (message === 'resetKeepAlive') {
+ console.log('Resetting keep-alive as requested.');
+ setupKeepAlive();
+ sendResponse({ success: true });
+ }
});
// when reactime is installed
@@ -425,16 +922,34 @@ chrome.runtime.onInstalled.addListener(() => {
});
});
-// when context menu is clicked, listen for the menuItemId,
-// if user clicked on reactime, open the devtools window
-chrome.contextMenus.onClicked.addListener(({ menuItemId }) => {
- const options = {
- type: 'panel',
- left: 0,
- top: 0,
- width: 1000,
- height: 1000,
- url: chrome.runtime.getURL('panel.html'),
- };
- if (menuItemId === 'reactime') chrome.windows.create(options);
+chrome.contextMenus.onClicked.addListener((info, tab) => {
+ if (info.menuItemId === 'reactime') {
+ chrome.windows
+ .create({
+ url: chrome.runtime.getURL('panel.html'),
+ type: 'popup',
+ width: 1200,
+ height: 800,
+ })
+ .then((window) => {
+ // Listen for window close
+ chrome.windows.onRemoved.addListener(function windowClosedListener(windowId) {
+ if (windowId === window.id) {
+ // Cleanup when window is closed
+ portsArr.forEach((port) => {
+ try {
+ port.disconnect();
+ } catch (error) {
+ console.warn('Error disconnecting port:', error);
+ }
+ });
+ // Clear the ports array
+ portsArr.length = 0;
+
+ // Remove this specific listener
+ chrome.windows.onRemoved.removeListener(windowClosedListener);
+ }
+ });
+ });
+ }
});
diff --git a/src/extension/build/assets/blackWhiteSquareIcon128.png b/src/extension/build/assets/blackWhiteSquareIcon128.png
new file mode 100644
index 000000000..9ff5c33e0
Binary files /dev/null and b/src/extension/build/assets/blackWhiteSquareIcon128.png differ
diff --git a/src/extension/build/assets/blackWhiteSquareIcon48.png b/src/extension/build/assets/blackWhiteSquareIcon48.png
new file mode 100644
index 000000000..d054e2b6c
Binary files /dev/null and b/src/extension/build/assets/blackWhiteSquareIcon48.png differ
diff --git a/src/extension/build/assets/icon128.png b/src/extension/build/assets/icon128.png
deleted file mode 100644
index 5010da137..000000000
Binary files a/src/extension/build/assets/icon128.png and /dev/null differ
diff --git a/src/extension/build/assets/icon48.png b/src/extension/build/assets/icon48.png
deleted file mode 100644
index bcc344401..000000000
Binary files a/src/extension/build/assets/icon48.png and /dev/null differ
diff --git a/src/extension/build/assets/logo-no-version.png b/src/extension/build/assets/logo-no-version.png
deleted file mode 100644
index 1cbbd91bf..000000000
Binary files a/src/extension/build/assets/logo-no-version.png and /dev/null differ
diff --git a/src/extension/build/assets/logo.png b/src/extension/build/assets/logo.png
deleted file mode 100644
index 04c13455f..000000000
Binary files a/src/extension/build/assets/logo.png and /dev/null differ
diff --git a/src/extension/build/assets/whiteBlackSquareIcon128.png b/src/extension/build/assets/whiteBlackSquareIcon128.png
new file mode 100644
index 000000000..cb89df108
Binary files /dev/null and b/src/extension/build/assets/whiteBlackSquareIcon128.png differ
diff --git a/src/extension/build/assets/whiteBlackSquareIcon48.png b/src/extension/build/assets/whiteBlackSquareIcon48.png
new file mode 100644
index 000000000..01e46463c
Binary files /dev/null and b/src/extension/build/assets/whiteBlackSquareIcon48.png differ
diff --git a/src/extension/build/assets/whiteBlackSquareLogo.png b/src/extension/build/assets/whiteBlackSquareLogo.png
new file mode 100644
index 000000000..dbd50002c
Binary files /dev/null and b/src/extension/build/assets/whiteBlackSquareLogo.png differ
diff --git a/src/extension/build/build.zip b/src/extension/build/build.zip
deleted file mode 100644
index 6d642a308..000000000
Binary files a/src/extension/build/build.zip and /dev/null differ
diff --git a/src/extension/build/devtools.html b/src/extension/build/devtools.html
index 53085350a..de554fb40 100644
--- a/src/extension/build/devtools.html
+++ b/src/extension/build/devtools.html
@@ -1,15 +1,13 @@
-
+
+
+
+
+
+ Reactime v26.0
+
-
-
-
-
- Reactime v9
-
-
-
-
-
-
+
+
+
diff --git a/src/extension/build/devtools.js b/src/extension/build/devtools.js
index 197ebb741..02c6d8f96 100644
--- a/src/extension/build/devtools.js
+++ b/src/extension/build/devtools.js
@@ -1 +1,6 @@
-chrome.devtools.panels.create('Reactime', "assets/icon48.png", 'panel.html', () => {});
+chrome.devtools.panels.create(
+ 'Reactime',
+ 'assets/whiteBlackSquareIcon48.png',
+ 'panel.html',
+ () => {},
+);
diff --git a/src/extension/build/manifest.json b/src/extension/build/manifest.json
index 0aa0c0f46..5d99bd806 100644
--- a/src/extension/build/manifest.json
+++ b/src/extension/build/manifest.json
@@ -1,15 +1,16 @@
{
"name": "Reactime",
- "version": "16.0.0",
+ "version": "26.1",
"devtools_page": "devtools.html",
- "description": "A Chrome extension that helps debug React applications by memorizing the state of components with every render.",
+ "description": "A Chrome extension for time travel debugging and performance monitoring in React applications.",
"manifest_version": 3,
"background": {
"service_worker": "bundles/background.bundle.js"
},
+
"icons": {
- "48": "assets/icon48.png",
- "128": "assets/icon128.png"
+ "48": "assets/whiteBlackSquareIcon48.png",
+ "128": "assets/whiteBlackSquareIcon128.png"
},
"content_scripts": [
{
@@ -23,6 +24,6 @@
"matches": [""]
}
],
- "permissions": ["contextMenus", "tabs", "activeTab", "scripting"],
+ "permissions": ["contextMenus", "tabs", "activeTab", "scripting", "debugger", "alarms"],
"host_permissions": [""]
}
diff --git a/src/extension/build/panel.html b/src/extension/build/panel.html
index 4ac1d1a5a..9c475132a 100644
--- a/src/extension/build/panel.html
+++ b/src/extension/build/panel.html
@@ -1,14 +1,14 @@
-
+
-
-
-
-
- Reactime 15.0
-
+
+
+
+
+ Reactime v26.0
+
-
-
-
-
+
+
+
+
diff --git a/src/extension/contentScript.ts b/src/extension/contentScript.ts
index f43e7fa80..76a992750 100644
--- a/src/extension/contentScript.ts
+++ b/src/extension/contentScript.ts
@@ -1,8 +1,105 @@
// Web vital metrics calculated by 'web-vitals' npm package to be displayed
// in Web Metrics tab of Reactime app.
-import {
- getTTFB, getLCP, getFID, getFCP, getCLS,
-} from 'web-vitals';
+import { current } from '@reduxjs/toolkit';
+import { onTTFB, onLCP, onFID, onFCP, onCLS, onINP } from 'web-vitals';
+
+const MAX_RECONNECT_ATTEMPTS = 5;
+const INITIAL_RECONNECT_DELAY = 1000;
+const MAX_RECONNECT_DELAY = 16000;
+
+let currentPort = null;
+let isAttemptingReconnect = false;
+
+function establishConnection(attemptNumber = 1) {
+ console.log(`Establishing connection, attempt ${attemptNumber}`);
+
+ try {
+ currentPort = chrome.runtime.connect({ name: 'keepAlivePort' });
+
+ console.log('Port created, setting up listeners');
+
+ currentPort.onMessage.addListener((msg) => {
+ console.log('Port received message:', msg);
+ });
+
+ currentPort.onDisconnect.addListener(() => {
+ const error = chrome.runtime.lastError;
+ console.log('Port disconnect triggered', error);
+
+ // Clear current port
+ currentPort = null;
+
+ // Prevent multiple simultaneous reconnection attempts
+ if (isAttemptingReconnect) {
+ console.log('Already attempting to reconnect, skipping');
+ return;
+ }
+
+ isAttemptingReconnect = true;
+
+ // Calculate delay with exponential backoff
+ const delay = Math.min(
+ INITIAL_RECONNECT_DELAY * Math.pow(2, attemptNumber - 1),
+ MAX_RECONNECT_DELAY,
+ );
+
+ if (attemptNumber <= MAX_RECONNECT_ATTEMPTS) {
+ console.log(
+ `Will attempt reconnection ${attemptNumber}/${MAX_RECONNECT_ATTEMPTS} in ${delay}ms`,
+ );
+
+ window.postMessage(
+ {
+ action: 'portDisconnect',
+ payload: {
+ attemptNumber,
+ maxAttempts: MAX_RECONNECT_ATTEMPTS,
+ nextRetryDelay: delay,
+ },
+ },
+ '*',
+ );
+
+ setTimeout(() => {
+ isAttemptingReconnect = false;
+ establishConnection(attemptNumber + 1);
+ }, delay);
+ } else {
+ console.log('Max reconnection attempts reached');
+ isAttemptingReconnect = false;
+
+ window.postMessage(
+ {
+ action: 'portDisconnect',
+ payload: {
+ autoReconnectFailed: true,
+ message: 'Automatic reconnection failed. Please use the reconnect button.',
+ },
+ },
+ '*',
+ );
+ }
+ });
+
+ // Send initial test message
+ currentPort.postMessage({ type: 'connectionTest' });
+ console.log('Test message sent');
+ } catch (error) {
+ console.error('Error establishing connection:', error);
+ isAttemptingReconnect = false;
+
+ // If immediate connection fails, try again
+ if (attemptNumber <= MAX_RECONNECT_ATTEMPTS) {
+ const delay = INITIAL_RECONNECT_DELAY;
+ console.log(`Connection failed immediately, retrying in ${delay}ms`);
+ setTimeout(() => establishConnection(attemptNumber + 1), delay);
+ }
+ }
+}
+
+// Initial connection
+console.log('Starting initial connection');
+establishConnection();
// Reactime application starts off with this file, and will send
// first message to background.js for initial tabs object set up.
@@ -12,7 +109,8 @@ let firstMessage = true;
// Listens for window messages (from the injected script on the DOM)
let isRecording = true;
-window.addEventListener('message', msg => {
+// INCOMING MESSAGE FROM BACKEND (index.ts) TO CONTENT SCRIPT
+window.addEventListener('message', (msg) => {
// Event listener runs constantly based on actions
// recorded on the test application from backend files (linkFiber.ts).
// Background.js has a listener that includes switch cases, depending on
@@ -28,6 +126,8 @@ window.addEventListener('message', msg => {
const { action }: { action: string } = msg.data;
if (action === 'recordSnap') {
if (isRecording) {
+ // add timestamp to payload for the purposes of duplicate screenshot check in backgroundscript -ellie
+ msg.data.payload.children[0].componentData.timestamp = Date.now();
chrome.runtime.sendMessage(msg.data);
}
}
@@ -39,9 +139,10 @@ window.addEventListener('message', msg => {
}
});
+// FROM BACKGROUND TO CONTENT SCRIPT
// Listening for messages from the UI of the Reactime extension.
-chrome.runtime.onMessage.addListener(request => {
- const { action }: { action: string; } = request;
+chrome.runtime.onMessage.addListener((request) => {
+ const { action, port }: { action: string; port?: string } = request;
if (action) {
// Message being sent from background.js
// This is toggling the record button on Reactime when clicked
@@ -51,13 +152,30 @@ chrome.runtime.onMessage.addListener(request => {
// this is only listening for Jump toSnap
if (action === 'jumpToSnap') {
chrome.runtime.sendMessage(request);
+ // After the jumpToSnap action has been sent back to background js,
+ // it will send the same action to backend files (index.ts) for it execute the jump feature
+ // '*' == target window origin required for event to be dispatched, '*' = no preference
+ window.postMessage(request, '*');
+ }
+ if (action === 'portDisconnect' && !currentPort && !isAttemptingReconnect) {
+ console.log('Received disconnect message, initiating reconnection');
+ // When we receive a port disconnection message, relay it to the window
+ window.postMessage(
+ {
+ action: 'portDisconnect',
+ },
+ '*',
+ );
+
+ // Attempt to re-establish connection
+ establishConnection();
}
- // After the jumpToSnap action has been sent back to background js,
- // it will send the same action to backend files (index.ts) for it execute the jump feature
- // '*' == target window origin required for event to be dispatched, '*' = no preference
- window.postMessage(request, '*');
+
+ if (action === 'reinitialize') {
+ window.postMessage(request, '*');
+ }
+ return true;
}
- return true; // attempt to fix port closing console error
});
// Performance metrics being calculated by the 'web-vitals' api and
@@ -66,7 +184,6 @@ chrome.runtime.onMessage.addListener(request => {
const metrics = {};
const gatherMetrics = ({ name, value }) => {
metrics[name] = value;
-
chrome.runtime.sendMessage({
type: 'performance:metric',
name,
@@ -75,11 +192,12 @@ const gatherMetrics = ({ name, value }) => {
};
// Functions that calculate web metric values.
-getTTFB(gatherMetrics);
-getLCP(gatherMetrics);
-getFID(gatherMetrics);
-getFCP(gatherMetrics);
-getCLS(gatherMetrics);
+onTTFB(gatherMetrics);
+onLCP(gatherMetrics);
+onFID(gatherMetrics);
+onFCP(gatherMetrics);
+onCLS(gatherMetrics);
+onINP(gatherMetrics);
// Send message to background.js for injecting the initial script
// into the app's DOM.
diff --git a/tsconfig.json b/tsconfig.json
index 3edaf6481..e2e7ac64f 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,26 +1,128 @@
{
"compilerOptions": {
- "outDir": "./src/extension/build/bundles/",
- "module": "es6",
- // "noImplicitAny": true,
- "target": "es5",
- "jsx": "react",
- "removeComments": true,
- "allowJs": true,
- "allowSyntheticDefaultImports": true,
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+
+ /* Projects */
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
+
+ /* Language and Environment */
+ "target": "ES6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ "jsx": "react" /* Specify what JSX code is generated. */,
+ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "ES6" /* Specify what module code is generated. */,
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ "moduleResolution": "node10" /* Specify how TypeScript looks up a file from a given module specifier. */,
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
"typeRoots": [
"./node_modules/@types"
- ],
- "types": ["chrome", "jest", "node"],
- "esModuleInterop": true,
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "forceConsistentCasingInFileNames": true,
+ ] /* Specify multiple folders that act like './node_modules/@types'. */,
+ "types": [
+ "chrome",
+ "jest",
+ "node"
+ ] /* Specify type package names to be included without being referenced in a source file. */,
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
+ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
+ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
+ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
+ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
+ "resolveJsonModule": true /* Enable importing .json files. */,
+ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
+ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
+
+ /* JavaScript Support */
+ "allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
+ // "checkJs": true /* Enable error reporting in type-checked JavaScript files. */,
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+ /* Emit */
+ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
+ "sourceMap": true /* Create source map files for emitted JavaScript files. */,
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+ "outDir": "./src/extension/build/bundles/" /* Specify an output folder for all emitted files. */,
+ "removeComments": true /* Disable emitting comments. */,
+ // "noEmit": true, /* Disable emitting files from a compilation. */
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
+ "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
+ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
+
+ /* Interop Constraints */
+ "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */,
+ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
+ "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */,
+ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
+
+ /* Type Checking */
+ // "strict": true /* Enable all strict type-checking options. */,
+ // "noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */,
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
+
+ /* Completeness */
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
},
- "include": ["./src/app", "./src/backend", "./src/extension", "./jest-setup.ts", "./global.d.ts"],
- "exclude": ["./src/app/__tests__", "./src/backend/__tests__", "node_modules"],
- "typeDocOptions": {
- "mode": "file",
+ // Specifies which files should be included in the compilation.
+ "include": ["./src/**/*", "./src/backend", "./src/extension", "./global.d.ts"],
+ "exclude": [
+ "./src/app/__tests__",
+ "./src/backend/__tests__",
+ "node_modules",
+ "./src/extension/build/bundles"
+ ],
+ "typedocOptions": {
+ "entryPoints": ["src"],
+ "entryPointStrategy": "expand",
"out": "docs"
- },
-}
\ No newline at end of file
+ }
+}
diff --git a/typedoc.json b/typedoc.json
deleted file mode 100644
index fffd02d04..000000000
--- a/typedoc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "mode": "modules",
- "out": "docs",
- "includes": [
- "./src/backend"
- ],
- "exclude": [
- "**/__tests__/**",
- "**/**/**/build/**",
- "**/types/**"
- ],
- "name": "Reactime 5.0"
-}
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index e11cdd635..b64c21032 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,56 +1,38 @@
+require('dotenv').config();
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
-const ChromeExtensionReloader = require('webpack-chrome-extension-reloader'); // enable hot reloading while developing a chrome extension
+
+/** ChromeExtensionReloader plugin is a tool for hot-reloading code in a Chrome extension during development.
+ * It works by injecting a script into the extension that listens for file changes and automatically reloads the extension when a file is modified.
+ */
+
// const TypedocWebpackPlugin = require('typedoc-webpack-plugin');
-const config = {
+module.exports = {
+ mode: process.env.NODE_ENV || 'production',
// use a "multi-main entry" to inject multiple dependent files together
// and graph their dependencies into one "chunk"
entry: {
- // app: './src/app/index.js',
app: './src/app/index.tsx',
background: './src/extension/background.js',
content: './src/extension/contentScript.ts',
backend: './src/backend/index.ts',
},
+ watchOptions: {
+ aggregateTimeout: 1000,
+ ignored: /node_modules/,
+ },
output: {
path: path.resolve(__dirname, 'src/extension/build/bundles'),
filename: '[name].bundle.js',
},
- node: {
- net: 'empty',
- tls: 'empty',
- },
+ devtool: 'cheap-module-source-map',
module: {
rules: [
- {
- test: /\.jsx?/,
- exclude: /(node_modules)/,
- resolve: {
- extensions: ['.js', '.jsx'],
- },
- use: {
- loader: 'babel-loader',
- options: {
- presets: [
- ['@babel/preset-env',
- {
- useBuiltIns: 'entry',
- corejs: 3,
- debug: true,
- },
- ],
-
- '@babel/preset-react',
- {
- plugins: [
- '@babel/plugin-proposal-class-properties',
- ],
- },
- ],
- },
- },
- },
+ /**
+ * For all files ending in .ts or .tsx, except those in node_modules
+ * => transpile typescript files into javascript file.
+ */
{
test: /\.tsx?$/,
use: 'ts-loader',
@@ -59,40 +41,25 @@ const config = {
extensions: ['.tsx', '.ts', '.js'],
},
},
+ /**
+ * For all files ending in .scss or .css files
+ * Since sass-loader will only works with .scss & .sass files, for any .css file, webpack will skip sass-loader and use css-loader, then style-loader.
+ */
{
- test: /\.scss$/,
- use: ['style-loader', 'css-loader', 'sass-loader'],
- },
- {
- test: /\.css$/,
- use: ['style-loader', 'css-loader'],
+ test: /\.s?css$/,
+ use: [
+ // Creates `style` nodes from JS strings
+ 'style-loader',
+ // Translates CSS into CommonJS
+ 'css-loader',
+ // Compiles Sass to CSS
+ 'sass-loader',
+ ],
},
],
},
- plugins: [
- // new TypedocWebpackPlugin({
- // name: 'Contoso',
- // mode: 'modules',
- // theme: './typedoc-theme/',
- // includeDeclarations: false,
- // ignoreCompilerErrors: true,
- // }),
- ],
-};
-
-module.exports = (env, argv) => {
- if (argv.mode === 'development') {
- config.devtool = 'cheap-module-source-map';
- config.plugins.push(
- new ChromeExtensionReloader({
- entries: {
- contentScript: ['app', 'content'],
- background: ['background'],
- },
- }),
- );
- } else {
- config.mode = 'production';
- }
- return config;
+ // Add `.ts` and `.tsx` as a resolvable extension.
+ resolve: {
+ extensions: ['.ts', '.tsx', '.js', '.jsx'],
+ },
};
diff --git a/www/.env.example b/www/.env.example
deleted file mode 100644
index 96d67936a..000000000
--- a/www/.env.example
+++ /dev/null
@@ -1,10 +0,0 @@
-# Since .env is gitignored, you can use .env.example to build a new `.env` file when you clone the repo.
-# Keep this file up-to-date when you add new variables to `.env`.
-
-# This file will be committed to version control, so make sure not to have any secrets in it.
-# If you are cloning this repo, create a copy of this file named `.env` and populate it with your secrets.
-
-# When adding additional env variables, the schema in /env/schema.mjs should be updated accordingly
-
-# Prisma
-DATABASE_URL=file:./db.sqlite
diff --git a/www/.eslintrc.json b/www/.eslintrc.json
deleted file mode 100644
index 4cc0a95ae..000000000
--- a/www/.eslintrc.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "parser": "@typescript-eslint/parser",
- "parserOptions": {
- "project": "./tsconfig.json"
- },
- "plugins": ["@typescript-eslint"],
- "extends": ["next/core-web-vitals", "plugin:@typescript-eslint/recommended"],
- "rules": {
- "@typescript-eslint/consistent-type-imports": "warn"
- }
-}
diff --git a/www/.gitignore b/www/.gitignore
deleted file mode 100644
index 2971a0bd6..000000000
--- a/www/.gitignore
+++ /dev/null
@@ -1,42 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-
-# testing
-/coverage
-
-# database
-/prisma/db.sqlite
-/prisma/db.sqlite-journal
-
-# next.js
-/.next/
-/out/
-next-env.d.ts
-
-# production
-/build
-
-# misc
-.DS_Store
-*.pem
-
-# debug
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-.pnpm-debug.log*
-
-# local env files
-# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables
-.env
-.env*.local
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
diff --git a/www/README.md b/www/README.md
deleted file mode 100644
index cc4052672..000000000
--- a/www/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Create T3 App
-
-This is a [T3 Stack](https://create.t3.gg/) project bootstrapped with `create-t3-app`.
-
-## What's next? How do I make an app with this?
-
-We try to keep this project as simple as possible, so you can start with just the scaffolding we set up for you, and add additional things later when they become necessary.
-
-If you are not familiar with the different technologies used in this project, please refer to the respective docs. If you still are in the wind, please join our [Discord](https://t3.gg/discord) and ask for help.
-
-- [Next.js](https://nextjs.org)
-- [NextAuth.js](https://next-auth.js.org)
-- [Prisma](https://prisma.io)
-- [Tailwind CSS](https://tailwindcss.com)
-- [tRPC](https://trpc.io)
-
-## Learn More
-
-To learn more about the [T3 Stack](https://create.t3.gg/), take a look at the following resources:
-
-- [Documentation](https://create.t3.gg/)
-- [Learn the T3 Stack](https://create.t3.gg/en/faq#what-learning-resources-are-currently-available) — Check out these awesome tutorials
-
-You can check out the [create-t3-app GitHub repository](https://github.com/t3-oss/create-t3-app) — your feedback and contributions are welcome!
-
-## How do I deploy this?
-
-Follow our deployment guides for [Vercel](https://create.t3.gg/en/deployment/vercel) and [Docker](https://create.t3.gg/en/deployment/docker) for more information.
diff --git a/www/__tests__/Blogs.test.tsx b/www/__tests__/Blogs.test.tsx
deleted file mode 100644
index e35d10025..000000000
--- a/www/__tests__/Blogs.test.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import '@testing-library/jest-dom/extend-expect';
-import Blogs from '../src/pages/components/Blogs';
-import React from 'react';
-
-const posts = [
- {
- title: 'Our Legendary Article here',
- href: '#',
- category: { name: 'Greatness', href: '#' },
- description:
- 'Reactime v17, we have come a long way from beta. Now introducing full Context API support and CustomHooks support: thereby allowing developers to better visualize the states and ... ',
- date: 'Dec 14, 2022',
- datetime: '2022-12-14',
- imageUrl:
- 'https://images.unsplash.com/photo-1496128858413-b36217c2ce36?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
- readingTime: '6 min',
- author: {
- name: 'James Nghiem',
- href: '#',
- imageUrl:
- 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
- },
- },
- {
- title: 'Time-Traveling Through React State',
- href: 'https://rxlina.medium.com/time-traveling-through-react-state-with-reactime-9-0-371dbdc99319',
- category: { name: 'React', href: 'https://medium.com/tag/react' },
- description:
- 'Reactime is a Chrome extension and time-travel debugger for React that allows developers to record, track, and visualize state changes. Reactime leverages React’s core reconciliation... ',
- date: 'Oct 7, 2021',
- datetime: '2020-10-07',
- imageUrl:
- 'https://images.unsplash.com/photo-1547586696-ea22b4d4235d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
- readingTime: '4 min',
- author: {
- name: 'Lina Shin',
- href: 'https://rxlina.medium.com/',
- imageUrl:
- 'https://media-exp1.licdn.com/dms/image/C5603AQHQGFvRHt25WQ/profile-displayphoto-shrink_200_200/0/1623865299399?e=1676505600&v=beta&t=yDqgIaJOhO3oOWLROIH9rHPBHdVzDSV3VlB2axWqXr4',
- },
- },
- {
- title: 'What time is it? Reactime!',
- href: 'https://medium.com/@robbytiptontol/inter-route-time-travel-with-reactime-d84cd55ec73b',
- category: { name: 'React Devtools', href: 'https://medium.com/tag/react-devtools' },
- description: 'Reactime is a debugging tool that lets developers take snapshots of an application\’s state data as well as time-travel through these snapshots. The snapshots display React...',
- date: 'Jun 16, 2022',
- datetime: '2022-06-16',
- imageUrl:
- 'https://images.unsplash.com/photo-1492724441997-5dc865305da7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
- readingTime: '9 min',
- author: {
- name: 'Robby Tipton',
- href: 'https://medium.com/@robbytiptontol',
- imageUrl:
- 'https://miro.medium.com/fit/c/96/96/1*pi-RH2LRvsZA9vLZTvY2mg.jpeg',
- },
- },
-]
-
-describe('Blog component test ', () => {
- beforeEach(() => {
- render ( )
- })
-
- it ('the title appears on the page', () => {
- expect(screen.getByText(/From the Blog/i)).toBeInTheDocument()
- expect(screen.getByText(/See the blogs from the most recent updates and to the past years!/i)).toBeInTheDocument()
- });
-
- it ('displays the correct information for each blog post', () => {
- const blogs = screen.getAllByTestId('blog')
- blogs.forEach((blog) => {
-
-
- })
- });
-});
\ No newline at end of file
diff --git a/www/__tests__/FeaturesSection.test.tsx b/www/__tests__/FeaturesSection.test.tsx
deleted file mode 100644
index 4308cd3e6..000000000
--- a/www/__tests__/FeaturesSection.test.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import {screen, render} from '@testing-library/react';
-import '@testing-library/jest-dom/extend-expect';
-import FeaturesSection from '../src/pages/components/FeaturesSection';
-
-const features = [
- {
- name: 'State SnapShot Display',
- description: 'See your application state in a stylized and interactive format, for clear concise state management',
- },
- {
- name: 'Time Travel Rendering',
- description: 'Simulate any state change from your DOM history, with a simple click of a button',
- },
- {
- name: 'Action Comparison & Snapshot Series',
- description: 'Save a series of state snapshots and use it to analyze changes in component render performance between current and previous series of snapshots.',
- },
-]
-
-describe('FeatureSection component test ', () => {
- beforeEach(() => {
- render( )
- });
-
- it('Renders the core features section', () => {
- expect(screen.getByText(/Core Features/i)).toBeInTheDocument();
- });
-
- it('Title appears on the page', () => {
- expect(screen.getByText(/What makes Reactime so great\?/i)).toBeInTheDocument();
- });
-
- it('Subheading shows up on the page', () => {
- expect(screen.getByText(/Reactime is full of features that make your life easier as a developer. From time-travel debugging to state snapshot display, check out how using Reactime will improve your developer experience./i)).toBeInTheDocument();
- })
-
- it('Renders all feature name and descriptions', () => {
- features.forEach((feature) => {
- expect(screen.getByText(feature.name)).toBeInTheDocument();
- expect(screen.getByText(feature.description)).toBeInTheDocument();
- });
- })
-});
\ No newline at end of file
diff --git a/www/jest.config.js b/www/jest.config.js
deleted file mode 100644
index a64e7424e..000000000
--- a/www/jest.config.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/** @type {import('ts-jest').JestConfigWithTsJest} */
-module.exports = {
- preset: 'ts-jest',
- testEnvironment: 'jsdom',
- transform: {
- // '^.+\\.[tj]sx?$' to process js/ts with `ts-jest`
- // '^.+\\.m?[tj]sx?$' to process js/ts/mjs/mts with `ts-jest`
- '^.+\\.tsx?$': [
- 'ts-jest',
- {
- tsconfig: 'tsconfig.jest.json',
- },
- ],
- },
-};
\ No newline at end of file
diff --git a/www/next.config.mjs b/www/next.config.mjs
deleted file mode 100644
index 3bac3410e..000000000
--- a/www/next.config.mjs
+++ /dev/null
@@ -1,25 +0,0 @@
-// @ts-check
-/**
- * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
- * This is especially useful for Docker builds.
- */
-!process.env.SKIP_ENV_VALIDATION && (await import("./src/env/server.mjs"));
-
-/** @type {import("next").NextConfig} */
-const config = {
- reactStrictMode: true,
- swcMinify: true,
- i18n: {
- locales: ["en"],
- defaultLocale: "en",
- },
- images: {
- remotePatterns: [
- {
- protocol: 'https',
- hostname: 'github.com',
- },
- ],
- },
-};
-export default config;
diff --git a/www/package.json b/www/package.json
deleted file mode 100644
index 779ca538d..000000000
--- a/www/package.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "name": "www",
- "version": "0.1.0",
- "private": true,
- "scripts": {
- "build": "next build",
- "dev": "next dev",
- "postinstall": "prisma generate",
- "lint": "next lint",
- "start": "next start",
- "test": "jest"
- },
- "dependencies": {
- "@headlessui/react": "^1.7.5",
- "@heroicons/react": "^2.0.13",
- "@prisma/client": "^4.5.0",
- "@tanstack/react-query": "^4.16.0",
- "@trpc/client": "^10.0.0",
- "@trpc/next": "^10.0.0",
- "@trpc/react-query": "^10.0.0",
- "@trpc/server": "^10.0.0",
- "next": "13.0.2",
- "react": "18.2.0",
- "react-dom": "18.2.0",
- "superjson": "1.9.1",
- "swiper": "^8.4.5",
- "tiny-slider": "^2.9.4",
- "tiny-slider-react": "^0.5.6",
- "zod": "^3.18.0"
- },
- "devDependencies": {
- "@testing-library/jest-dom": "^5.16.5",
- "@testing-library/react": "^13.4.0",
- "@types/jest": "^29.2.5",
- "@types/node": "^18.0.0",
- "@types/react": "^18.0.14",
- "@types/react-dom": "^18.0.5",
- "@types/testing-library__react": "^10.2.0",
- "@types/tiny-slider-react": "^0.3.4",
- "@typescript-eslint/eslint-plugin": "^5.33.0",
- "@typescript-eslint/parser": "^5.33.0",
- "autoprefixer": "^10.4.7",
- "eslint": "^8.26.0",
- "eslint-config-next": "13.0.2",
- "jest": "^29.3.1",
- "jest-environment-jsdom": "^29.3.1",
- "postcss": "^8.4.14",
- "prettier": "^2.7.1",
- "prettier-plugin-tailwindcss": "^0.1.13",
- "prisma": "^4.5.0",
- "tailwindcss": "^3.2.0",
- "ts-jest": "^29.0.3",
- "typescript": "^4.9.4"
- },
- "ct3aMetadata": {
- "initVersion": "6.11.3"
- }
-}
diff --git a/www/postcss.config.cjs b/www/postcss.config.cjs
deleted file mode 100644
index 12a703d90..000000000
--- a/www/postcss.config.cjs
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-};
diff --git a/www/prettier.config.cjs b/www/prettier.config.cjs
deleted file mode 100644
index 58b0aee22..000000000
--- a/www/prettier.config.cjs
+++ /dev/null
@@ -1,4 +0,0 @@
-/** @type {import("prettier").Config} */
-module.exports = {
- plugins: [require.resolve("prettier-plugin-tailwindcss")],
-};
diff --git a/www/prisma/migrations/20221219231117_init/migration.sql b/www/prisma/migrations/20221219231117_init/migration.sql
deleted file mode 100644
index 2395d433f..000000000
--- a/www/prisma/migrations/20221219231117_init/migration.sql
+++ /dev/null
@@ -1,9 +0,0 @@
--- CreateTable
-CREATE TABLE "User" (
- "id" TEXT NOT NULL PRIMARY KEY,
- "name" TEXT NOT NULL,
- "email" TEXT NOT NULL,
- "admin" BOOLEAN NOT NULL DEFAULT false,
- "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
- "updatedAt" DATETIME NOT NULL
-);
diff --git a/www/prisma/migrations/migration_lock.toml b/www/prisma/migrations/migration_lock.toml
deleted file mode 100644
index e5e5c4705..000000000
--- a/www/prisma/migrations/migration_lock.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-# Please do not edit this file manually
-# It should be added in your version-control system (i.e. Git)
-provider = "sqlite"
\ No newline at end of file
diff --git a/www/prisma/schema.prisma b/www/prisma/schema.prisma
deleted file mode 100644
index 1b457d482..000000000
--- a/www/prisma/schema.prisma
+++ /dev/null
@@ -1,21 +0,0 @@
-// This is your Prisma schema file,
-// learn more about it in the docs: https://pris.ly/d/prisma-schema
-
-generator client {
- provider = "prisma-client-js"
-}
-
-datasource db {
- provider = "mysql"
- url = env("DATABASE_URL")
- relationMode = "prisma"
-}
-
-model User {
- id String @id @default(cuid())
- name String
- email String
- admin Boolean @default(false)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
-}
diff --git a/www/public/RTScreen.png b/www/public/RTScreen.png
deleted file mode 100644
index 1768d6194..000000000
Binary files a/www/public/RTScreen.png and /dev/null differ
diff --git a/www/public/favicon.ico b/www/public/favicon.ico
deleted file mode 100644
index efd76f16a..000000000
Binary files a/www/public/favicon.ico and /dev/null differ
diff --git a/www/public/profileFallback.png b/www/public/profileFallback.png
deleted file mode 100644
index cfbdfcd02..000000000
Binary files a/www/public/profileFallback.png and /dev/null differ
diff --git a/www/src/env/client.mjs b/www/src/env/client.mjs
deleted file mode 100644
index 30958cb8e..000000000
--- a/www/src/env/client.mjs
+++ /dev/null
@@ -1,35 +0,0 @@
-// @ts-check
-import { clientEnv, clientSchema } from "./schema.mjs";
-
-const _clientEnv = clientSchema.safeParse(clientEnv);
-
-export const formatErrors = (
- /** @type {import('zod').ZodFormattedError,string>} */
- errors,
-) =>
- Object.entries(errors)
- .map(([name, value]) => {
- if (value && "_errors" in value)
- return `${name}: ${value._errors.join(", ")}\n`;
- })
- .filter(Boolean);
-
-if (!_clientEnv.success) {
- console.error(
- "❌ Invalid environment variables:\n",
- ...formatErrors(_clientEnv.error.format()),
- );
- throw new Error("Invalid environment variables");
-}
-
-for (let key of Object.keys(_clientEnv.data)) {
- if (!key.startsWith("NEXT_PUBLIC_")) {
- console.warn(
- `❌ Invalid public environment variable name: ${key}. It must begin with 'NEXT_PUBLIC_'`,
- );
-
- throw new Error("Invalid public environment variable name");
- }
-}
-
-export const env = _clientEnv.data;
diff --git a/www/src/env/schema.mjs b/www/src/env/schema.mjs
deleted file mode 100644
index 45d39359e..000000000
--- a/www/src/env/schema.mjs
+++ /dev/null
@@ -1,30 +0,0 @@
-// @ts-check
-import { z } from "zod";
-
-/**
- * Specify your server-side environment variables schema here.
- * This way you can ensure the app isn't built with invalid env vars.
- */
-export const serverSchema = z.object({
- DATABASE_URL: z.string().url(),
- NODE_ENV: z.enum(["development", "test", "production"]),
-});
-
-/**
- * Specify your client-side environment variables schema here.
- * This way you can ensure the app isn't built with invalid env vars.
- * To expose them to the client, prefix them with `NEXT_PUBLIC_`.
- */
-export const clientSchema = z.object({
- // NEXT_PUBLIC_CLIENTVAR: z.string(),
-});
-
-/**
- * You can't destruct `process.env` as a regular object, so you have to do
- * it manually here. This is because Next.js evaluates this at build time,
- * and only used environment variables are included in the build.
- * @type {{ [k in keyof z.infer]: z.infer[k] | undefined }}
- */
-export const clientEnv = {
- // NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR,
-};
diff --git a/www/src/env/server.mjs b/www/src/env/server.mjs
deleted file mode 100644
index 736e3a6bf..000000000
--- a/www/src/env/server.mjs
+++ /dev/null
@@ -1,27 +0,0 @@
-// @ts-check
-/**
- * This file is included in `/next.config.mjs` which ensures the app isn't built with invalid env vars.
- * It has to be a `.mjs`-file to be imported there.
- */
-import { serverSchema } from "./schema.mjs";
-import { env as clientEnv, formatErrors } from "./client.mjs";
-
-const _serverEnv = serverSchema.safeParse(process.env);
-
-if (!_serverEnv.success) {
- console.error(
- "❌ Invalid environment variables:\n",
- ...formatErrors(_serverEnv.error.format()),
- );
- throw new Error("Invalid environment variables");
-}
-
-for (let key of Object.keys(_serverEnv.data)) {
- if (key.startsWith("NEXT_PUBLIC_")) {
- console.warn("❌ You are exposing a server-side env-variable:", key);
-
- throw new Error("You are exposing a server-side env-variable");
- }
-}
-
-export const env = { ..._serverEnv.data, ...clientEnv };
diff --git a/www/src/pages/_app.tsx b/www/src/pages/_app.tsx
deleted file mode 100644
index 9ff6e366b..000000000
--- a/www/src/pages/_app.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { type AppType } from "next/app";
-
-import { trpc } from "../utils/trpc";
-
-import "../styles/globals.css";
-
-const MyApp: AppType = ({ Component, pageProps }) => {
-
- return ;
-};
-
-export default trpc.withTRPC(MyApp);
diff --git a/www/src/pages/api/examples.ts b/www/src/pages/api/examples.ts
deleted file mode 100644
index c0889f553..000000000
--- a/www/src/pages/api/examples.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { type NextApiRequest, type NextApiResponse } from "next";
-
-import { prisma } from "../../server/db/client";
-
-const examples = async (req: NextApiRequest, res: NextApiResponse) => {
- const examples = await prisma.example.findMany();
- res.status(200).json(examples);
-};
-
-export default examples;
diff --git a/www/src/pages/api/trpc/[trpc].ts b/www/src/pages/api/trpc/[trpc].ts
deleted file mode 100644
index f69201d3e..000000000
--- a/www/src/pages/api/trpc/[trpc].ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { createNextApiHandler } from "@trpc/server/adapters/next";
-
-import { env } from "../../../env/server.mjs";
-import { createContext } from "../../../server/trpc/context";
-import { appRouter } from "../../../server/trpc/router/_app";
-
-// export API handler
-export default createNextApiHandler({
- router: appRouter,
- createContext,
- onError:
- env.NODE_ENV === "development"
- ? ({ path, error }) => {
- console.error(`❌ tRPC failed on ${path}: ${error}`);
- }
- : undefined,
-});
diff --git a/www/src/pages/components/Blogs.tsx b/www/src/pages/components/Blogs.tsx
deleted file mode 100644
index 01c38844a..000000000
--- a/www/src/pages/components/Blogs.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-const posts = [
- {
- title: 'Our Legendary Article here',
- href: '#',
- category: { name: 'Greatness', href: '#' },
- description:
- 'Reactime v17, we have come a long way from beta. Now introducing full Context API support and CustomHooks support: thereby allowing developers to better visualize the states and ... ',
- date: 'Dec 14, 2022',
- datetime: '2022-12-14',
- imageUrl:
- 'https://images.unsplash.com/photo-1496128858413-b36217c2ce36?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
- readingTime: '6 min',
- author: {
- name: 'James Nghiem',
- href: '#',
- imageUrl:
- 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
- },
- },
- {
- title: 'Time-Traveling Through React State',
- href: 'https://rxlina.medium.com/time-traveling-through-react-state-with-reactime-9-0-371dbdc99319',
- category: { name: 'React', href: 'https://medium.com/tag/react' },
- description:
- 'Reactime is a Chrome extension and time-travel debugger for React that allows developers to record, track, and visualize state changes. Reactime leverages React’s core reconciliation... ',
- date: 'Oct 7, 2021',
- datetime: '2020-10-07',
- imageUrl:
- 'https://images.unsplash.com/photo-1547586696-ea22b4d4235d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
- readingTime: '4 min',
- author: {
- name: 'Lina Shin',
- href: 'https://rxlina.medium.com/',
- imageUrl:
- 'https://media-exp1.licdn.com/dms/image/C5603AQHQGFvRHt25WQ/profile-displayphoto-shrink_200_200/0/1623865299399?e=1676505600&v=beta&t=yDqgIaJOhO3oOWLROIH9rHPBHdVzDSV3VlB2axWqXr4',
- },
- },
- {
- title: 'What time is it? Reactime!',
- href: 'https://medium.com/@robbytiptontol/inter-route-time-travel-with-reactime-d84cd55ec73b',
- category: { name: 'React Devtools', href: 'https://medium.com/tag/react-devtools' },
- description: 'Reactime is a debugging tool that lets developers take snapshots of an application\’s state data as well as time-travel through these snapshots. The snapshots display React...',
- date: 'Jun 16, 2022',
- datetime: '2022-06-16',
- imageUrl:
- 'https://images.unsplash.com/photo-1492724441997-5dc865305da7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1679&q=80',
- readingTime: '9 min',
- author: {
- name: 'Robby Tipton',
- href: 'https://medium.com/@robbytiptontol',
- imageUrl:
- 'https://miro.medium.com/fit/c/96/96/1*pi-RH2LRvsZA9vLZTvY2mg.jpeg',
- },
- },
-]
-
-export default function Blogs() {
- return (
-
-
-
-
-
From the Blog
-
- See the blogs from the most recent updates and to the past years!
-
-
-
- {posts.map((post) => (
-
-
-
-
-
-
- ))}
-
-
-
- )
-}
\ No newline at end of file
diff --git a/www/src/pages/components/FeaturesSection.tsx b/www/src/pages/components/FeaturesSection.tsx
deleted file mode 100644
index a34dc1766..000000000
--- a/www/src/pages/components/FeaturesSection.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import {
- ArrowPathIcon,
- CloudArrowUpIcon,
- CogIcon,
- ArrowDownTrayIcon,
- ServerIcon,
- ClockIcon,
- CameraIcon,
- PresentationChartLineIcon,
- MapIcon,
-} from '@heroicons/react/24/outline'
-
-const features = [
- {
- name: 'State SnapShot Display',
- description: 'See your application state in a stylized and interactive format, for clear concise state management',
- icon: CameraIcon,
- },
- {
- name: 'Time Travel Rendering',
- description: 'Simulate any state change from your DOM history, with a simple click of a button',
- icon: ClockIcon,
- },
- {
- name: 'Action Comparison & Snapshot Series',
- description: 'Save a series of state snapshots and use it to analyze changes in component render performance between current and previous series of snapshots.',
- icon: ArrowPathIcon,
- },
- {
- name: 'Components Performance Display',
- description: 'Visualize the relative latency trends introduced by re-rendering each component on state change',
- icon: PresentationChartLineIcon,
- },
- {
- name: 'Download, Upload, and Persist',
- description: 'Save your state history for future tests. Keep your state changes on app reload',
- icon: ArrowDownTrayIcon,
- },
- {
- name: 'Atom and Selector Relationships',
- description: 'Visualize the mapping of Atoms and Selectors to components in Recoil Apps',
- icon: MapIcon,
- },
-]
-
-export default function FeaturesSection() {
- return (
-
-
-
Core Features
-
- What makes Reactime so great?
-
-
- Reactime is full of features that make your life easier as a developer. From time-travel debugging to state snapshot display, check out how using Reactime will improve your developer experience.
-
-
-
- {features.map((feature) => (
-
-
-
-
-
-
-
-
-
- {feature.name}
-
-
{feature.description}
-
-
-
- ))}
-
-
-
-
- )
-}
diff --git a/www/src/pages/components/LandingPage.tsx b/www/src/pages/components/LandingPage.tsx
deleted file mode 100644
index 0e596af09..000000000
--- a/www/src/pages/components/LandingPage.tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import { ChevronRightIcon, StarIcon } from '@heroicons/react/20/solid';
-import { string } from 'prop-types';
-import TeamSection from '../components/TeamSection';
-import FeaturesSection from '../components/FeaturesSection';
-import Image from 'next/image';
-import Blogs from './Blogs';
-import { useState } from 'react';
-import { trpc } from '../../utils/trpc';
-
-export default function LandingPage() {
- const [name, setName] = useState('');
- const [email, setEmail] = useState('');
- const { mutate } = trpc.user.createUser.useMutation();
-
- const handleSubmit = (e: React.MouseEvent) => {
- e.preventDefault();
- // grab the information of name and email
- // bundle those together to be an object to be sent to backend
- mutate({name, email});
- setName('');
- setEmail('');
- }
-
- return (
- <>
-
-
- {/* Hero section */}
-
-
-
-
-
-
-
-
-
-
- A time travel debugger for modern react apps
-
-
- A Chrome Extension that lets you rewind time and replay previous versions of your stateful React components.
-
-
-
-
-
- Name
-
- {setName(e.target.value)}}
- />
-
- Email address
-
- {setEmail(e.target.value)}}
- />
-
-
- handleSubmit(e)}
- >
- Notify me
-
-
-
-
-
-
- {/* */}
-
-
-
- Starred on GitHub by over{' '}
- 1,700 users
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* Footer section */}
-
-
- >
- )
-}
diff --git a/www/src/pages/components/NavBar.tsx b/www/src/pages/components/NavBar.tsx
deleted file mode 100644
index 377d0efaa..000000000
--- a/www/src/pages/components/NavBar.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-import { Fragment, useEffect, useState } from 'react'
-import { Disclosure, Menu, Transition } from '@headlessui/react'
-import { Bars3Icon, BellIcon, XMarkIcon } from '@heroicons/react/24/outline'
-
-function classNames(...classes: string[]) {
- return classes.filter(Boolean).join(' ')
-}
-
-
-
-export default function NavBar() {
-
-const [scrollPosition, setScrollPosition] = useState(0);
-
-const handleScroll = () => {
- const position = window.pageYOffset;
- setScrollPosition(position);
-};
-
-useEffect(() => {
- window.addEventListener('scroll', handleScroll, { passive: true });
-
- return () => {
- window.removeEventListener('scroll', handleScroll);
- };
-}, []);
-
-function NavBarSytle() {
- return scrollPosition === 0 ? "sticky top-0 bg-gray-50 w-screen z-20 border-b" : "sticky top-0 bg-gray-50 w-screen z-20 shadow-xl";
-}
- return (
-
- {({ open }) => (
- <>
-
-
-
-
-
-
-
-
Reactime
-
- v17.0.0
-
-
-
-
-
-
-
-
-
-
- {/* Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" */}
-
- Team
-
-
- Team
-
-
- Projects
-
-
- Calendar
-
-
-
- >
- )}
-
- )
-}
-
-import React from 'react';
\ No newline at end of file
diff --git a/www/src/pages/components/TeamSection.tsx b/www/src/pages/components/TeamSection.tsx
deleted file mode 100644
index c0cdb9e0d..000000000
--- a/www/src/pages/components/TeamSection.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-import Image from 'next/image'
-import { useState } from 'react';
-
-const people: string[][] = [
- ["Alex Gomez", "alexgomez9"],
- ["Alexander Landeros", "AlexanderLanderos"],
- ["Ali Rahman", "CourageWolf"],
- ["Andy Tsou", "andytsou19"],
- ["Andy Wong", "andywongdev"],
- ["Becca Viner", "rtviner"],
- ["Ben Margolius", "benmarg"],
- ["Ben Michareune", "bmichare"],
- ["Brian Yang", "yangbrian310"],
- ["Bryan Lee", "mylee1995"],
- ["Caitlin Chan", "caitlinchan23"],
- ["Caner Demir", "demircaner"],
- ["Carlos Perez", "crperezt"],
- ["Chris Flannery", "chriswillsflannery"],
- ["Chris Guizzetti", "guizzettic"],
- ["Chris LeBrett", "fscgolden"],
- ["Christina Or", "christinaor"],
- ["Cole Styr", "c-styr"],
- ["Daljit Gill", "dgill05"],
- ["Dane Corpion", "danecorpion"],
- ["David Bernstein", "dangitbobbeh"],
- ["David Chai", "davidchai717"],
- ["David Kim", "codejunkie7"],
- ["Dennis Lopez", "DennisLpz"],
- ["Edar Liu", "liuedar"],
- ["Edwin Menendez", "edwinjmenendez"],
- ["Emin Tahirov", "eminthrv"],
- ["Ergi Shehu", "Ergi516"],
- ["Eric Yun", "ericsngyun"],
- ["Feiyi Wu", "FreyaWu"],
- ["Gabriela Aquino", "aquinojardim"],
- ["Greg Panciera", "gpanciera"],
- ["Haejin Jo", "haejinjo"],
- ["Harry Fox", "StackOverFlowWhereArtThou"],
- ["Hien Nguyen", "hienqn"],
- ["Jack Crish", "JackC27"],
- ["James Nghiem", "jemzir"],
- ["Jason Victor", "Theqwertypusher"],
- ["Joshua Howard", "Joshua-Howard"],
- ["Joseph Park", "joeepark"],
- ["Joseph Stern", "josephiswhere"],
- ["Josh Kim", "joshua0308"],
- ["Kevin Fey", "kevinfey"],
- ["Kevin HoEun Lee", "khobread"],
- ["Kevin Ngo", "kevin-ngo"],
- ["Khanh Bui", "AndyB909"],
- ["Kim Mai Nguyen", "Nkmai"],
- ["Kris Sorensen", "kris-sorensen"],
- ["Kristina Wallen", "kristinawallen"],
- ["Lina Shin", "rxlina"],
- ["Louis Lam", "llam722"],
- ["Nate Wa Mwenze", "nmwenz90"],
- ["Nathan Richardson", "BagelEnthusiast"],
- ["Ozair Ghulam", "OzairGh"],
- ["Peng Dong", "d28601581"],
- ["Prasanna Malla", "prasmalla"],
- ["Quan Le", "blachfog"],
- ["Rajeeb Banstola", "rajeebthegreat"],
- ["Raymond Kwan", "rkwn"],
- ["Robby Tipton", "RobbyTipton"],
- ["Robert Maeda", "robmaeda"],
- ["Rocky Lin", "rocky9413"],
- ["Ruth Anam", "peachiecodes"],
- ["Ryan Dang", "rydang"],
- ["Samuel Tran", "LeumasTr"],
- ["Sanjay Lavingia", "sanjaylavingia"],
- ["Sierra Swaby", "starkspark"],
- ["Tania Lind", "lind-tania"],
- ["Viet Nguyen", "vnguyen95"],
- ["Vincent Nguyen", "VNguyenCode"],
- ["Wilton Lee", "wiltonlee948"],
- ["Yujin Kang", " yujinkay"],
-]
-
-function replace(e: React.SyntheticEvent): void{
- console.log('test');
- e.currentTarget.onerror = null;
- e.currentTarget.src = "/profileFallback.png"
-}
-
- export default function People(): JSX.Element {
- return (
-
-
-
-
-
Our Contributors
-
- All of the people who make Reactime awesome!
-
-
-
- <>
- {people.map((person)=>(
-
- ))}
- >
-
-
-
-
- )
- }
- type profileType = {
- profile: string | undefined,
- name: string | undefined,
- }
- function Profile({profile, name}: profileType) {
- const [imageError, setImageError] = useState(false);
- return (
-
-
setImageError(true)}
- alt="missing-profile-image"
- />
-
-
- )
-}
-
-
-
diff --git a/www/src/pages/index.tsx b/www/src/pages/index.tsx
deleted file mode 100644
index 152a3581e..000000000
--- a/www/src/pages/index.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { type NextPage } from "next";
-import Head from "next/head";
-import Link from "next/link";
-import LandingPage from "./components/LandingPage";
-import NavBar from "./components/NavBar";
-import Blogs from "./components/Blogs";
-import { trpc } from "../utils/trpc";
-
-const Home: NextPage = () => {
- return (
- <>
-
-
- >
- );
-};
-
-export default Home;
diff --git a/www/src/pages/secret.tsx b/www/src/pages/secret.tsx
deleted file mode 100644
index c4c1a3091..000000000
--- a/www/src/pages/secret.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * create an input box
- * create a password andusername checker --
- * if correct send them the shit
- */
-
-import { type NextPage } from "next";
-import { useState } from "react";
-import Head from "next/head";
-import Link from "next/link";
-import LandingPage from "./components/LandingPage";
-import NavBar from "./components/NavBar";
-import Blogs from "./components/Blogs";
-import { trpc } from "../utils/trpc";
-
-const secret: NextPage = () => {
- const [isAdmin, setIsAdmin] = useState(false);
- const [password, setPassword] = useState("");
-
- const clickHandler = () => {
- if (process.env.NEXT_PUBLIC_ADMIN_PASSWORD === password) {
- setIsAdmin(true);
- }
- };
-
- const { data:users } = trpc.user.findAll.useQuery();
-
- return (
- <>
- {!isAdmin &&
- setPassword(e.target.value)}
- required
- placeholder="password"
- className="block w-50 rounded-md border border-gray-300 px-5 py-3 text-base text-gray-900 placeholder-gray-500 shadow-sm focus:border-rose-500 focus:ring-rose-500 mr-8">
-
- Submit
-
}
- {isAdmin && {users?.map(user => {user.email}, )}
}
-
- >
- );
-};
-
-export default secret;
diff --git a/www/src/server/db/client.ts b/www/src/server/db/client.ts
deleted file mode 100644
index 0c3d23437..000000000
--- a/www/src/server/db/client.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { PrismaClient } from "@prisma/client";
-
-import { env } from "../../env/server.mjs";
-
-declare global {
- // eslint-disable-next-line no-var
- var prisma: PrismaClient | undefined;
-}
-
-export const prisma =
- global.prisma ||
- new PrismaClient({
- log:
- env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
- });
-
-if (env.NODE_ENV !== "production") {
- global.prisma = prisma;
-}
diff --git a/www/src/server/trpc/context.ts b/www/src/server/trpc/context.ts
deleted file mode 100644
index 873dc9d9a..000000000
--- a/www/src/server/trpc/context.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { type inferAsyncReturnType } from "@trpc/server";
-import { type CreateNextContextOptions } from "@trpc/server/adapters/next";
-
-import { prisma } from "../db/client";
-
-/**
- * Replace this with an object if you want to pass things to createContextInner
- */
-type CreateContextOptions = Record;
-
-/** Use this helper for:
- * - testing, so we dont have to mock Next.js' req/res
- * - trpc's `createSSGHelpers` where we don't have req/res
- * @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts
- **/
-export const createContextInner = async (opts: CreateContextOptions) => {
- return {
- prisma,
- };
-};
-
-/**
- * This is the actual context you'll use in your router
- * @link https://trpc.io/docs/context
- **/
-export const createContext = async (opts: CreateNextContextOptions) => {
- return await createContextInner({});
-};
-
-export type Context = inferAsyncReturnType;
diff --git a/www/src/server/trpc/router/_app.ts b/www/src/server/trpc/router/_app.ts
deleted file mode 100644
index 5ea8f0e33..000000000
--- a/www/src/server/trpc/router/_app.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { router } from "../trpc";
-import { userRouter } from "./user";
-
-export const appRouter = router({
- user : userRouter,
-});
-
-// export type definition of API
-export type AppRouter = typeof appRouter;
diff --git a/www/src/server/trpc/router/user.ts b/www/src/server/trpc/router/user.ts
deleted file mode 100644
index d10c64382..000000000
--- a/www/src/server/trpc/router/user.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { z } from "zod";
-
-import { router, publicProcedure } from "../trpc";
-
-export const userRouter = router({
- createUser: publicProcedure
- .input(z.object({
- name: z.string(),
- email: z.string().email()}),
-
- ) // name and email
- .mutation(async ({ input, ctx }) => {
- // we want to add to our database with the name, email, admin defaulted to false as column values
- return await ctx.prisma.user.create({
- data: {
- name: input.name,
- email: input.email,
- }
- })
- }),
- findAll: publicProcedure
- .query(async ({ctx}) => {
- return await ctx.prisma.user.findMany();
- })
-});
-
-
-//const greeting = trpc.userRouter.hello({text: ""});
-
-/**
- * hello -- name of endpoint api
- * .input will be what we are going to be expecting
- * .query/.mutation will be what is going to happen once we go to this endpoint api
- * (differentiation is that query and mutation should be adjusted for read and CUD functionality)
- */
\ No newline at end of file
diff --git a/www/src/server/trpc/trpc.ts b/www/src/server/trpc/trpc.ts
deleted file mode 100644
index b4a952758..000000000
--- a/www/src/server/trpc/trpc.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { initTRPC } from "@trpc/server";
-import superjson from "superjson";
-
-import { type Context } from "./context";
-
-const t = initTRPC.context().create({
- transformer: superjson,
- errorFormatter({ shape }) {
- return shape;
- },
-});
-
-export const router = t.router;
-
-export const publicProcedure = t.procedure;
diff --git a/www/src/styles/globals.css b/www/src/styles/globals.css
deleted file mode 100644
index 91a933f99..000000000
--- a/www/src/styles/globals.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-body {
- background-color: rgba(249, 250, 251);
-}
\ No newline at end of file
diff --git a/www/src/utils/trpc.ts b/www/src/utils/trpc.ts
deleted file mode 100644
index 2391cbc3b..000000000
--- a/www/src/utils/trpc.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { httpBatchLink, loggerLink } from "@trpc/client";
-import { createTRPCNext } from "@trpc/next";
-import { type inferRouterInputs, type inferRouterOutputs } from "@trpc/server";
-import superjson from "superjson";
-
-import { type AppRouter } from "../server/trpc/router/_app";
-
-const getBaseUrl = () => {
- if (typeof window !== "undefined") return ""; // browser should use relative url
- if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; // SSR should use vercel url
- return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost
-};
-
-export const trpc = createTRPCNext({
- config() {
- return {
- transformer: superjson,
- links: [
- loggerLink({
- enabled: (opts) =>
- process.env.NODE_ENV === "development" ||
- (opts.direction === "down" && opts.result instanceof Error),
- }),
- httpBatchLink({
- url: `${getBaseUrl()}/api/trpc`,
- }),
- ],
- };
- },
- ssr: false,
-});
-
-/**
- * Inference helper for inputs
- * @example type HelloInput = RouterInputs['example']['hello']
- **/
-export type RouterInputs = inferRouterInputs;
-/**
- * Inference helper for outputs
- * @example type HelloOutput = RouterOutputs['example']['hello']
- **/
-export type RouterOutputs = inferRouterOutputs;
diff --git a/www/tailwind.config.cjs b/www/tailwind.config.cjs
deleted file mode 100644
index 54331dc99..000000000
--- a/www/tailwind.config.cjs
+++ /dev/null
@@ -1,8 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- content: ["./src/**/*.{js,ts,jsx,tsx}"],
- theme: {
- extend: {},
- },
- plugins: [],
-};
diff --git a/www/tsconfig.jest.json b/www/tsconfig.jest.json
deleted file mode 100644
index d8fbaefd2..000000000
--- a/www/tsconfig.jest.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "jsx": "react-jsx"
- }
-}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
deleted file mode 100644
index 0159a8a9d..000000000
--- a/yarn.lock
+++ /dev/null
@@ -1,11105 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13":
- "integrity" "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g=="
- "resolved" "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/highlight" "^7.12.13"
-
-"@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.12", "@babel/compat-data@^7.13.8":
- "integrity" "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ=="
- "resolved" "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz"
- "version" "7.13.12"
-
-"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.12.7", "@babel/core@^7.13.0", "@babel/core@^7.4.0-0", "@babel/core@^7.7.5":
- "integrity" "sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw=="
- "resolved" "https://registry.npmjs.org/@babel/core/-/core-7.13.10.tgz"
- "version" "7.13.10"
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@babel/generator" "^7.13.9"
- "@babel/helper-compilation-targets" "^7.13.10"
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helpers" "^7.13.10"
- "@babel/parser" "^7.13.10"
- "@babel/template" "^7.12.13"
- "@babel/traverse" "^7.13.0"
- "@babel/types" "^7.13.0"
- "convert-source-map" "^1.7.0"
- "debug" "^4.1.0"
- "gensync" "^1.0.0-beta.2"
- "json5" "^2.1.2"
- "lodash" "^4.17.19"
- "semver" "^6.3.0"
- "source-map" "^0.5.0"
-
-"@babel/generator@^7.13.0", "@babel/generator@^7.13.9":
- "integrity" "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw=="
- "resolved" "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz"
- "version" "7.13.9"
- dependencies:
- "@babel/types" "^7.13.0"
- "jsesc" "^2.5.1"
- "source-map" "^0.5.0"
-
-"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13":
- "integrity" "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw=="
- "resolved" "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/types" "^7.12.13"
-
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13":
- "integrity" "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-explode-assignable-expression" "^7.12.13"
- "@babel/types" "^7.12.13"
-
-"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.13.8":
- "integrity" "sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz"
- "version" "7.13.10"
- dependencies:
- "@babel/compat-data" "^7.13.8"
- "@babel/helper-validator-option" "^7.12.17"
- "browserslist" "^4.14.5"
- "semver" "^6.3.0"
-
-"@babel/helper-create-class-features-plugin@^7.13.0":
- "integrity" "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw=="
- "resolved" "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz"
- "version" "7.13.11"
- dependencies:
- "@babel/helper-function-name" "^7.12.13"
- "@babel/helper-member-expression-to-functions" "^7.13.0"
- "@babel/helper-optimise-call-expression" "^7.12.13"
- "@babel/helper-replace-supers" "^7.13.0"
- "@babel/helper-split-export-declaration" "^7.12.13"
-
-"@babel/helper-create-regexp-features-plugin@^7.12.13":
- "integrity" "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg=="
- "resolved" "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz"
- "version" "7.12.17"
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.12.13"
- "regexpu-core" "^4.7.1"
-
-"@babel/helper-define-map@^7.12.13":
- "integrity" "sha512-r9/bcpR9n3FHH4Iq9Pz96mvnBbV4D8aDYUW5HjkR8eaQhJmsGshRh1bfOalGKofWOB/3KVFtmLf0iJi7/6Lgfg=="
- "resolved" "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/helper-function-name" "^7.12.13"
- "@babel/types" "^7.13.12"
-
-"@babel/helper-define-polyfill-provider@^0.1.5":
- "integrity" "sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg=="
- "resolved" "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz"
- "version" "0.1.5"
- dependencies:
- "@babel/helper-compilation-targets" "^7.13.0"
- "@babel/helper-module-imports" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/traverse" "^7.13.0"
- "debug" "^4.1.1"
- "lodash.debounce" "^4.0.8"
- "resolve" "^1.14.2"
- "semver" "^6.1.2"
-
-"@babel/helper-explode-assignable-expression@^7.12.13":
- "integrity" "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/types" "^7.13.0"
-
-"@babel/helper-function-name@^7.12.13":
- "integrity" "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-get-function-arity" "^7.12.13"
- "@babel/template" "^7.12.13"
- "@babel/types" "^7.12.13"
-
-"@babel/helper-get-function-arity@^7.12.13":
- "integrity" "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg=="
- "resolved" "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/types" "^7.12.13"
-
-"@babel/helper-hoist-variables@^7.13.0":
- "integrity" "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g=="
- "resolved" "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/traverse" "^7.13.0"
- "@babel/types" "^7.13.0"
-
-"@babel/helper-member-expression-to-functions@^7.13.0", "@babel/helper-member-expression-to-functions@^7.13.12":
- "integrity" "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw=="
- "resolved" "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/types" "^7.13.12"
-
-"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12":
- "integrity" "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/types" "^7.13.12"
-
-"@babel/helper-module-transforms@^7.13.0":
- "integrity" "sha512-7zVQqMO3V+K4JOOj40kxiCrMf6xlQAkewBB0eu2b03OO/Q21ZutOzjpfD79A5gtE/2OWi1nv625MrDlGlkbknQ=="
- "resolved" "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/helper-module-imports" "^7.13.12"
- "@babel/helper-replace-supers" "^7.13.12"
- "@babel/helper-simple-access" "^7.13.12"
- "@babel/helper-split-export-declaration" "^7.12.13"
- "@babel/helper-validator-identifier" "^7.12.11"
- "@babel/template" "^7.12.13"
- "@babel/traverse" "^7.13.0"
- "@babel/types" "^7.13.12"
-
-"@babel/helper-optimise-call-expression@^7.12.13":
- "integrity" "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/types" "^7.12.13"
-
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
- "integrity" "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz"
- "version" "7.17.12"
-
-"@babel/helper-remap-async-to-generator@^7.13.0":
- "integrity" "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg=="
- "resolved" "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.12.13"
- "@babel/helper-wrap-function" "^7.13.0"
- "@babel/types" "^7.13.0"
-
-"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12":
- "integrity" "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw=="
- "resolved" "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/helper-member-expression-to-functions" "^7.13.12"
- "@babel/helper-optimise-call-expression" "^7.12.13"
- "@babel/traverse" "^7.13.0"
- "@babel/types" "^7.13.12"
-
-"@babel/helper-simple-access@^7.12.13", "@babel/helper-simple-access@^7.13.12":
- "integrity" "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/types" "^7.13.12"
-
-"@babel/helper-skip-transparent-expression-wrappers@^7.12.1":
- "integrity" "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz"
- "version" "7.12.1"
- dependencies:
- "@babel/types" "^7.12.1"
-
-"@babel/helper-split-export-declaration@^7.12.13":
- "integrity" "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg=="
- "resolved" "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/types" "^7.12.13"
-
-"@babel/helper-validator-identifier@^7.12.11":
- "integrity" "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
- "resolved" "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz"
- "version" "7.12.11"
-
-"@babel/helper-validator-option@^7.12.17":
- "integrity" "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw=="
- "resolved" "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz"
- "version" "7.12.17"
-
-"@babel/helper-wrap-function@^7.13.0":
- "integrity" "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA=="
- "resolved" "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-function-name" "^7.12.13"
- "@babel/template" "^7.12.13"
- "@babel/traverse" "^7.13.0"
- "@babel/types" "^7.13.0"
-
-"@babel/helpers@^7.13.10":
- "integrity" "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ=="
- "resolved" "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz"
- "version" "7.13.10"
- dependencies:
- "@babel/template" "^7.12.13"
- "@babel/traverse" "^7.13.0"
- "@babel/types" "^7.13.0"
-
-"@babel/highlight@^7.12.13":
- "integrity" "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg=="
- "resolved" "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz"
- "version" "7.13.10"
- dependencies:
- "@babel/helper-validator-identifier" "^7.12.11"
- "chalk" "^2.0.0"
- "js-tokens" "^4.0.0"
-
-"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.13.0", "@babel/parser@^7.13.10", "@babel/parser@^7.14.7":
- "integrity" "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow=="
- "resolved" "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz"
- "version" "7.18.4"
-
-"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12":
- "integrity" "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
- "@babel/plugin-proposal-optional-chaining" "^7.13.12"
-
-"@babel/plugin-proposal-async-generator-functions@^7.13.8":
- "integrity" "sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-remap-async-to-generator" "^7.13.0"
- "@babel/plugin-syntax-async-generators" "^7.8.4"
-
-"@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.13.0":
- "integrity" "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-create-class-features-plugin" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-proposal-decorators@^7.10.5":
- "integrity" "sha512-i0GDfVNuoapwiheevUOuSW67mInqJ8qw7uWfpjNVeHMn143kXblEy/bmL9AdZ/0yf/4BMQeWXezK0tQIvNPqag=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.13.5.tgz"
- "version" "7.13.5"
- dependencies:
- "@babel/helper-create-class-features-plugin" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-decorators" "^7.12.13"
-
-"@babel/plugin-proposal-dynamic-import@^7.13.8":
- "integrity" "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-dynamic-import" "^7.8.3"
-
-"@babel/plugin-proposal-export-namespace-from@^7.12.13":
- "integrity" "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
- "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
-
-"@babel/plugin-proposal-json-strings@^7.13.8":
- "integrity" "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-json-strings" "^7.8.3"
-
-"@babel/plugin-proposal-logical-assignment-operators@^7.13.8":
- "integrity" "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
-
-"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3":
- "integrity" "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
-
-"@babel/plugin-proposal-numeric-separator@^7.12.13", "@babel/plugin-proposal-numeric-separator@^7.8.3":
- "integrity" "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
- "@babel/plugin-syntax-numeric-separator" "^7.10.4"
-
-"@babel/plugin-proposal-object-rest-spread@^7.13.8", "@babel/plugin-proposal-object-rest-spread@^7.9.0":
- "integrity" "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/compat-data" "^7.13.8"
- "@babel/helper-compilation-targets" "^7.13.8"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
- "@babel/plugin-transform-parameters" "^7.13.0"
-
-"@babel/plugin-proposal-optional-catch-binding@^7.13.8", "@babel/plugin-proposal-optional-catch-binding@^7.8.3":
- "integrity" "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
-
-"@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.9.0":
- "integrity" "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
- "@babel/plugin-syntax-optional-chaining" "^7.8.3"
-
-"@babel/plugin-proposal-private-methods@^7.13.0":
- "integrity" "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-create-class-features-plugin" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
- "integrity" "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-syntax-async-generators@^7.8.4":
- "integrity" "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz"
- "version" "7.8.4"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-bigint@^7.8.3":
- "integrity" "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz"
- "version" "7.8.3"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3":
- "integrity" "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-syntax-decorators@^7.12.13":
- "integrity" "sha512-Rw6aIXGuqDLr6/LoBBYE57nKOzQpz/aDkKlMqEwH+Vp0MXbG6H/TfRjaY343LKxzAKAMXIHsQ8JzaZKuDZ9MwA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-syntax-dynamic-import@^7.8.3":
- "integrity" "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz"
- "version" "7.8.3"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-export-namespace-from@^7.8.3":
- "integrity" "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz"
- "version" "7.8.3"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
-
-"@babel/plugin-syntax-import-meta@^7.8.3":
- "integrity" "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz"
- "version" "7.10.4"
- dependencies:
- "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-syntax-json-strings@^7.8.3":
- "integrity" "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz"
- "version" "7.8.3"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-jsx@^7.12.13":
- "integrity" "sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3":
- "integrity" "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz"
- "version" "7.10.4"
- dependencies:
- "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3":
- "integrity" "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz"
- "version" "7.8.3"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3":
- "integrity" "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz"
- "version" "7.10.4"
- dependencies:
- "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-syntax-object-rest-spread@^7.8.3":
- "integrity" "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz"
- "version" "7.8.3"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-optional-catch-binding@^7.8.3":
- "integrity" "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz"
- "version" "7.8.3"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-optional-chaining@^7.8.3":
- "integrity" "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz"
- "version" "7.8.3"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-top-level-await@^7.12.13", "@babel/plugin-syntax-top-level-await@^7.8.3":
- "integrity" "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-arrow-functions@^7.13.0":
- "integrity" "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-async-to-generator@^7.13.0":
- "integrity" "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-module-imports" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-remap-async-to-generator" "^7.13.0"
-
-"@babel/plugin-transform-block-scoped-functions@^7.12.13":
- "integrity" "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-block-scoping@^7.12.13":
- "integrity" "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-classes@^7.13.0", "@babel/plugin-transform-classes@^7.9.2":
- "integrity" "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.12.13"
- "@babel/helper-function-name" "^7.12.13"
- "@babel/helper-optimise-call-expression" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-replace-supers" "^7.13.0"
- "@babel/helper-split-export-declaration" "^7.12.13"
- "globals" "^11.1.0"
-
-"@babel/plugin-transform-computed-properties@^7.13.0":
- "integrity" "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-destructuring@^7.13.0":
- "integrity" "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4":
- "integrity" "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-duplicate-keys@^7.12.13":
- "integrity" "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-exponentiation-operator@^7.12.13", "@babel/plugin-transform-exponentiation-operator@^7.8.3":
- "integrity" "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-for-of@^7.13.0":
- "integrity" "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-function-name@^7.12.13":
- "integrity" "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-function-name" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-literals@^7.12.13":
- "integrity" "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-member-expression-literals@^7.12.13", "@babel/plugin-transform-member-expression-literals@^7.8.3":
- "integrity" "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-modules-amd@^7.13.0":
- "integrity" "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
- "babel-plugin-dynamic-import-node" "^2.3.3"
-
-"@babel/plugin-transform-modules-commonjs@^7.13.8":
- "integrity" "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-simple-access" "^7.12.13"
- "babel-plugin-dynamic-import-node" "^2.3.3"
-
-"@babel/plugin-transform-modules-systemjs@^7.13.8":
- "integrity" "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz"
- "version" "7.13.8"
- dependencies:
- "@babel/helper-hoist-variables" "^7.13.0"
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-validator-identifier" "^7.12.11"
- "babel-plugin-dynamic-import-node" "^2.3.3"
-
-"@babel/plugin-transform-modules-umd@^7.13.0":
- "integrity" "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13":
- "integrity" "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.12.13"
-
-"@babel/plugin-transform-new-target@^7.12.13":
- "integrity" "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-object-super@^7.12.13":
- "integrity" "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
- "@babel/helper-replace-supers" "^7.12.13"
-
-"@babel/plugin-transform-parameters@^7.13.0":
- "integrity" "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-property-literals@^7.12.13", "@babel/plugin-transform-property-literals@^7.8.3":
- "integrity" "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-property-mutators@^7.8.3":
- "integrity" "sha512-e6zKU7ojSHSdeMRl9BUOcADH0S+A4uCjZY4hGWF/1wGn8cYTQvlGF9xm03QzWF4UfWyQTqPdBWVxOKECdBZIjQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-property-mutators/-/plugin-transform-property-mutators-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-define-map" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-react-display-name@^7.12.13":
- "integrity" "sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-react-jsx-development@^7.12.12":
- "integrity" "sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz"
- "version" "7.12.17"
- dependencies:
- "@babel/plugin-transform-react-jsx" "^7.12.17"
-
-"@babel/plugin-transform-react-jsx@^7.12.13", "@babel/plugin-transform-react-jsx@^7.12.17":
- "integrity" "sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.12.13"
- "@babel/helper-module-imports" "^7.13.12"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-jsx" "^7.12.13"
- "@babel/types" "^7.13.12"
-
-"@babel/plugin-transform-react-pure-annotations@^7.12.1":
- "integrity" "sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz"
- "version" "7.12.1"
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.10.4"
- "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-transform-regenerator@^7.12.13":
- "integrity" "sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "regenerator-transform" "^0.14.2"
-
-"@babel/plugin-transform-reserved-words@^7.12.13":
- "integrity" "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-runtime@^7.9.0":
- "integrity" "sha512-Y5k8ipgfvz5d/76tx7JYbKQTcgFSU6VgJ3kKQv4zGTKr+a9T/KBvfRvGtSFgKDQGt/DBykQixV0vNWKIdzWErA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.10.tgz"
- "version" "7.13.10"
- dependencies:
- "@babel/helper-module-imports" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.13.0"
- "babel-plugin-polyfill-corejs2" "^0.1.4"
- "babel-plugin-polyfill-corejs3" "^0.1.3"
- "babel-plugin-polyfill-regenerator" "^0.1.2"
- "semver" "^6.3.0"
-
-"@babel/plugin-transform-shorthand-properties@^7.12.13":
- "integrity" "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-spread@^7.13.0":
- "integrity" "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
-
-"@babel/plugin-transform-sticky-regex@^7.12.13":
- "integrity" "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-template-literals@^7.13.0", "@babel/plugin-transform-template-literals@^7.8.3":
- "integrity" "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-typeof-symbol@^7.12.13":
- "integrity" "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-unicode-escapes@^7.12.13":
- "integrity" "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-unicode-regex@^7.12.13":
- "integrity" "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA=="
- "resolved" "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/preset-env@^7.12.7", "@babel/preset-env@^7.9.0":
- "integrity" "sha512-JzElc6jk3Ko6zuZgBtjOd01pf9yYDEIH8BcqVuYIuOkzOwDesoa/Nz4gIo4lBG6K861KTV9TvIgmFuT6ytOaAA=="
- "resolved" "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/compat-data" "^7.13.12"
- "@babel/helper-compilation-targets" "^7.13.10"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-validator-option" "^7.12.17"
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12"
- "@babel/plugin-proposal-async-generator-functions" "^7.13.8"
- "@babel/plugin-proposal-class-properties" "^7.13.0"
- "@babel/plugin-proposal-dynamic-import" "^7.13.8"
- "@babel/plugin-proposal-export-namespace-from" "^7.12.13"
- "@babel/plugin-proposal-json-strings" "^7.13.8"
- "@babel/plugin-proposal-logical-assignment-operators" "^7.13.8"
- "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8"
- "@babel/plugin-proposal-numeric-separator" "^7.12.13"
- "@babel/plugin-proposal-object-rest-spread" "^7.13.8"
- "@babel/plugin-proposal-optional-catch-binding" "^7.13.8"
- "@babel/plugin-proposal-optional-chaining" "^7.13.12"
- "@babel/plugin-proposal-private-methods" "^7.13.0"
- "@babel/plugin-proposal-unicode-property-regex" "^7.12.13"
- "@babel/plugin-syntax-async-generators" "^7.8.4"
- "@babel/plugin-syntax-class-properties" "^7.12.13"
- "@babel/plugin-syntax-dynamic-import" "^7.8.3"
- "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
- "@babel/plugin-syntax-json-strings" "^7.8.3"
- "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
- "@babel/plugin-syntax-numeric-separator" "^7.10.4"
- "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
- "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
- "@babel/plugin-syntax-optional-chaining" "^7.8.3"
- "@babel/plugin-syntax-top-level-await" "^7.12.13"
- "@babel/plugin-transform-arrow-functions" "^7.13.0"
- "@babel/plugin-transform-async-to-generator" "^7.13.0"
- "@babel/plugin-transform-block-scoped-functions" "^7.12.13"
- "@babel/plugin-transform-block-scoping" "^7.12.13"
- "@babel/plugin-transform-classes" "^7.13.0"
- "@babel/plugin-transform-computed-properties" "^7.13.0"
- "@babel/plugin-transform-destructuring" "^7.13.0"
- "@babel/plugin-transform-dotall-regex" "^7.12.13"
- "@babel/plugin-transform-duplicate-keys" "^7.12.13"
- "@babel/plugin-transform-exponentiation-operator" "^7.12.13"
- "@babel/plugin-transform-for-of" "^7.13.0"
- "@babel/plugin-transform-function-name" "^7.12.13"
- "@babel/plugin-transform-literals" "^7.12.13"
- "@babel/plugin-transform-member-expression-literals" "^7.12.13"
- "@babel/plugin-transform-modules-amd" "^7.13.0"
- "@babel/plugin-transform-modules-commonjs" "^7.13.8"
- "@babel/plugin-transform-modules-systemjs" "^7.13.8"
- "@babel/plugin-transform-modules-umd" "^7.13.0"
- "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13"
- "@babel/plugin-transform-new-target" "^7.12.13"
- "@babel/plugin-transform-object-super" "^7.12.13"
- "@babel/plugin-transform-parameters" "^7.13.0"
- "@babel/plugin-transform-property-literals" "^7.12.13"
- "@babel/plugin-transform-regenerator" "^7.12.13"
- "@babel/plugin-transform-reserved-words" "^7.12.13"
- "@babel/plugin-transform-shorthand-properties" "^7.12.13"
- "@babel/plugin-transform-spread" "^7.13.0"
- "@babel/plugin-transform-sticky-regex" "^7.12.13"
- "@babel/plugin-transform-template-literals" "^7.13.0"
- "@babel/plugin-transform-typeof-symbol" "^7.12.13"
- "@babel/plugin-transform-unicode-escapes" "^7.12.13"
- "@babel/plugin-transform-unicode-regex" "^7.12.13"
- "@babel/preset-modules" "^0.1.4"
- "@babel/types" "^7.13.12"
- "babel-plugin-polyfill-corejs2" "^0.1.4"
- "babel-plugin-polyfill-corejs3" "^0.1.3"
- "babel-plugin-polyfill-regenerator" "^0.1.2"
- "core-js-compat" "^3.9.0"
- "semver" "^6.3.0"
-
-"@babel/preset-modules@^0.1.4":
- "integrity" "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg=="
- "resolved" "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz"
- "version" "0.1.4"
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
- "@babel/plugin-transform-dotall-regex" "^7.4.4"
- "@babel/types" "^7.4.4"
- "esutils" "^2.0.2"
-
-"@babel/preset-react@^7.12.7", "@babel/preset-react@^7.9.4":
- "integrity" "sha512-TYM0V9z6Abb6dj1K7i5NrEhA13oS5ujUYQYDfqIBXYHOc2c2VkFgc+q9kyssIyUfy4/hEwqrgSlJ/Qgv8zJLsA=="
- "resolved" "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
- "@babel/plugin-transform-react-display-name" "^7.12.13"
- "@babel/plugin-transform-react-jsx" "^7.12.13"
- "@babel/plugin-transform-react-jsx-development" "^7.12.12"
- "@babel/plugin-transform-react-pure-annotations" "^7.12.1"
-
-"@babel/runtime-corejs3@^7.10.2":
- "integrity" "sha512-RMafpmrNB5E/bwdSphLr8a8++9TosnyJp98RZzI6VOx2R2CCMpsXXXRvmI700O9oEKpXdZat6oEK68/F0zjd4A=="
- "resolved" "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.5.tgz"
- "version" "7.10.5"
- dependencies:
- "core-js-pure" "^3.0.0"
- "regenerator-runtime" "^0.13.4"
-
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
- "integrity" "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA=="
- "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz"
- "version" "7.19.4"
- dependencies:
- "regenerator-runtime" "^0.13.4"
-
-"@babel/template@^7.12.13", "@babel/template@^7.3.3":
- "integrity" "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA=="
- "resolved" "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz"
- "version" "7.12.13"
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@babel/parser" "^7.12.13"
- "@babel/types" "^7.12.13"
-
-"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0":
- "integrity" "sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ=="
- "resolved" "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.0.tgz"
- "version" "7.13.0"
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@babel/generator" "^7.13.0"
- "@babel/helper-function-name" "^7.12.13"
- "@babel/helper-split-export-declaration" "^7.12.13"
- "@babel/parser" "^7.13.0"
- "@babel/types" "^7.13.0"
- "debug" "^4.1.0"
- "globals" "^11.1.0"
- "lodash" "^4.17.19"
-
-"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
- "integrity" "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA=="
- "resolved" "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz"
- "version" "7.13.12"
- dependencies:
- "@babel/helper-validator-identifier" "^7.12.11"
- "lodash" "^4.17.19"
- "to-fast-properties" "^2.0.0"
-
-"@bcoe/v8-coverage@^0.2.3":
- "integrity" "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="
- "resolved" "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz"
- "version" "0.2.3"
-
-"@cnakazawa/watch@^1.0.3":
- "integrity" "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ=="
- "resolved" "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "exec-sh" "^0.3.2"
- "minimist" "^1.2.0"
-
-"@emotion/babel-plugin@^11.7.1", "@emotion/babel-plugin@^11.7.2":
- "integrity" "sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ=="
- "resolved" "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz"
- "version" "11.7.2"
- dependencies:
- "@babel/helper-module-imports" "^7.12.13"
- "@babel/plugin-syntax-jsx" "^7.12.13"
- "@babel/runtime" "^7.13.10"
- "@emotion/hash" "^0.8.0"
- "@emotion/memoize" "^0.7.5"
- "@emotion/serialize" "^1.0.2"
- "babel-plugin-macros" "^2.6.1"
- "convert-source-map" "^1.5.0"
- "escape-string-regexp" "^4.0.0"
- "find-root" "^1.1.0"
- "source-map" "^0.5.7"
- "stylis" "4.0.13"
-
-"@emotion/cache@^10.0.27":
- "integrity" "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ=="
- "resolved" "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz"
- "version" "10.0.29"
- dependencies:
- "@emotion/sheet" "0.9.4"
- "@emotion/stylis" "0.8.5"
- "@emotion/utils" "0.11.3"
- "@emotion/weak-memoize" "0.2.5"
-
-"@emotion/cache@^10.0.9":
- "integrity" "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ=="
- "resolved" "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz"
- "version" "10.0.29"
- dependencies:
- "@emotion/sheet" "0.9.4"
- "@emotion/stylis" "0.8.5"
- "@emotion/utils" "0.11.3"
- "@emotion/weak-memoize" "0.2.5"
-
-"@emotion/cache@^11.7.1", "@emotion/cache@^11.9.3":
- "integrity" "sha512-0dgkI/JKlCXa+lEXviaMtGBL0ynpx4osh7rjOXE71q9bIF8G+XhJgvi+wDu0B0IdCVx37BffiwXlN9I3UuzFvg=="
- "resolved" "https://registry.npmjs.org/@emotion/cache/-/cache-11.9.3.tgz"
- "version" "11.9.3"
- dependencies:
- "@emotion/memoize" "^0.7.4"
- "@emotion/sheet" "^1.1.1"
- "@emotion/utils" "^1.0.0"
- "@emotion/weak-memoize" "^0.2.5"
- "stylis" "4.0.13"
-
-"@emotion/core@^10.0.9":
- "integrity" "sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA=="
- "resolved" "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz"
- "version" "10.0.28"
- dependencies:
- "@babel/runtime" "^7.5.5"
- "@emotion/cache" "^10.0.27"
- "@emotion/css" "^10.0.27"
- "@emotion/serialize" "^0.11.15"
- "@emotion/sheet" "0.9.4"
- "@emotion/utils" "0.11.3"
-
-"@emotion/css@^10.0.27", "@emotion/css@^10.0.9":
- "integrity" "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw=="
- "resolved" "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz"
- "version" "10.0.27"
- dependencies:
- "@emotion/serialize" "^0.11.15"
- "@emotion/utils" "0.11.3"
- "babel-plugin-emotion" "^10.0.27"
-
-"@emotion/hash@^0.8.0", "@emotion/hash@0.8.0":
- "integrity" "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
- "resolved" "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz"
- "version" "0.8.0"
-
-"@emotion/is-prop-valid@^1.1.2", "@emotion/is-prop-valid@^1.1.3":
- "integrity" "sha512-RFg04p6C+1uO19uG8N+vqanzKqiM9eeV1LDOG3bmkYmuOj7NbKNlFC/4EZq5gnwAIlcC/jOT24f8Td0iax2SXA=="
- "resolved" "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.3.tgz"
- "version" "1.1.3"
- dependencies:
- "@emotion/memoize" "^0.7.4"
-
-"@emotion/memoize@^0.7.4", "@emotion/memoize@^0.7.5":
- "integrity" "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ=="
- "resolved" "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz"
- "version" "0.7.5"
-
-"@emotion/memoize@0.7.4":
- "integrity" "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
- "resolved" "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz"
- "version" "0.7.4"
-
-"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.1.4", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0", "@emotion/react@^11.9.0":
- "integrity" "sha512-g9Q1GcTOlzOEjqwuLF/Zd9LC+4FljjPjDfxSM7KmEakm+hsHXk+bYZ2q+/hTJzr0OUNkujo72pXLQvXj6H+GJQ=="
- "resolved" "https://registry.npmjs.org/@emotion/react/-/react-11.9.3.tgz"
- "version" "11.9.3"
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@emotion/babel-plugin" "^11.7.1"
- "@emotion/cache" "^11.9.3"
- "@emotion/serialize" "^1.0.4"
- "@emotion/utils" "^1.1.0"
- "@emotion/weak-memoize" "^0.2.5"
- "hoist-non-react-statics" "^3.3.1"
-
-"@emotion/serialize@^0.11.15":
- "integrity" "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg=="
- "resolved" "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz"
- "version" "0.11.16"
- dependencies:
- "@emotion/hash" "0.8.0"
- "@emotion/memoize" "0.7.4"
- "@emotion/unitless" "0.7.5"
- "@emotion/utils" "0.11.3"
- "csstype" "^2.5.7"
-
-"@emotion/serialize@^0.11.16":
- "integrity" "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg=="
- "resolved" "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz"
- "version" "0.11.16"
- dependencies:
- "@emotion/hash" "0.8.0"
- "@emotion/memoize" "0.7.4"
- "@emotion/unitless" "0.7.5"
- "@emotion/utils" "0.11.3"
- "csstype" "^2.5.7"
-
-"@emotion/serialize@^1.0.2", "@emotion/serialize@^1.0.4":
- "integrity" "sha512-1JHamSpH8PIfFwAMryO2bNka+y8+KA5yga5Ocf2d7ZEiJjb7xlLW7aknBGZqJLajuLOvJ+72vN+IBSwPlXD1Pg=="
- "resolved" "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "@emotion/hash" "^0.8.0"
- "@emotion/memoize" "^0.7.4"
- "@emotion/unitless" "^0.7.5"
- "@emotion/utils" "^1.0.0"
- "csstype" "^3.0.2"
-
-"@emotion/sheet@^1.1.1":
- "integrity" "sha512-J3YPccVRMiTZxYAY0IOq3kd+hUP8idY8Kz6B/Cyo+JuXq52Ek+zbPbSQUrVQp95aJ+lsAW7DPL1P2Z+U1jGkKA=="
- "resolved" "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.1.tgz"
- "version" "1.1.1"
-
-"@emotion/sheet@0.9.4":
- "integrity" "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA=="
- "resolved" "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz"
- "version" "0.9.4"
-
-"@emotion/styled@^11.3.0", "@emotion/styled@^11.8.1":
- "integrity" "sha512-o3sBNwbtoVz9v7WB1/Y/AmXl69YHmei2mrVnK7JgyBJ//Rst5yqPZCecEJlMlJrFeWHp+ki/54uN265V2pEcXA=="
- "resolved" "https://registry.npmjs.org/@emotion/styled/-/styled-11.9.3.tgz"
- "version" "11.9.3"
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@emotion/babel-plugin" "^11.7.1"
- "@emotion/is-prop-valid" "^1.1.3"
- "@emotion/serialize" "^1.0.4"
- "@emotion/utils" "^1.1.0"
-
-"@emotion/stylis@0.8.5":
- "integrity" "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
- "resolved" "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz"
- "version" "0.8.5"
-
-"@emotion/unitless@^0.7.5", "@emotion/unitless@0.7.5":
- "integrity" "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
- "resolved" "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz"
- "version" "0.7.5"
-
-"@emotion/utils@^1.0.0", "@emotion/utils@^1.1.0":
- "integrity" "sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ=="
- "resolved" "https://registry.npmjs.org/@emotion/utils/-/utils-1.1.0.tgz"
- "version" "1.1.0"
-
-"@emotion/utils@0.11.3":
- "integrity" "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw=="
- "resolved" "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz"
- "version" "0.11.3"
-
-"@emotion/weak-memoize@^0.2.5", "@emotion/weak-memoize@0.2.5":
- "integrity" "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA=="
- "resolved" "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz"
- "version" "0.2.5"
-
-"@fortawesome/fontawesome-common-types@^0.2.35":
- "integrity" "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw=="
- "resolved" "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz"
- "version" "0.2.35"
-
-"@fortawesome/fontawesome-free@^5.15.1":
- "integrity" "sha512-rFnSUN/QOtnOAgqFRooTA3H57JLDm0QEG/jPdk+tLQNL/eWd+Aok8g3qCI+Q1xuDPWpGW/i9JySpJVsq8Q0s9w=="
- "resolved" "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.3.tgz"
- "version" "5.15.3"
-
-"@fortawesome/fontawesome-svg-core@^1.2.32":
- "integrity" "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg=="
- "resolved" "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz"
- "version" "1.2.35"
- dependencies:
- "@fortawesome/fontawesome-common-types" "^0.2.35"
-
-"@fortawesome/free-regular-svg-icons@^5.15.1":
- "integrity" "sha512-q4/p8Xehy9qiVTdDWHL4Z+o5PCLRChePGZRTXkl+/Z7erDVL8VcZUuqzJjs6gUz6czss4VIPBRdCz6wP37/zMQ=="
- "resolved" "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.15.3.tgz"
- "version" "5.15.3"
- dependencies:
- "@fortawesome/fontawesome-common-types" "^0.2.35"
-
-"@fortawesome/free-solid-svg-icons@^5.15.1":
- "integrity" "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q=="
- "resolved" "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz"
- "version" "5.15.3"
- dependencies:
- "@fortawesome/fontawesome-common-types" "^0.2.35"
-
-"@fortawesome/react-fontawesome@^0.1.12":
- "integrity" "sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA=="
- "resolved" "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz"
- "version" "0.1.14"
- dependencies:
- "prop-types" "^15.7.2"
-
-"@istanbuljs/load-nyc-config@^1.0.0":
- "integrity" "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ=="
- "resolved" "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz"
- "version" "1.1.0"
- dependencies:
- "camelcase" "^5.3.1"
- "find-up" "^4.1.0"
- "get-package-type" "^0.1.0"
- "js-yaml" "^3.13.1"
- "resolve-from" "^5.0.0"
-
-"@istanbuljs/schema@^0.1.2":
- "integrity" "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw=="
- "resolved" "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz"
- "version" "0.1.2"
-
-"@jest/console@^26.6.2":
- "integrity" "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g=="
- "resolved" "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "chalk" "^4.0.0"
- "jest-message-util" "^26.6.2"
- "jest-util" "^26.6.2"
- "slash" "^3.0.0"
-
-"@jest/core@^26.6.3":
- "integrity" "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw=="
- "resolved" "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@jest/console" "^26.6.2"
- "@jest/reporters" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/transform" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "ansi-escapes" "^4.2.1"
- "chalk" "^4.0.0"
- "exit" "^0.1.2"
- "graceful-fs" "^4.2.4"
- "jest-changed-files" "^26.6.2"
- "jest-config" "^26.6.3"
- "jest-haste-map" "^26.6.2"
- "jest-message-util" "^26.6.2"
- "jest-regex-util" "^26.0.0"
- "jest-resolve" "^26.6.2"
- "jest-resolve-dependencies" "^26.6.3"
- "jest-runner" "^26.6.3"
- "jest-runtime" "^26.6.3"
- "jest-snapshot" "^26.6.2"
- "jest-util" "^26.6.2"
- "jest-validate" "^26.6.2"
- "jest-watcher" "^26.6.2"
- "micromatch" "^4.0.2"
- "p-each-series" "^2.1.0"
- "rimraf" "^3.0.0"
- "slash" "^3.0.0"
- "strip-ansi" "^6.0.0"
-
-"@jest/environment@^26.6.2":
- "integrity" "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA=="
- "resolved" "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/fake-timers" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "jest-mock" "^26.6.2"
-
-"@jest/fake-timers@^26.6.2":
- "integrity" "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA=="
- "resolved" "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "@sinonjs/fake-timers" "^6.0.1"
- "@types/node" "*"
- "jest-message-util" "^26.6.2"
- "jest-mock" "^26.6.2"
- "jest-util" "^26.6.2"
-
-"@jest/globals@^26.6.2":
- "integrity" "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA=="
- "resolved" "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/environment" "^26.6.2"
- "@jest/types" "^26.6.2"
- "expect" "^26.6.2"
-
-"@jest/reporters@^26.6.2":
- "integrity" "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw=="
- "resolved" "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@bcoe/v8-coverage" "^0.2.3"
- "@jest/console" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/transform" "^26.6.2"
- "@jest/types" "^26.6.2"
- "chalk" "^4.0.0"
- "collect-v8-coverage" "^1.0.0"
- "exit" "^0.1.2"
- "glob" "^7.1.2"
- "graceful-fs" "^4.2.4"
- "istanbul-lib-coverage" "^3.0.0"
- "istanbul-lib-instrument" "^4.0.3"
- "istanbul-lib-report" "^3.0.0"
- "istanbul-lib-source-maps" "^4.0.0"
- "istanbul-reports" "^3.0.2"
- "jest-haste-map" "^26.6.2"
- "jest-resolve" "^26.6.2"
- "jest-util" "^26.6.2"
- "jest-worker" "^26.6.2"
- "slash" "^3.0.0"
- "source-map" "^0.6.0"
- "string-length" "^4.0.1"
- "terminal-link" "^2.0.0"
- "v8-to-istanbul" "^7.0.0"
- optionalDependencies:
- "node-notifier" "^8.0.0"
-
-"@jest/source-map@^26.6.2":
- "integrity" "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA=="
- "resolved" "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "callsites" "^3.0.0"
- "graceful-fs" "^4.2.4"
- "source-map" "^0.6.0"
-
-"@jest/test-result@^26.6.2":
- "integrity" "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ=="
- "resolved" "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/console" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/istanbul-lib-coverage" "^2.0.0"
- "collect-v8-coverage" "^1.0.0"
-
-"@jest/test-sequencer@^26.6.3":
- "integrity" "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw=="
- "resolved" "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@jest/test-result" "^26.6.2"
- "graceful-fs" "^4.2.4"
- "jest-haste-map" "^26.6.2"
- "jest-runner" "^26.6.3"
- "jest-runtime" "^26.6.3"
-
-"@jest/transform@^26.6.2":
- "integrity" "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA=="
- "resolved" "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@babel/core" "^7.1.0"
- "@jest/types" "^26.6.2"
- "babel-plugin-istanbul" "^6.0.0"
- "chalk" "^4.0.0"
- "convert-source-map" "^1.4.0"
- "fast-json-stable-stringify" "^2.0.0"
- "graceful-fs" "^4.2.4"
- "jest-haste-map" "^26.6.2"
- "jest-regex-util" "^26.0.0"
- "jest-util" "^26.6.2"
- "micromatch" "^4.0.2"
- "pirates" "^4.0.1"
- "slash" "^3.0.0"
- "source-map" "^0.6.1"
- "write-file-atomic" "^3.0.0"
-
-"@jest/types@^24.9.0":
- "integrity" "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw=="
- "resolved" "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz"
- "version" "24.9.0"
- dependencies:
- "@types/istanbul-lib-coverage" "^2.0.0"
- "@types/istanbul-reports" "^1.1.1"
- "@types/yargs" "^13.0.0"
-
-"@jest/types@^25.5.0":
- "integrity" "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw=="
- "resolved" "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz"
- "version" "25.5.0"
- dependencies:
- "@types/istanbul-lib-coverage" "^2.0.0"
- "@types/istanbul-reports" "^1.1.1"
- "@types/yargs" "^15.0.0"
- "chalk" "^3.0.0"
-
-"@jest/types@^26.6.2":
- "integrity" "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ=="
- "resolved" "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@types/istanbul-lib-coverage" "^2.0.0"
- "@types/istanbul-reports" "^3.0.0"
- "@types/node" "*"
- "@types/yargs" "^15.0.0"
- "chalk" "^4.0.0"
-
-"@material-ui/core@^4.11.2":
- "integrity" "sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw=="
- "resolved" "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz"
- "version" "4.11.3"
- dependencies:
- "@babel/runtime" "^7.4.4"
- "@material-ui/styles" "^4.11.3"
- "@material-ui/system" "^4.11.3"
- "@material-ui/types" "^5.1.0"
- "@material-ui/utils" "^4.11.2"
- "@types/react-transition-group" "^4.2.0"
- "clsx" "^1.0.4"
- "hoist-non-react-statics" "^3.3.2"
- "popper.js" "1.16.1-lts"
- "prop-types" "^15.7.2"
- "react-is" "^16.8.0 || ^17.0.0"
- "react-transition-group" "^4.4.0"
-
-"@material-ui/styles@^4.11.3":
- "integrity" "sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg=="
- "resolved" "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz"
- "version" "4.11.3"
- dependencies:
- "@babel/runtime" "^7.4.4"
- "@emotion/hash" "^0.8.0"
- "@material-ui/types" "^5.1.0"
- "@material-ui/utils" "^4.11.2"
- "clsx" "^1.0.4"
- "csstype" "^2.5.2"
- "hoist-non-react-statics" "^3.3.2"
- "jss" "^10.5.1"
- "jss-plugin-camel-case" "^10.5.1"
- "jss-plugin-default-unit" "^10.5.1"
- "jss-plugin-global" "^10.5.1"
- "jss-plugin-nested" "^10.5.1"
- "jss-plugin-props-sort" "^10.5.1"
- "jss-plugin-rule-value-function" "^10.5.1"
- "jss-plugin-vendor-prefixer" "^10.5.1"
- "prop-types" "^15.7.2"
-
-"@material-ui/system@^4.11.3":
- "integrity" "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw=="
- "resolved" "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz"
- "version" "4.11.3"
- dependencies:
- "@babel/runtime" "^7.4.4"
- "@material-ui/utils" "^4.11.2"
- "csstype" "^2.5.2"
- "prop-types" "^15.7.2"
-
-"@material-ui/types@^5.1.0":
- "integrity" "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A=="
- "resolved" "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz"
- "version" "5.1.0"
-
-"@material-ui/utils@^4.11.2":
- "integrity" "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA=="
- "resolved" "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz"
- "version" "4.11.2"
- dependencies:
- "@babel/runtime" "^7.4.4"
- "prop-types" "^15.7.2"
- "react-is" "^16.8.0 || ^17.0.0"
-
-"@mui/base@5.0.0-alpha.86":
- "integrity" "sha512-0vi/Nni1mizrgrzKeyksEjw5JVSrgT8Vr2NhxzFtYxqpMgtdSrBvcmcuzBf9kE/ECMPbgpSIcqv0nLbLZUYkOQ=="
- "resolved" "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.86.tgz"
- "version" "5.0.0-alpha.86"
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@emotion/is-prop-valid" "^1.1.2"
- "@mui/types" "^7.1.4"
- "@mui/utils" "^5.8.4"
- "@popperjs/core" "^2.11.5"
- "clsx" "^1.1.1"
- "prop-types" "^15.8.1"
- "react-is" "^17.0.2"
-
-"@mui/material@^5.8.2":
- "integrity" "sha512-wngPXlOI9BurLSGlObQM/2L0QFFaIcvJnDK5A+ALxuUyuQnPviVWfC1l/r8rPlxQ4PCbSYpq3gzLlgnLoWcO/g=="
- "resolved" "https://registry.npmjs.org/@mui/material/-/material-5.8.5.tgz"
- "version" "5.8.5"
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@mui/base" "5.0.0-alpha.86"
- "@mui/system" "^5.8.5"
- "@mui/types" "^7.1.4"
- "@mui/utils" "^5.8.4"
- "@types/react-transition-group" "^4.4.4"
- "clsx" "^1.1.1"
- "csstype" "^3.1.0"
- "prop-types" "^15.8.1"
- "react-is" "^17.0.2"
- "react-transition-group" "^4.4.2"
-
-"@mui/private-theming@^5.8.4":
- "integrity" "sha512-3Lp0VAEjtQygJ70MWEyHkKvg327O6YoBH6ZNEy6fIsrK6gmRIj+YrlvJ7LQCbowY+qDGnbdMrTBd1hfThlI8lg=="
- "resolved" "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.8.4.tgz"
- "version" "5.8.4"
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@mui/utils" "^5.8.4"
- "prop-types" "^15.8.1"
-
-"@mui/styled-engine@^5.8.0":
- "integrity" "sha512-Q3spibB8/EgeMYHc+/o3RRTnAYkSl7ROCLhXJ830W8HZ2/iDiyYp16UcxKPurkXvLhUaILyofPVrP3Su2uKsAw=="
- "resolved" "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.8.0.tgz"
- "version" "5.8.0"
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@emotion/cache" "^11.7.1"
- "prop-types" "^15.8.1"
-
-"@mui/system@^5.8.5":
- "integrity" "sha512-1bhITHp5sX/CVEf1QwtBWvW+kNnH+GU7lKz0CeAL1RyH9dWvoL9Yt/+i/L8hJ6jVZB/7Au2F6MsyDPt8V1jfdA=="
- "resolved" "https://registry.npmjs.org/@mui/system/-/system-5.8.5.tgz"
- "version" "5.8.5"
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@mui/private-theming" "^5.8.4"
- "@mui/styled-engine" "^5.8.0"
- "@mui/types" "^7.1.4"
- "@mui/utils" "^5.8.4"
- "clsx" "^1.1.1"
- "csstype" "^3.1.0"
- "prop-types" "^15.8.1"
-
-"@mui/types@^7.1.4":
- "integrity" "sha512-uveM3byMbthO+6tXZ1n2zm0W3uJCQYtwt/v5zV5I77v2v18u0ITkb8xwhsDD2i3V2Kye7SaNR6FFJ6lMuY/WqQ=="
- "resolved" "https://registry.npmjs.org/@mui/types/-/types-7.1.4.tgz"
- "version" "7.1.4"
-
-"@mui/utils@^5.8.4":
- "integrity" "sha512-BHYErfrjqqh76KaDAm8wZlhEip1Uj7Cmco65NcsF3BWrAl3FWngACpaPZeEbTgmaEwyWAQEE6LZhsmy43hfyqQ=="
- "resolved" "https://registry.npmjs.org/@mui/utils/-/utils-5.8.4.tgz"
- "version" "5.8.4"
- dependencies:
- "@babel/runtime" "^7.17.2"
- "@types/prop-types" "^15.7.5"
- "@types/react-is" "^16.7.1 || ^17.0.0"
- "prop-types" "^15.8.1"
- "react-is" "^17.0.2"
-
-"@popperjs/core@^2.11.5":
- "integrity" "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw=="
- "resolved" "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz"
- "version" "2.11.5"
-
-"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.7.0":
- "integrity" "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q=="
- "resolved" "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz"
- "version" "1.8.0"
- dependencies:
- "type-detect" "4.0.8"
-
-"@sinonjs/fake-timers@^6.0.1":
- "integrity" "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA=="
- "resolved" "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz"
- "version" "6.0.1"
- dependencies:
- "@sinonjs/commons" "^1.7.0"
-
-"@sinonjs/formatio@^3.2.1":
- "integrity" "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ=="
- "resolved" "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz"
- "version" "3.2.2"
- dependencies:
- "@sinonjs/commons" "^1"
- "@sinonjs/samsam" "^3.1.0"
-
-"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.3":
- "integrity" "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ=="
- "resolved" "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz"
- "version" "3.3.3"
- dependencies:
- "@sinonjs/commons" "^1.3.0"
- "array-from" "^2.1.1"
- "lodash" "^4.17.15"
-
-"@sinonjs/text-encoding@^0.7.1":
- "integrity" "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ=="
- "resolved" "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz"
- "version" "0.7.1"
-
-"@testing-library/dom@^8.5.0":
- "integrity" "sha512-P6iIPyYQ+qH8CvGauAqanhVnjrnRe0IZFSYCeGkSRW9q3u8bdVn2NPI+lasFyVsEQn1J/IFmp5Aax41+dAP9wg=="
- "resolved" "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.1.tgz"
- "version" "8.19.1"
- dependencies:
- "@babel/code-frame" "^7.10.4"
- "@babel/runtime" "^7.12.5"
- "@types/aria-query" "^5.0.1"
- "aria-query" "^5.0.0"
- "chalk" "^4.1.0"
- "dom-accessibility-api" "^0.5.9"
- "lz-string" "^1.4.4"
- "pretty-format" "^27.0.2"
-
-"@testing-library/jest-dom@^4.2.4":
- "integrity" "sha512-j31Bn0rQo12fhCWOUWy9fl7wtqkp7In/YP2p5ZFyRuiiB9Qs3g+hS4gAmDWONbAHcRmVooNJ5eOHQDCOmUFXHg=="
- "resolved" "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-4.2.4.tgz"
- "version" "4.2.4"
- dependencies:
- "@babel/runtime" "^7.5.1"
- "chalk" "^2.4.1"
- "css" "^2.2.3"
- "css.escape" "^1.5.1"
- "jest-diff" "^24.0.0"
- "jest-matcher-utils" "^24.0.0"
- "lodash" "^4.17.11"
- "pretty-format" "^24.0.0"
- "redent" "^3.0.0"
-
-"@testing-library/react@^13.4.0":
- "integrity" "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw=="
- "resolved" "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz"
- "version" "13.4.0"
- dependencies:
- "@babel/runtime" "^7.12.5"
- "@testing-library/dom" "^8.5.0"
- "@types/react-dom" "^18.0.0"
-
-"@tootallnate/once@1":
- "integrity" "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="
- "resolved" "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz"
- "version" "1.1.2"
-
-"@types/aria-query@^5.0.1":
- "integrity" "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q=="
- "resolved" "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz"
- "version" "5.0.1"
-
-"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
- "integrity" "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw=="
- "resolved" "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz"
- "version" "7.1.19"
- dependencies:
- "@babel/parser" "^7.1.0"
- "@babel/types" "^7.0.0"
- "@types/babel__generator" "*"
- "@types/babel__template" "*"
- "@types/babel__traverse" "*"
-
-"@types/babel__generator@*":
- "integrity" "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg=="
- "resolved" "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz"
- "version" "7.6.4"
- dependencies:
- "@babel/types" "^7.0.0"
-
-"@types/babel__template@*":
- "integrity" "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g=="
- "resolved" "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz"
- "version" "7.4.1"
- dependencies:
- "@babel/parser" "^7.1.0"
- "@babel/types" "^7.0.0"
-
-"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6":
- "integrity" "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA=="
- "resolved" "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz"
- "version" "7.17.1"
- dependencies:
- "@babel/types" "^7.3.0"
-
-"@types/chai@^4.2.14":
- "integrity" "sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ=="
- "resolved" "https://registry.npmjs.org/@types/chai/-/chai-4.2.15.tgz"
- "version" "4.2.15"
-
-"@types/chrome@^0.0.119":
- "integrity" "sha512-Hpl2pFrtnqyHQKTz15HcJ2gLaSojb7HozEwp1OX10ERqaBcfVNnkn+Vq0YeSMiKgvwf/zz73GazK05obaQ3rhg=="
- "resolved" "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.119.tgz"
- "version" "0.0.119"
- dependencies:
- "@types/filesystem" "*"
- "@types/har-format" "*"
-
-"@types/classnames@^2.2.9":
- "integrity" "sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw=="
- "resolved" "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.11.tgz"
- "version" "2.2.11"
-
-"@types/color-name@^1.1.1":
- "integrity" "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
- "resolved" "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz"
- "version" "1.1.1"
-
-"@types/d3-array@*":
- "integrity" "sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.3.tgz"
- "version" "3.0.3"
-
-"@types/d3-axis@*":
- "integrity" "sha512-zji/iIbdd49g9WN0aIsGcwcTBUkgLsCSwB+uH+LPVDAiKWENMtI3cJEWt+7/YYwelMoZmbBfzA3qCdrZ2XFNnw=="
- "resolved" "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "@types/d3-selection" "*"
-
-"@types/d3-brush@*":
- "integrity" "sha512-B532DozsiTuQMHu2YChdZU0qsFJSio3Q6jmBYGYNp3gMDzBmuFFgPt9qKA4VYuLZMp4qc6eX7IUFUEsvHiXZAw=="
- "resolved" "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "@types/d3-selection" "*"
-
-"@types/d3-chord@*":
- "integrity" "sha512-eQfcxIHrg7V++W8Qxn6QkqBNBokyhdWSAS73AbkbMzvLQmVVBviknoz2SRS/ZJdIOmhcmmdCRE/NFOm28Z1AMw=="
- "resolved" "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.1.tgz"
- "version" "3.0.1"
-
-"@types/d3-color@*", "@types/d3-color@^1":
- "integrity" "sha512-xkPLi+gbgUU9ED6QX4g6jqYL2KCB0/3AlM+ncMGqn49OgH0gFMY/ITGqPF8HwEiLzJaC+2L0I+gNwBgABv1Pvg=="
- "resolved" "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.4.1.tgz"
- "version" "1.4.1"
-
-"@types/d3-contour@*":
- "integrity" "sha512-C3zfBrhHZvrpAAK3YXqLWVAGo87A4SvJ83Q/zVJ8rFWJdKejUnDYaWZPkA8K84kb2vDA/g90LTQAz7etXcgoQQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "@types/d3-array" "*"
- "@types/geojson" "*"
-
-"@types/d3-delaunay@*":
- "integrity" "sha512-tLxQ2sfT0p6sxdG75c6f/ekqxjyYR0+LwPrsO1mbC9YDBzPJhs2HbJJRrn8Ez1DBoHRo2yx7YEATI+8V1nGMnQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.1.tgz"
- "version" "6.0.1"
-
-"@types/d3-dispatch@*":
- "integrity" "sha512-NhxMn3bAkqhjoxabVJWKryhnZXXYYVQxaBnbANu0O94+O/nX9qSjrA1P1jbAQJxJf+VC72TxDX/YJcKue5bRqw=="
- "resolved" "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.1.tgz"
- "version" "3.0.1"
-
-"@types/d3-drag@*":
- "integrity" "sha512-o1Va7bLwwk6h03+nSM8dpaGEYnoIG19P0lKqlic8Un36ymh9NSkNFX1yiXMKNMx8rJ0Kfnn2eovuFaL6Jvj0zA=="
- "resolved" "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "@types/d3-selection" "*"
-
-"@types/d3-dsv@*":
- "integrity" "sha512-o0/7RlMl9p5n6FQDptuJVMxDf/7EDEv2SYEO/CwdG2tr1hTfUVi0Iavkk2ax+VpaQ/1jVhpnj5rq1nj8vwhn2A=="
- "resolved" "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.0.tgz"
- "version" "3.0.0"
-
-"@types/d3-ease@*":
- "integrity" "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA=="
- "resolved" "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz"
- "version" "3.0.0"
-
-"@types/d3-fetch@*":
- "integrity" "sha512-toZJNOwrOIqz7Oh6Q7l2zkaNfXkfR7mFSJvGvlD/Ciq/+SQ39d5gynHJZ/0fjt83ec3WL7+u3ssqIijQtBISsw=="
- "resolved" "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "@types/d3-dsv" "*"
-
-"@types/d3-force@*":
- "integrity" "sha512-z8GteGVfkWJMKsx6hwC3SiTSLspL98VNpmvLpEFJQpZPq6xpA1I8HNBDNSpukfK0Vb0l64zGFhzunLgEAcBWSA=="
- "resolved" "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.3.tgz"
- "version" "3.0.3"
-
-"@types/d3-format@*":
- "integrity" "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg=="
- "resolved" "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz"
- "version" "3.0.1"
-
-"@types/d3-geo@*":
- "integrity" "sha512-DbqK7MLYA8LpyHQfv6Klz0426bQEf7bRTvhMy44sNGVyZoWn//B0c+Qbeg8Osi2Obdc9BLLXYAKpyWege2/7LQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.2.tgz"
- "version" "3.0.2"
- dependencies:
- "@types/geojson" "*"
-
-"@types/d3-hierarchy@*", "@types/d3-hierarchy@^1.1.6":
- "integrity" "sha512-fvht6DOYKzqmXjMb/+xfgkmrWM4SD7rMA/ZbM+gGwr9ZTuIDfky95J8CARtaJo/ExeWyS0xGVdL2gqno2zrQ0Q=="
- "resolved" "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.7.tgz"
- "version" "1.1.7"
-
-"@types/d3-interpolate@*", "@types/d3-interpolate@^1.3.1":
- "integrity" "sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg=="
- "resolved" "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz"
- "version" "1.4.2"
- dependencies:
- "@types/d3-color" "^1"
-
-"@types/d3-path@*", "@types/d3-path@^1", "@types/d3-path@^1.0.8":
- "integrity" "sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.9.tgz"
- "version" "1.0.9"
-
-"@types/d3-polygon@*":
- "integrity" "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw=="
- "resolved" "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.0.tgz"
- "version" "3.0.0"
-
-"@types/d3-quadtree@*":
- "integrity" "sha512-QNcK8Jguvc8lU+4OfeNx+qnVy7c0VrDJ+CCVFS9srBo2GL9Y18CnIxBdTF3v38flrGy5s1YggcoAiu6s4fLQIw=="
- "resolved" "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.2.tgz"
- "version" "3.0.2"
-
-"@types/d3-random@*":
- "integrity" "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.1.tgz"
- "version" "3.0.1"
-
-"@types/d3-scale-chromatic@*", "@types/d3-scale-chromatic@^2.0.0":
- "integrity" "sha512-Y62+2clOwZoKua84Ha0xU77w7lePiaBoTjXugT4l8Rd5LAk+Mn/ZDtrgs087a+B5uJ3jYUHHtKw5nuEzp0WBHw=="
- "resolved" "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz"
- "version" "2.0.0"
-
-"@types/d3-scale@*", "@types/d3-scale@^3.3.0":
- "integrity" "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz"
- "version" "3.3.2"
- dependencies:
- "@types/d3-time" "^2"
-
-"@types/d3-selection@*":
- "integrity" "sha512-Mw5cf6nlW1MlefpD9zrshZ+DAWL4IQ5LnWfRheW6xwsdaWOb6IRRu2H7XPAQcyXEx1D7XQWgdoKR83ui1/HlEA=="
- "resolved" "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.3.tgz"
- "version" "3.0.3"
-
-"@types/d3-shape@*", "@types/d3-shape@^1.3.1":
- "integrity" "sha512-aPEax03owTAKynoK8ZkmkZEDZvvT4Y5pWgii4Jp4oQt0gH45j6siDl9gNDVC5kl64XHN2goN9jbYoHK88tFAcA=="
- "resolved" "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.5.tgz"
- "version" "1.3.5"
- dependencies:
- "@types/d3-path" "^1"
-
-"@types/d3-time-format@*":
- "integrity" "sha512-yjfBUe6DJBsDin2BMIulhSHmr5qNR5Pxs17+oW4DoVPyVIXZ+m6bs7j1UVKP08Emv6jRmYrYqxYzO63mQxy1rw=="
- "resolved" "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.0.tgz"
- "version" "4.0.0"
-
-"@types/d3-time@*", "@types/d3-time@^2", "@types/d3-time@^2.0.0":
- "integrity" "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg=="
- "resolved" "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz"
- "version" "2.1.1"
-
-"@types/d3-timer@*":
- "integrity" "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g=="
- "resolved" "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz"
- "version" "3.0.0"
-
-"@types/d3-transition@*":
- "integrity" "sha512-jo5o/Rf+/u6uerJ/963Dc39NI16FQzqwOc54bwvksGAdVfvDrqDpVeq95bEvPtBwLCVZutAEyAtmSyEMxN7vxQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.2.tgz"
- "version" "3.0.2"
- dependencies:
- "@types/d3-selection" "*"
-
-"@types/d3-zoom@*":
- "integrity" "sha512-7s5L9TjfqIYQmQQEUcpMAcBOahem7TRoSO/+Gkz02GbMVuULiZzjF2BOdw291dbO2aNon4m2OdFsRGaCq2caLQ=="
- "resolved" "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "@types/d3-interpolate" "*"
- "@types/d3-selection" "*"
-
-"@types/d3@^7.4.0":
- "integrity" "sha512-jIfNVK0ZlxcuRDKtRS/SypEyOQ6UHaFQBKv032X45VvxSJ6Yi5G9behy9h6tNTHTDGh5Vq+KbmBjUWLgY4meCA=="
- "resolved" "https://registry.npmjs.org/@types/d3/-/d3-7.4.0.tgz"
- "version" "7.4.0"
- dependencies:
- "@types/d3-array" "*"
- "@types/d3-axis" "*"
- "@types/d3-brush" "*"
- "@types/d3-chord" "*"
- "@types/d3-color" "*"
- "@types/d3-contour" "*"
- "@types/d3-delaunay" "*"
- "@types/d3-dispatch" "*"
- "@types/d3-drag" "*"
- "@types/d3-dsv" "*"
- "@types/d3-ease" "*"
- "@types/d3-fetch" "*"
- "@types/d3-force" "*"
- "@types/d3-format" "*"
- "@types/d3-geo" "*"
- "@types/d3-hierarchy" "*"
- "@types/d3-interpolate" "*"
- "@types/d3-path" "*"
- "@types/d3-polygon" "*"
- "@types/d3-quadtree" "*"
- "@types/d3-random" "*"
- "@types/d3-scale" "*"
- "@types/d3-scale-chromatic" "*"
- "@types/d3-selection" "*"
- "@types/d3-shape" "*"
- "@types/d3-time" "*"
- "@types/d3-time-format" "*"
- "@types/d3-timer" "*"
- "@types/d3-transition" "*"
- "@types/d3-zoom" "*"
-
-"@types/eslint-visitor-keys@^1.0.0":
- "integrity" "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag=="
- "resolved" "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz"
- "version" "1.0.0"
-
-"@types/filesystem@*":
- "integrity" "sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw=="
- "resolved" "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.29.tgz"
- "version" "0.0.29"
- dependencies:
- "@types/filewriter" "*"
-
-"@types/filewriter@*":
- "integrity" "sha1-wFTor02d11205jq8dviFFocU1LM=sha512-AR2KUJIMdSfl/SaAHpRotBAlaJpmhgHwehEeSJQOG0hS3IrjDU16xUEEUTdqcvdLa1q16ZK5MMrtOagfLvm0gw==sha512-AR2KUJIMdSfl/SaAHpRotBAlaJpmhgHwehEeSJQOG0hS3IrjDU16xUEEUTdqcvdLa1q16ZK5MMrtOagfLvm0gw==sha512-AR2KUJIMdSfl/SaAHpRotBAlaJpmhgHwehEeSJQOG0hS3IrjDU16xUEEUTdqcvdLa1q16ZK5MMrtOagfLvm0gw==sha512-AR2KUJIMdSfl/SaAHpRotBAlaJpmhgHwehEeSJQOG0hS3IrjDU16xUEEUTdqcvdLa1q16ZK5MMrtOagfLvm0gw==sha512-AR2KUJIMdSfl/SaAHpRotBAlaJpmhgHwehEeSJQOG0hS3IrjDU16xUEEUTdqcvdLa1q16ZK5MMrtOagfLvm0gw==sha512-AR2KUJIMdSfl/SaAHpRotBAlaJpmhgHwehEeSJQOG0hS3IrjDU16xUEEUTdqcvdLa1q16ZK5MMrtOagfLvm0gw==sha512-AR2KUJIMdSfl/SaAHpRotBAlaJpmhgHwehEeSJQOG0hS3IrjDU16xUEEUTdqcvdLa1q16ZK5MMrtOagfLvm0gw== sha512-AR2KUJIMdSfl/SaAHpRotBAlaJpmhgHwehEeSJQOG0hS3IrjDU16xUEEUTdqcvdLa1q16ZK5MMrtOagfLvm0gw=="
- "resolved" "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz"
- "version" "0.0.28"
-
-"@types/geojson@*":
- "integrity" "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA=="
- "resolved" "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz"
- "version" "7946.0.10"
-
-"@types/graceful-fs@^4.1.2":
- "integrity" "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ=="
- "resolved" "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz"
- "version" "4.1.3"
- dependencies:
- "@types/node" "*"
-
-"@types/har-format@*":
- "integrity" "sha512-iUxzm1meBm3stxUMzRqgOVHjj4Kgpgu5w9fm4X7kPRfSgVRzythsucEN7/jtOo8SQzm+HfcxWWzJS0mJDH/3DQ=="
- "resolved" "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.4.tgz"
- "version" "1.2.4"
-
-"@types/history@^4.7.11":
- "integrity" "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA=="
- "resolved" "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz"
- "version" "4.7.11"
-
-"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
- "integrity" "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw=="
- "resolved" "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz"
- "version" "2.0.3"
-
-"@types/istanbul-lib-report@*":
- "integrity" "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg=="
- "resolved" "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "@types/istanbul-lib-coverage" "*"
-
-"@types/istanbul-reports@^1.1.1":
- "integrity" "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw=="
- "resolved" "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz"
- "version" "1.1.2"
- dependencies:
- "@types/istanbul-lib-coverage" "*"
- "@types/istanbul-lib-report" "*"
-
-"@types/istanbul-reports@^3.0.0":
- "integrity" "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw=="
- "resolved" "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "@types/istanbul-lib-report" "*"
-
-"@types/jest@^26.0.4":
- "integrity" "sha512-4fQNItvelbNA9+sFgU+fhJo8ZFF+AS4Egk3GWwCW2jFtViukXbnztccafAdLhzE/0EiCogljtQQXP8aQ9J7sFg=="
- "resolved" "https://registry.npmjs.org/@types/jest/-/jest-26.0.4.tgz"
- "version" "26.0.4"
- dependencies:
- "jest-diff" "^25.2.1"
- "pretty-format" "^25.2.1"
-
-"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
- "integrity" "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ=="
- "resolved" "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz"
- "version" "7.0.9"
-
-"@types/json5@^0.0.29":
- "integrity" "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
- "resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
- "version" "0.0.29"
-
-"@types/lodash.isequal@^4.5.5":
- "integrity" "sha512-4IKbinG7MGP131wRfceK6W4E/Qt3qssEFLF30LnJbjYiSfHGGRU/Io8YxXrZX109ir+iDETC8hw8QsDijukUVg=="
- "resolved" "https://registry.npmjs.org/@types/lodash.isequal/-/lodash.isequal-4.5.5.tgz"
- "version" "4.5.5"
- dependencies:
- "@types/lodash" "*"
-
-"@types/lodash@*", "@types/lodash@^4.14.146", "@types/lodash@^4.14.160":
- "integrity" "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q=="
- "resolved" "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz"
- "version" "4.14.168"
-
-"@types/node@*", "@types/node@^12.19.6":
- "integrity" "sha512-sRVq8d+ApGslmkE9e3i+D3gFGk7aZHAT+G4cIpIEdLJYPsWiSPwcAnJEjddLQQDqV3Ra2jOclX/Sv6YrvGYiWA=="
- "resolved" "https://registry.npmjs.org/@types/node/-/node-12.20.6.tgz"
- "version" "12.20.6"
-
-"@types/normalize-package-data@^2.4.0":
- "integrity" "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA=="
- "resolved" "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz"
- "version" "2.4.0"
-
-"@types/parse-json@^4.0.0":
- "integrity" "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
- "resolved" "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz"
- "version" "4.0.0"
-
-"@types/prettier@^2.0.0":
- "integrity" "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg=="
- "resolved" "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz"
- "version" "2.6.3"
-
-"@types/prop-types@*", "@types/prop-types@^15.7.5":
- "integrity" "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
- "resolved" "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
- "version" "15.7.5"
-
-"@types/react-dom@*", "@types/react-dom@^17.0.14":
- "integrity" "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ=="
- "resolved" "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz"
- "version" "17.0.14"
- dependencies:
- "@types/react" "*"
-
-"@types/react-dom@^18.0.0":
- "integrity" "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg=="
- "resolved" "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz"
- "version" "18.0.10"
- dependencies:
- "@types/react" "*"
-
-"@types/react-is@^16.7.1 || ^17.0.0":
- "integrity" "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw=="
- "resolved" "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz"
- "version" "17.0.3"
- dependencies:
- "@types/react" "*"
-
-"@types/react-router-dom@^5.3.3":
- "integrity" "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw=="
- "resolved" "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz"
- "version" "5.3.3"
- dependencies:
- "@types/history" "^4.7.11"
- "@types/react" "*"
- "@types/react-router" "*"
-
-"@types/react-router@*":
- "integrity" "sha512-YYknwy0D0iOwKQgz9v8nOzt2J6l4gouBmDnWqUUznltOTaon+r8US8ky8HvN0tXvc38U9m6z/t2RsVsnd1zM0g=="
- "resolved" "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.18.tgz"
- "version" "5.1.18"
- dependencies:
- "@types/history" "^4.7.11"
- "@types/react" "*"
-
-"@types/react-transition-group@^4.2.0", "@types/react-transition-group@^4.4.4":
- "integrity" "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA=="
- "resolved" "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz"
- "version" "4.4.5"
- dependencies:
- "@types/react" "*"
-
-"@types/react@*", "@types/react@^16.8.6 || ^17.0.0", "@types/react@^17.0.0 || ^18.0.0", "@types/react@^17.0.43":
- "integrity" "sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A=="
- "resolved" "https://registry.npmjs.org/@types/react/-/react-17.0.43.tgz"
- "version" "17.0.43"
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- "csstype" "^3.0.2"
-
-"@types/scheduler@*":
- "integrity" "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA=="
- "resolved" "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz"
- "version" "0.16.1"
-
-"@types/stack-utils@^2.0.0":
- "integrity" "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw=="
- "resolved" "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz"
- "version" "2.0.1"
-
-"@types/yargs-parser@*":
- "integrity" "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
- "resolved" "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz"
- "version" "15.0.0"
-
-"@types/yargs@^13.0.0":
- "integrity" "sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ=="
- "resolved" "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.11.tgz"
- "version" "13.0.11"
- dependencies:
- "@types/yargs-parser" "*"
-
-"@types/yargs@^15.0.0":
- "integrity" "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w=="
- "resolved" "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz"
- "version" "15.0.5"
- dependencies:
- "@types/yargs-parser" "*"
-
-"@types/yauzl@^2.9.1":
- "integrity" "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw=="
- "resolved" "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz"
- "version" "2.10.0"
- dependencies:
- "@types/node" "*"
-
-"@typescript-eslint/eslint-plugin@^3.6.1":
- "integrity" "sha512-06lfjo76naNeOMDl+mWG9Fh/a0UHKLGhin+mGaIw72FUMbMGBkdi/FEJmgEDzh4eE73KIYzHWvOCYJ0ak7nrJQ=="
- "resolved" "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.6.1.tgz"
- "version" "3.6.1"
- dependencies:
- "@typescript-eslint/experimental-utils" "3.6.1"
- "debug" "^4.1.1"
- "functional-red-black-tree" "^1.0.1"
- "regexpp" "^3.0.0"
- "semver" "^7.3.2"
- "tsutils" "^3.17.1"
-
-"@typescript-eslint/experimental-utils@^1.13.0":
- "integrity" "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg=="
- "resolved" "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz"
- "version" "1.13.0"
- dependencies:
- "@types/json-schema" "^7.0.3"
- "@typescript-eslint/typescript-estree" "1.13.0"
- "eslint-scope" "^4.0.0"
-
-"@typescript-eslint/experimental-utils@3.6.1":
- "integrity" "sha512-oS+hihzQE5M84ewXrTlVx7eTgc52eu+sVmG7ayLfOhyZmJ8Unvf3osyFQNADHP26yoThFfbxcibbO0d2FjnYhg=="
- "resolved" "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.6.1.tgz"
- "version" "3.6.1"
- dependencies:
- "@types/json-schema" "^7.0.3"
- "@typescript-eslint/types" "3.6.1"
- "@typescript-eslint/typescript-estree" "3.6.1"
- "eslint-scope" "^5.0.0"
- "eslint-utils" "^2.0.0"
-
-"@typescript-eslint/parser@^3.0.0", "@typescript-eslint/parser@^3.6.1":
- "integrity" "sha512-SLihQU8RMe77YJ/jGTqOt0lMq7k3hlPVfp7v/cxMnXA9T0bQYoMDfTsNgHXpwSJM1Iq2aAJ8WqekxUwGv5F67Q=="
- "resolved" "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.6.1.tgz"
- "version" "3.6.1"
- dependencies:
- "@types/eslint-visitor-keys" "^1.0.0"
- "@typescript-eslint/experimental-utils" "3.6.1"
- "@typescript-eslint/types" "3.6.1"
- "@typescript-eslint/typescript-estree" "3.6.1"
- "eslint-visitor-keys" "^1.1.0"
-
-"@typescript-eslint/types@3.6.1":
- "integrity" "sha512-NPxd5yXG63gx57WDTW1rp0cF3XlNuuFFB5G+Kc48zZ+51ZnQn9yjDEsjTPQ+aWM+V+Z0I4kuTFKjKvgcT1F7xQ=="
- "resolved" "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.6.1.tgz"
- "version" "3.6.1"
-
-"@typescript-eslint/typescript-estree@1.13.0":
- "integrity" "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw=="
- "resolved" "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz"
- "version" "1.13.0"
- dependencies:
- "lodash.unescape" "4.0.1"
- "semver" "5.5.0"
-
-"@typescript-eslint/typescript-estree@3.6.1":
- "integrity" "sha512-G4XRe/ZbCZkL1fy09DPN3U0mR6SayIv1zSeBNquRFRk7CnVLgkC2ZPj8llEMJg5Y8dJ3T76SvTGtceytniaztQ=="
- "resolved" "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.6.1.tgz"
- "version" "3.6.1"
- dependencies:
- "@typescript-eslint/types" "3.6.1"
- "@typescript-eslint/visitor-keys" "3.6.1"
- "debug" "^4.1.1"
- "glob" "^7.1.6"
- "is-glob" "^4.0.1"
- "lodash" "^4.17.15"
- "semver" "^7.3.2"
- "tsutils" "^3.17.1"
-
-"@typescript-eslint/visitor-keys@3.6.1":
- "integrity" "sha512-qC8Olwz5ZyMTZrh4Wl3K4U6tfms0R/mzU4/5W3XeUZptVraGVmbptJbn6h2Ey6Rb3hOs3zWoAUebZk8t47KGiQ=="
- "resolved" "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.6.1.tgz"
- "version" "3.6.1"
- dependencies:
- "eslint-visitor-keys" "^1.1.0"
-
-"@visx/axis@^1.0.0":
- "integrity" "sha512-3JdAY8xwA4xVnzkbXdIzCOWYCknCgw3L185lOJTXWNGO7kIgzbQ2YrLXnet37BFgD83MfxmlP6LhiHLkKVI6OQ=="
- "resolved" "https://registry.npmjs.org/@visx/axis/-/axis-1.17.1.tgz"
- "version" "1.17.1"
- dependencies:
- "@types/react" "*"
- "@visx/group" "1.17.1"
- "@visx/point" "1.7.0"
- "@visx/scale" "1.14.0"
- "@visx/shape" "1.17.1"
- "@visx/text" "1.17.1"
- "classnames" "^2.3.1"
- "prop-types" "^15.6.0"
-
-"@visx/bounds@1.7.0":
- "integrity" "sha512-ajF6PTgDoZTfwv5J0ZTx1miXY8lk3sGhMVqE3UsMubdTZBlOgeZMT4OmtTPtbCJTBTgw0FD0gd7X3gZ+3X9HgQ=="
- "resolved" "https://registry.npmjs.org/@visx/bounds/-/bounds-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/react" "*"
- "@types/react-dom" "*"
- "prop-types" "^15.5.10"
-
-"@visx/brush@^1.2.0":
- "integrity" "sha512-BSJWVVLU5GCOZGSaon1qh7BcGHrchLQ38SMuXlNhVIdH5ubiLC9J5Pj6l/NQSdQd1cYTD6eNceEiwnxa5TOWrQ=="
- "resolved" "https://registry.npmjs.org/@visx/brush/-/brush-1.18.1.tgz"
- "version" "1.18.1"
- dependencies:
- "@visx/drag" "1.18.1"
- "@visx/event" "1.7.0"
- "@visx/group" "1.17.1"
- "@visx/shape" "1.17.1"
- "classnames" "^2.3.1"
- "prop-types" "^15.6.1"
-
-"@visx/clip-path@^1.0.0":
- "integrity" "sha512-PuEz/2Clmx3qb0gat4kzjoq/rLush1nhNOT1DV7ui/fipC7z+KpB53OXHeOviB4udD+u233W5kY1uSErLysPRQ=="
- "resolved" "https://registry.npmjs.org/@visx/clip-path/-/clip-path-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/react" "*"
- "prop-types" "^15.5.10"
-
-"@visx/curve@1.7.0":
- "integrity" "sha512-n0/SHM4YXjke+aEinhHFZPLMxWu3jbqtvqzfGJyibX8OmbDjavk9P+MHfGokUcw0xHy6Ch3YTuwbYuvVw5ny9A=="
- "resolved" "https://registry.npmjs.org/@visx/curve/-/curve-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/d3-shape" "^1.3.1"
- "d3-shape" "^1.0.6"
-
-"@visx/drag@1.18.1":
- "integrity" "sha512-5xsgUUthG/0Nq51HFWYIe3NaHT5csxuVqx/+VfNsjkGgCHntWkcS2soPlEMh4wUT2iPKRs9z9VtRAyrpN4TtKw=="
- "resolved" "https://registry.npmjs.org/@visx/drag/-/drag-1.18.1.tgz"
- "version" "1.18.1"
- dependencies:
- "@types/react" "*"
- "@visx/event" "1.7.0"
- "prop-types" "^15.5.10"
-
-"@visx/event@^1.0.0", "@visx/event@1.7.0":
- "integrity" "sha512-RbAoKxvy+ildX2dVXC9/ZX94lQXPwjKgtO9jy7COc15knG4zmzsMCDYDC3uLd0+jE2o/+gSaZ/9r52p6zG5+IQ=="
- "resolved" "https://registry.npmjs.org/@visx/event/-/event-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/react" "*"
- "@visx/point" "1.7.0"
-
-"@visx/glyph@^1.0.0":
- "integrity" "sha512-fejF4c/t2psZ600RwuF29g2rjD2RHgieQNdW6jW1nupfbBgItii6+65wlk9J2rp9qLlorValf4o7A4DG5bXDEQ=="
- "resolved" "https://registry.npmjs.org/@visx/glyph/-/glyph-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/classnames" "^2.2.9"
- "@types/d3-shape" "^1.3.1"
- "@types/react" "*"
- "@visx/group" "1.7.0"
- "classnames" "^2.2.5"
- "d3-shape" "^1.2.0"
- "prop-types" "^15.6.2"
-
-"@visx/gradient@^1.0.0":
- "integrity" "sha512-KtlzpgY+1tEIxEhFwyGp7nVwDjaPs9bcLO5Wkm3uw5ehQtRMYQBC3O2N+GEKdQM2yNZVApvtSMiXQDxGTFK67g=="
- "resolved" "https://registry.npmjs.org/@visx/gradient/-/gradient-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/react" "*"
- "prop-types" "^15.5.7"
-
-"@visx/grid@^1.0.0":
- "integrity" "sha512-dse9q3weDqPNmeXK0lGKKPRgGiDuUjJ7Mt7NNonPUyXPctNmv6lJEWZu9HJrXEGiCAVNa8PHJ7Qkns/z+mH88Q=="
- "resolved" "https://registry.npmjs.org/@visx/grid/-/grid-1.17.1.tgz"
- "version" "1.17.1"
- dependencies:
- "@types/react" "*"
- "@visx/curve" "1.7.0"
- "@visx/group" "1.17.1"
- "@visx/point" "1.7.0"
- "@visx/scale" "1.14.0"
- "@visx/shape" "1.17.1"
- "classnames" "^2.3.1"
- "prop-types" "^15.6.2"
-
-"@visx/group@^1.0.0", "@visx/group@1.7.0":
- "integrity" "sha512-rzSXtV0+MHUyK+rwhVSV4qaHdzGi3Me3PRFXJSIAKVfoJIZczOkudUOLy34WvSrRlVyoFvGL7k9U5g8wHyY3nw=="
- "resolved" "https://registry.npmjs.org/@visx/group/-/group-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/classnames" "^2.2.9"
- "@types/react" "*"
- "classnames" "^2.2.5"
- "prop-types" "^15.6.2"
-
-"@visx/group@1.17.1":
- "integrity" "sha512-g8pSqy8TXAisiOzypnVycDynEGlBhfxtVlwDmsbYB+XSFGEjnOheQSDohDI+ia7ek54Mw9uYe05tx5kP1hRMYw=="
- "resolved" "https://registry.npmjs.org/@visx/group/-/group-1.17.1.tgz"
- "version" "1.17.1"
- dependencies:
- "@types/react" "*"
- "classnames" "^2.3.1"
- "prop-types" "^15.6.2"
-
-"@visx/hierarchy@^1.0.0":
- "integrity" "sha512-s9kU8uNGl3ekH3aEUK0LZED4hbJgj2qmjP+7SAhnJGtzut668L6YSPKHsPh+XS8qKUJ6I1dRn/eJCSF4gt8NQQ=="
- "resolved" "https://registry.npmjs.org/@visx/hierarchy/-/hierarchy-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/classnames" "^2.2.9"
- "@types/d3-hierarchy" "^1.1.6"
- "@types/react" "*"
- "@visx/group" "1.7.0"
- "classnames" "^2.2.5"
- "d3-hierarchy" "^1.1.4"
- "prop-types" "^15.6.1"
-
-"@visx/legend@^1.0.0":
- "integrity" "sha512-vdB3EPHXYwTyS4g2MB/sVAvq6ddeyzjlTjsM6YNc6Nagwb4uTOuMeKT+t0jgLJejNMOcY7Q8eBjDDWAdiPNV1A=="
- "resolved" "https://registry.npmjs.org/@visx/legend/-/legend-1.17.1.tgz"
- "version" "1.17.1"
- dependencies:
- "@types/react" "*"
- "@visx/group" "1.17.1"
- "@visx/scale" "1.14.0"
- "classnames" "^2.3.1"
- "prop-types" "^15.5.10"
-
-"@visx/point@1.7.0":
- "integrity" "sha512-oaoY/HXYHhmpkkeKI4rBPmFtjHWtxSrIhZCVm1ipPoyQp3voJ8L6JD5eUIVmmaUCdUGUGwL1lFLnJiQ2p1Vlwg=="
- "resolved" "https://registry.npmjs.org/@visx/point/-/point-1.7.0.tgz"
- "version" "1.7.0"
-
-"@visx/responsive@^1.0.0":
- "integrity" "sha512-1S78uLxT1wLMz36pocON3ddZMNJH93lHRYNRC0bcWOFKJKGNTuiUL1/nKXIIm9IZCvuxgh/KuBOGXdO+WnCJkg=="
- "resolved" "https://registry.npmjs.org/@visx/responsive/-/responsive-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/lodash" "^4.14.146"
- "@types/react" "*"
- "lodash" "^4.17.10"
- "prop-types" "^15.6.1"
- "resize-observer-polyfill" "1.5.1"
-
-"@visx/scale@^1.0.0", "@visx/scale@1.14.0":
- "integrity" "sha512-ovbtEOF/d76uGMJ5UZlxdS3t2T8I6md+aIwOXBaq0HdjaCLbe7HLlMyHJKjak/sqBxLAiCGVnechTUpSkfgSQw=="
- "resolved" "https://registry.npmjs.org/@visx/scale/-/scale-1.14.0.tgz"
- "version" "1.14.0"
- dependencies:
- "@types/d3-interpolate" "^1.3.1"
- "@types/d3-scale" "^3.3.0"
- "@types/d3-time" "^2.0.0"
- "d3-interpolate" "^1.4.0"
- "d3-scale" "^3.3.0"
- "d3-time" "^2.1.1"
-
-"@visx/shape@^1.0.0", "@visx/shape@1.17.1":
- "integrity" "sha512-rVYFpytPCnV4s5U0za+jQ2jqFzKnmB3c8RP6fuOfF6kKosFPJcOYg9ikvewojARyMBTr1u3XvWV960Da+xyUdQ=="
- "resolved" "https://registry.npmjs.org/@visx/shape/-/shape-1.17.1.tgz"
- "version" "1.17.1"
- dependencies:
- "@types/d3-path" "^1.0.8"
- "@types/d3-shape" "^1.3.1"
- "@types/lodash" "^4.14.146"
- "@types/react" "*"
- "@visx/curve" "1.7.0"
- "@visx/group" "1.17.1"
- "@visx/scale" "1.14.0"
- "classnames" "^2.3.1"
- "d3-path" "^1.0.5"
- "d3-shape" "^1.2.0"
- "lodash" "^4.17.15"
- "prop-types" "^15.5.10"
-
-"@visx/text@^1.0.0", "@visx/text@1.17.1":
- "integrity" "sha512-Cx6iH0kVq3YqCfFj7U6bMiKwa/bz4Z3q0vPdxmnVGcPjGZM1ac/y61KFH263e164LJ5jFaTYpPrrFmbZoy8+Vg=="
- "resolved" "https://registry.npmjs.org/@visx/text/-/text-1.17.1.tgz"
- "version" "1.17.1"
- dependencies:
- "@types/lodash" "^4.14.160"
- "@types/react" "*"
- "classnames" "^2.3.1"
- "lodash" "^4.17.20"
- "prop-types" "^15.7.2"
- "reduce-css-calc" "^1.3.0"
-
-"@visx/tooltip@^1.0.0":
- "integrity" "sha512-QCNLaOGpgZ6RnZjCIbEJtfbu8ZkSwDOXRy5SOUvcC5J9RiEwCi0DXF1JzT7ZPv3hkLU1KiSPaUFf5q/5LNHwLg=="
- "resolved" "https://registry.npmjs.org/@visx/tooltip/-/tooltip-1.7.2.tgz"
- "version" "1.7.2"
- dependencies:
- "@types/classnames" "^2.2.9"
- "@types/react" "*"
- "@visx/bounds" "1.7.0"
- "classnames" "^2.2.5"
- "prop-types" "^15.5.10"
- "react-use-measure" "^2.0.4"
-
-"@visx/zoom@^1.0.0":
- "integrity" "sha512-3r1fJ84CIiKDDBBm+0t0okzBF2s56FaZD84Ut2g52A7CJGmNz6v8O613zTFVxRyEK3gRieOfm0IlWCt1LpFRqg=="
- "resolved" "https://registry.npmjs.org/@visx/zoom/-/zoom-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "@types/react" "*"
- "@visx/event" "1.7.0"
- "prop-types" "^15.6.2"
-
-"@webassemblyjs/ast@1.9.0":
- "integrity" "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/helper-module-context" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/wast-parser" "1.9.0"
-
-"@webassemblyjs/floating-point-hex-parser@1.9.0":
- "integrity" "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz"
- "version" "1.9.0"
-
-"@webassemblyjs/helper-api-error@1.9.0":
- "integrity" "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz"
- "version" "1.9.0"
-
-"@webassemblyjs/helper-buffer@1.9.0":
- "integrity" "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz"
- "version" "1.9.0"
-
-"@webassemblyjs/helper-code-frame@1.9.0":
- "integrity" "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/wast-printer" "1.9.0"
-
-"@webassemblyjs/helper-fsm@1.9.0":
- "integrity" "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz"
- "version" "1.9.0"
-
-"@webassemblyjs/helper-module-context@1.9.0":
- "integrity" "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
-
-"@webassemblyjs/helper-wasm-bytecode@1.9.0":
- "integrity" "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz"
- "version" "1.9.0"
-
-"@webassemblyjs/helper-wasm-section@1.9.0":
- "integrity" "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-buffer" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/wasm-gen" "1.9.0"
-
-"@webassemblyjs/ieee754@1.9.0":
- "integrity" "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@xtuc/ieee754" "^1.2.0"
-
-"@webassemblyjs/leb128@1.9.0":
- "integrity" "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@xtuc/long" "4.2.2"
-
-"@webassemblyjs/utf8@1.9.0":
- "integrity" "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz"
- "version" "1.9.0"
-
-"@webassemblyjs/wasm-edit@1.9.0":
- "integrity" "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-buffer" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/helper-wasm-section" "1.9.0"
- "@webassemblyjs/wasm-gen" "1.9.0"
- "@webassemblyjs/wasm-opt" "1.9.0"
- "@webassemblyjs/wasm-parser" "1.9.0"
- "@webassemblyjs/wast-printer" "1.9.0"
-
-"@webassemblyjs/wasm-gen@1.9.0":
- "integrity" "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/ieee754" "1.9.0"
- "@webassemblyjs/leb128" "1.9.0"
- "@webassemblyjs/utf8" "1.9.0"
-
-"@webassemblyjs/wasm-opt@1.9.0":
- "integrity" "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-buffer" "1.9.0"
- "@webassemblyjs/wasm-gen" "1.9.0"
- "@webassemblyjs/wasm-parser" "1.9.0"
-
-"@webassemblyjs/wasm-parser@1.9.0":
- "integrity" "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-api-error" "1.9.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
- "@webassemblyjs/ieee754" "1.9.0"
- "@webassemblyjs/leb128" "1.9.0"
- "@webassemblyjs/utf8" "1.9.0"
-
-"@webassemblyjs/wast-parser@1.9.0":
- "integrity" "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/floating-point-hex-parser" "1.9.0"
- "@webassemblyjs/helper-api-error" "1.9.0"
- "@webassemblyjs/helper-code-frame" "1.9.0"
- "@webassemblyjs/helper-fsm" "1.9.0"
- "@xtuc/long" "4.2.2"
-
-"@webassemblyjs/wast-printer@1.9.0":
- "integrity" "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA=="
- "resolved" "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz"
- "version" "1.9.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/wast-parser" "1.9.0"
- "@xtuc/long" "4.2.2"
-
-"@xtuc/ieee754@^1.2.0":
- "integrity" "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
- "resolved" "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz"
- "version" "1.2.0"
-
-"@xtuc/long@4.2.2":
- "integrity" "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
- "resolved" "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz"
- "version" "4.2.2"
-
-"abab@^2.0.3", "abab@^2.0.5":
- "integrity" "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA=="
- "resolved" "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz"
- "version" "2.0.6"
-
-"accepts@~1.3.8":
- "integrity" "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="
- "resolved" "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz"
- "version" "1.3.8"
- dependencies:
- "mime-types" "~2.1.34"
- "negotiator" "0.6.3"
-
-"acorn-globals@^6.0.0":
- "integrity" "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg=="
- "resolved" "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz"
- "version" "6.0.0"
- dependencies:
- "acorn" "^7.1.1"
- "acorn-walk" "^7.1.1"
-
-"acorn-jsx@^5.2.0":
- "integrity" "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ=="
- "resolved" "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz"
- "version" "5.2.0"
-
-"acorn-walk@^7.1.1":
- "integrity" "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA=="
- "resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz"
- "version" "7.2.0"
-
-"acorn@^6.0.0 || ^7.0.0", "acorn@^7.1.1", "acorn@^7.3.1":
- "integrity" "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA=="
- "resolved" "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz"
- "version" "7.3.1"
-
-"acorn@^6.4.1":
- "integrity" "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA=="
- "resolved" "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz"
- "version" "6.4.1"
-
-"acorn@^8.2.4":
- "integrity" "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A=="
- "resolved" "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz"
- "version" "8.7.1"
-
-"add-dom-event-listener@^1.1.0":
- "integrity" "sha512-WCxx1ixHT0GQU9hb0KI/mhgRQhnU+U3GvwY6ZvVjYq8rsihIGoaIOUbY0yMPBxLH5MDtr0kz3fisWGNcbWW7Jw=="
- "resolved" "https://registry.npmjs.org/add-dom-event-listener/-/add-dom-event-listener-1.1.0.tgz"
- "version" "1.1.0"
- dependencies:
- "object-assign" "4.x"
-
-"agent-base@6":
- "integrity" "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="
- "resolved" "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz"
- "version" "6.0.2"
- dependencies:
- "debug" "4"
-
-"airbnb-prop-types@^2.16.0":
- "integrity" "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg=="
- "resolved" "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz"
- "version" "2.16.0"
- dependencies:
- "array.prototype.find" "^2.1.1"
- "function.prototype.name" "^1.1.2"
- "is-regex" "^1.1.0"
- "object-is" "^1.1.2"
- "object.assign" "^4.1.0"
- "object.entries" "^1.1.2"
- "prop-types" "^15.7.2"
- "prop-types-exact" "^1.2.0"
- "react-is" "^16.13.1"
-
-"ajv-errors@^1.0.0":
- "integrity" "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ=="
- "resolved" "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz"
- "version" "1.0.1"
-
-"ajv-keywords@^3.1.0", "ajv-keywords@^3.4.1":
- "integrity" "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
- "resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz"
- "version" "3.5.2"
-
-"ajv@^6.1.0", "ajv@^6.10.0", "ajv@^6.10.2", "ajv@^6.12.2", "ajv@^6.9.1", "ajv@>=5.0.0":
- "integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="
- "resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
- "version" "6.12.6"
- dependencies:
- "fast-deep-equal" "^3.1.1"
- "fast-json-stable-stringify" "^2.0.0"
- "json-schema-traverse" "^0.4.1"
- "uri-js" "^4.2.2"
-
-"ansi-escapes@^4.2.1":
- "integrity" "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA=="
- "resolved" "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz"
- "version" "4.3.1"
- dependencies:
- "type-fest" "^0.11.0"
-
-"ansi-regex@^4.0.0", "ansi-regex@^4.1.0":
- "integrity" "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="
- "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz"
- "version" "4.1.1"
-
-"ansi-regex@^5.0.0":
- "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
- "version" "5.0.1"
-
-"ansi-regex@^5.0.1":
- "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
- "version" "5.0.1"
-
-"ansi-styles@^3.2.0", "ansi-styles@^3.2.1":
- "integrity" "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="
- "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
- "version" "3.2.1"
- dependencies:
- "color-convert" "^1.9.0"
-
-"ansi-styles@^4.0.0", "ansi-styles@^4.1.0":
- "integrity" "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA=="
- "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz"
- "version" "4.2.1"
- dependencies:
- "@types/color-name" "^1.1.1"
- "color-convert" "^2.0.1"
-
-"ansi-styles@^5.0.0":
- "integrity" "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="
- "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz"
- "version" "5.2.0"
-
-"anymatch@^2.0.0":
- "integrity" "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw=="
- "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "micromatch" "^3.1.4"
- "normalize-path" "^2.1.1"
-
-"anymatch@^3.0.3", "anymatch@~3.1.1":
- "integrity" "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg=="
- "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz"
- "version" "3.1.1"
- dependencies:
- "normalize-path" "^3.0.0"
- "picomatch" "^2.0.4"
-
-"apexcharts@^3.18.0", "apexcharts@^3.23.1":
- "integrity" "sha512-zdYHs3k3tgmCn1BpYLj7rhGEndBYF33Pq1+g0ora37xAr+3act5CJrpdXM2jx2boVUyXgavoSp6sa8WpK7RkSA=="
- "resolved" "https://registry.npmjs.org/apexcharts/-/apexcharts-3.26.0.tgz"
- "version" "3.26.0"
- dependencies:
- "svg.draggable.js" "^2.2.2"
- "svg.easing.js" "^2.0.0"
- "svg.filter.js" "^2.0.2"
- "svg.pathmorphing.js" "^0.1.3"
- "svg.resize.js" "^1.4.3"
- "svg.select.js" "^3.0.1"
-
-"aproba@^1.1.1":
- "integrity" "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
- "resolved" "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz"
- "version" "1.2.0"
-
-"arg@^4.1.0":
- "integrity" "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
- "resolved" "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz"
- "version" "4.1.3"
-
-"argparse@^1.0.7":
- "integrity" "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="
- "resolved" "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
- "version" "1.0.10"
- dependencies:
- "sprintf-js" "~1.0.2"
-
-"aria-query@^4.2.2":
- "integrity" "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA=="
- "resolved" "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz"
- "version" "4.2.2"
- dependencies:
- "@babel/runtime" "^7.10.2"
- "@babel/runtime-corejs3" "^7.10.2"
-
-"aria-query@^5.0.0":
- "integrity" "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ=="
- "resolved" "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz"
- "version" "5.1.3"
- dependencies:
- "deep-equal" "^2.0.5"
-
-"arr-diff@^4.0.0":
- "integrity" "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA=="
- "resolved" "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz"
- "version" "4.0.0"
-
-"arr-flatten@^1.1.0":
- "integrity" "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
- "resolved" "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz"
- "version" "1.1.0"
-
-"arr-union@^3.1.0":
- "integrity" "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q=="
- "resolved" "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz"
- "version" "3.1.0"
-
-"array-filter@^1.0.0":
- "integrity" "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA==sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA==sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA==sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA==sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA==sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA==sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA== sha512-Ene1hbrinPZ1qPoZp7NSx4jQnh4nr7MtY78pHNb+yr8yHbxmTS7ChGW0a55JKA7TkRDeoQxK4GcJaCvBYplSKA=="
- "resolved" "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz"
- "version" "1.0.0"
-
-"array-flatten@1.1.1":
- "integrity" "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
- "resolved" "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz"
- "version" "1.1.1"
-
-"array-from@^2.1.1":
- "integrity" "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg== sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg=="
- "resolved" "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz"
- "version" "2.1.1"
-
-"array-includes@^3.1.1":
- "integrity" "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ=="
- "resolved" "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz"
- "version" "3.1.1"
- dependencies:
- "define-properties" "^1.1.3"
- "es-abstract" "^1.17.0"
- "is-string" "^1.0.5"
-
-"array-unique@^0.3.2":
- "integrity" "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ=="
- "resolved" "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz"
- "version" "0.3.2"
-
-"array.prototype.find@^2.1.1":
- "integrity" "sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA=="
- "resolved" "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "define-properties" "^1.1.3"
- "es-abstract" "^1.17.4"
-
-"array.prototype.flat@^1.2.3":
- "integrity" "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ=="
- "resolved" "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz"
- "version" "1.2.3"
- dependencies:
- "define-properties" "^1.1.3"
- "es-abstract" "^1.17.0-next.1"
-
-"array.prototype.flatmap@^1.2.3":
- "integrity" "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg=="
- "resolved" "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz"
- "version" "1.2.3"
- dependencies:
- "define-properties" "^1.1.3"
- "es-abstract" "^1.17.0-next.1"
- "function-bind" "^1.1.1"
-
-"asn1.js@^4.0.0":
- "integrity" "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw=="
- "resolved" "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz"
- "version" "4.10.1"
- dependencies:
- "bn.js" "^4.0.0"
- "inherits" "^2.0.1"
- "minimalistic-assert" "^1.0.0"
-
-"assert@^1.1.1":
- "integrity" "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA=="
- "resolved" "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz"
- "version" "1.5.0"
- dependencies:
- "object-assign" "^4.1.1"
- "util" "0.10.3"
-
-"assertion-error@^1.1.0":
- "integrity" "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="
- "resolved" "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz"
- "version" "1.1.0"
-
-"assign-symbols@^1.0.0":
- "integrity" "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw=="
- "resolved" "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz"
- "version" "1.0.0"
-
-"ast-types-flow@^0.0.7":
- "integrity" "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag=="
- "resolved" "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz"
- "version" "0.0.7"
-
-"astral-regex@^1.0.0":
- "integrity" "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg=="
- "resolved" "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz"
- "version" "1.0.0"
-
-"async-each@^1.0.1":
- "integrity" "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ=="
- "resolved" "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz"
- "version" "1.0.3"
-
-"async-limiter@~1.0.0":
- "integrity" "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
- "resolved" "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz"
- "version" "1.0.1"
-
-"asynckit@^0.4.0":
- "integrity" "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
- "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
- "version" "0.4.0"
-
-"atob@^2.1.2":
- "integrity" "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
- "resolved" "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz"
- "version" "2.1.2"
-
-"available-typed-arrays@^1.0.5":
- "integrity" "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
- "resolved" "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz"
- "version" "1.0.5"
-
-"axe-core@^3.5.4":
- "integrity" "sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q=="
- "resolved" "https://registry.npmjs.org/axe-core/-/axe-core-3.5.5.tgz"
- "version" "3.5.5"
-
-"axobject-query@^2.1.2":
- "integrity" "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA=="
- "resolved" "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz"
- "version" "2.2.0"
-
-"babel-jest@^26.6.3":
- "integrity" "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA=="
- "resolved" "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@jest/transform" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/babel__core" "^7.1.7"
- "babel-plugin-istanbul" "^6.0.0"
- "babel-preset-jest" "^26.6.2"
- "chalk" "^4.0.0"
- "graceful-fs" "^4.2.4"
- "slash" "^3.0.0"
-
-"babel-loader@^8.1.0":
- "integrity" "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw=="
- "resolved" "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz"
- "version" "8.1.0"
- dependencies:
- "find-cache-dir" "^2.1.0"
- "loader-utils" "^1.4.0"
- "mkdirp" "^0.5.3"
- "pify" "^4.0.1"
- "schema-utils" "^2.6.5"
-
-"babel-plugin-dynamic-import-node@^2.3.3":
- "integrity" "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ=="
- "resolved" "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz"
- "version" "2.3.3"
- dependencies:
- "object.assign" "^4.1.0"
-
-"babel-plugin-emotion@^10.0.27":
- "integrity" "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ=="
- "resolved" "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz"
- "version" "10.0.33"
- dependencies:
- "@babel/helper-module-imports" "^7.0.0"
- "@emotion/hash" "0.8.0"
- "@emotion/memoize" "0.7.4"
- "@emotion/serialize" "^0.11.16"
- "babel-plugin-macros" "^2.0.0"
- "babel-plugin-syntax-jsx" "^6.18.0"
- "convert-source-map" "^1.5.0"
- "escape-string-regexp" "^1.0.5"
- "find-root" "^1.1.0"
- "source-map" "^0.5.7"
-
-"babel-plugin-istanbul@^6.0.0":
- "integrity" "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA=="
- "resolved" "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz"
- "version" "6.1.1"
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@istanbuljs/load-nyc-config" "^1.0.0"
- "@istanbuljs/schema" "^0.1.2"
- "istanbul-lib-instrument" "^5.0.4"
- "test-exclude" "^6.0.0"
-
-"babel-plugin-jest-hoist@^26.6.2":
- "integrity" "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw=="
- "resolved" "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@babel/template" "^7.3.3"
- "@babel/types" "^7.3.3"
- "@types/babel__core" "^7.0.0"
- "@types/babel__traverse" "^7.0.6"
-
-"babel-plugin-macros@^2.0.0", "babel-plugin-macros@^2.6.1":
- "integrity" "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg=="
- "resolved" "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz"
- "version" "2.8.0"
- dependencies:
- "@babel/runtime" "^7.7.2"
- "cosmiconfig" "^6.0.0"
- "resolve" "^1.12.0"
-
-"babel-plugin-polyfill-corejs2@^0.1.4":
- "integrity" "sha512-DO95wD4g0A8KRaHKi0D51NdGXzvpqVLnLu5BTvDlpqUEpTmeEtypgC1xqesORaWmiUOQI14UHKlzNd9iZ2G3ZA=="
- "resolved" "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.10.tgz"
- "version" "0.1.10"
- dependencies:
- "@babel/compat-data" "^7.13.0"
- "@babel/helper-define-polyfill-provider" "^0.1.5"
- "semver" "^6.1.1"
-
-"babel-plugin-polyfill-corejs3@^0.1.3":
- "integrity" "sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw=="
- "resolved" "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz"
- "version" "0.1.7"
- dependencies:
- "@babel/helper-define-polyfill-provider" "^0.1.5"
- "core-js-compat" "^3.8.1"
-
-"babel-plugin-polyfill-regenerator@^0.1.2":
- "integrity" "sha512-OUrYG9iKPKz8NxswXbRAdSwF0GhRdIEMTloQATJi4bDuFqrXaXcCUT/VGNrr8pBcjMh1RxZ7Xt9cytVJTJfvMg=="
- "resolved" "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.6.tgz"
- "version" "0.1.6"
- dependencies:
- "@babel/helper-define-polyfill-provider" "^0.1.5"
-
-"babel-plugin-syntax-jsx@^6.18.0":
- "integrity" "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw== sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw=="
- "resolved" "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz"
- "version" "6.18.0"
-
-"babel-plugin-transform-react-remove-prop-types@^0.4.24":
- "integrity" "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA=="
- "resolved" "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz"
- "version" "0.4.24"
-
-"babel-preset-airbnb@^5.0.0":
- "integrity" "sha512-Y5nqHhnhu4RpwbmQj4H+srdk1kb413pX81PfJsT1IZQOuEuRzUDXmgN4Ut1GgpQJnfRpjjEuQy0/uzcLMMP1cQ=="
- "resolved" "https://registry.npmjs.org/babel-preset-airbnb/-/babel-preset-airbnb-5.0.0.tgz"
- "version" "5.0.0"
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.3"
- "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3"
- "@babel/plugin-proposal-numeric-separator" "^7.8.3"
- "@babel/plugin-proposal-object-rest-spread" "^7.9.0"
- "@babel/plugin-proposal-optional-catch-binding" "^7.8.3"
- "@babel/plugin-proposal-optional-chaining" "^7.9.0"
- "@babel/plugin-transform-classes" "^7.9.2"
- "@babel/plugin-transform-exponentiation-operator" "^7.8.3"
- "@babel/plugin-transform-member-expression-literals" "^7.8.3"
- "@babel/plugin-transform-property-literals" "^7.8.3"
- "@babel/plugin-transform-property-mutators" "^7.8.3"
- "@babel/plugin-transform-runtime" "^7.9.0"
- "@babel/plugin-transform-template-literals" "^7.8.3"
- "@babel/preset-env" "^7.9.0"
- "@babel/preset-react" "^7.9.4"
- "babel-plugin-transform-react-remove-prop-types" "^0.4.24"
-
-"babel-preset-current-node-syntax@^1.0.0":
- "integrity" "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ=="
- "resolved" "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "@babel/plugin-syntax-async-generators" "^7.8.4"
- "@babel/plugin-syntax-bigint" "^7.8.3"
- "@babel/plugin-syntax-class-properties" "^7.8.3"
- "@babel/plugin-syntax-import-meta" "^7.8.3"
- "@babel/plugin-syntax-json-strings" "^7.8.3"
- "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
- "@babel/plugin-syntax-numeric-separator" "^7.8.3"
- "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
- "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
- "@babel/plugin-syntax-optional-chaining" "^7.8.3"
- "@babel/plugin-syntax-top-level-await" "^7.8.3"
-
-"babel-preset-jest@^26.6.2":
- "integrity" "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ=="
- "resolved" "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "babel-plugin-jest-hoist" "^26.6.2"
- "babel-preset-current-node-syntax" "^1.0.0"
-
-"babel-runtime@^6.26.0", "babel-runtime@^6.6.1", "babel-runtime@6.x":
- "integrity" "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g== sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g=="
- "resolved" "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz"
- "version" "6.26.0"
- dependencies:
- "core-js" "^2.4.0"
- "regenerator-runtime" "^0.11.0"
-
-"balanced-match@^0.4.2":
- "integrity" "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg== sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg=="
- "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz"
- "version" "0.4.2"
-
-"balanced-match@^1.0.0":
- "integrity" "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg== sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg=="
- "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz"
- "version" "1.0.0"
-
-"base@^0.11.1":
- "integrity" "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg=="
- "resolved" "https://registry.npmjs.org/base/-/base-0.11.2.tgz"
- "version" "0.11.2"
- dependencies:
- "cache-base" "^1.0.1"
- "class-utils" "^0.3.5"
- "component-emitter" "^1.2.1"
- "define-property" "^1.0.0"
- "isobject" "^3.0.1"
- "mixin-deep" "^1.2.0"
- "pascalcase" "^0.1.1"
-
-"base16@^1.0.0":
- "integrity" "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ== sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ=="
- "resolved" "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz"
- "version" "1.0.0"
-
-"base64-js@^1.0.2", "base64-js@^1.3.1":
- "integrity" "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
- "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz"
- "version" "1.3.1"
-
-"big.js@^5.2.2":
- "integrity" "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
- "resolved" "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz"
- "version" "5.2.2"
-
-"binary-extensions@^1.0.0":
- "integrity" "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw=="
- "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz"
- "version" "1.13.1"
-
-"binary-extensions@^2.0.0":
- "integrity" "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ=="
- "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz"
- "version" "2.1.0"
-
-"bl@^4.0.3":
- "integrity" "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="
- "resolved" "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz"
- "version" "4.1.0"
- dependencies:
- "buffer" "^5.5.0"
- "inherits" "^2.0.4"
- "readable-stream" "^3.4.0"
-
-"bluebird@^3.5.5":
- "integrity" "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
- "resolved" "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz"
- "version" "3.7.2"
-
-"bn.js@^4.0.0":
- "integrity" "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw=="
- "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz"
- "version" "4.11.9"
-
-"bn.js@^4.1.0":
- "integrity" "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw=="
- "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz"
- "version" "4.11.9"
-
-"bn.js@^4.11.9":
- "integrity" "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw=="
- "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz"
- "version" "4.11.9"
-
-"bn.js@^5.1.1":
- "integrity" "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
- "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz"
- "version" "5.1.2"
-
-"body-parser@1.20.1":
- "integrity" "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw=="
- "resolved" "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz"
- "version" "1.20.1"
- dependencies:
- "bytes" "3.1.2"
- "content-type" "~1.0.4"
- "debug" "2.6.9"
- "depd" "2.0.0"
- "destroy" "1.2.0"
- "http-errors" "2.0.0"
- "iconv-lite" "0.4.24"
- "on-finished" "2.4.1"
- "qs" "6.11.0"
- "raw-body" "2.5.1"
- "type-is" "~1.6.18"
- "unpipe" "1.0.0"
-
-"boolbase@^1.0.0":
- "integrity" "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
- "resolved" "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
- "version" "1.0.0"
-
-"brace-expansion@^1.1.7":
- "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="
- "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
- "version" "1.1.11"
- dependencies:
- "balanced-match" "^1.0.0"
- "concat-map" "0.0.1"
-
-"braces@^2.3.1", "braces@^2.3.2":
- "integrity" "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w=="
- "resolved" "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz"
- "version" "2.3.2"
- dependencies:
- "arr-flatten" "^1.1.0"
- "array-unique" "^0.3.2"
- "extend-shallow" "^2.0.1"
- "fill-range" "^4.0.0"
- "isobject" "^3.0.1"
- "repeat-element" "^1.1.2"
- "snapdragon" "^0.8.1"
- "snapdragon-node" "^2.0.1"
- "split-string" "^3.0.2"
- "to-regex" "^3.0.1"
-
-"braces@^3.0.2", "braces@~3.0.2":
- "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A=="
- "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
- "version" "3.0.2"
- dependencies:
- "fill-range" "^7.0.1"
-
-"brorand@^1.0.1", "brorand@^1.1.0":
- "integrity" "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w=="
- "resolved" "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz"
- "version" "1.1.0"
-
-"browser-process-hrtime@^1.0.0":
- "integrity" "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
- "resolved" "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz"
- "version" "1.0.0"
-
-"browserify-aes@^1.0.0", "browserify-aes@^1.0.4":
- "integrity" "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA=="
- "resolved" "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz"
- "version" "1.2.0"
- dependencies:
- "buffer-xor" "^1.0.3"
- "cipher-base" "^1.0.0"
- "create-hash" "^1.1.0"
- "evp_bytestokey" "^1.0.3"
- "inherits" "^2.0.1"
- "safe-buffer" "^5.0.1"
-
-"browserify-cipher@^1.0.0":
- "integrity" "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w=="
- "resolved" "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "browserify-aes" "^1.0.4"
- "browserify-des" "^1.0.0"
- "evp_bytestokey" "^1.0.0"
-
-"browserify-des@^1.0.0":
- "integrity" "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A=="
- "resolved" "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "cipher-base" "^1.0.1"
- "des.js" "^1.0.0"
- "inherits" "^2.0.1"
- "safe-buffer" "^5.1.2"
-
-"browserify-rsa@^4.0.0", "browserify-rsa@^4.0.1":
- "integrity" "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw==sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw==sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw==sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw==sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw==sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw==sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw== sha512-+YpEyaLDDvvdzIxQ+cCx73r5YEhS3ANGOkiHdyWqW4t3gdeoNEYjSiQwntbU4Uo2/9yRkpYX3SRFeH+7jc2Duw=="
- "resolved" "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz"
- "version" "4.0.1"
- dependencies:
- "bn.js" "^4.1.0"
- "randombytes" "^2.0.1"
-
-"browserify-sign@^4.0.0":
- "integrity" "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA=="
- "resolved" "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz"
- "version" "4.2.0"
- dependencies:
- "bn.js" "^5.1.1"
- "browserify-rsa" "^4.0.1"
- "create-hash" "^1.2.0"
- "create-hmac" "^1.1.7"
- "elliptic" "^6.5.2"
- "inherits" "^2.0.4"
- "parse-asn1" "^5.1.5"
- "readable-stream" "^3.6.0"
- "safe-buffer" "^5.2.0"
-
-"browserify-zlib@^0.2.0":
- "integrity" "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA=="
- "resolved" "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz"
- "version" "0.2.0"
- dependencies:
- "pako" "~1.0.5"
-
-"browserslist@^4.14.5", "browserslist@^4.16.3", "browserslist@>= 4.21.0":
- "integrity" "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw=="
- "resolved" "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz"
- "version" "4.21.4"
- dependencies:
- "caniuse-lite" "^1.0.30001400"
- "electron-to-chromium" "^1.4.251"
- "node-releases" "^2.0.6"
- "update-browserslist-db" "^1.0.9"
-
-"bs-logger@0.x":
- "integrity" "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog=="
- "resolved" "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz"
- "version" "0.2.6"
- dependencies:
- "fast-json-stable-stringify" "2.x"
-
-"bser@2.1.1":
- "integrity" "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="
- "resolved" "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "node-int64" "^0.4.0"
-
-"buffer-crc32@~0.2.3":
- "integrity" "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="
- "resolved" "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz"
- "version" "0.2.13"
-
-"buffer-from@^1.0.0", "buffer-from@1.x":
- "integrity" "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
- "resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz"
- "version" "1.1.1"
-
-"buffer-xor@^1.0.3":
- "integrity" "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ=="
- "resolved" "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz"
- "version" "1.0.3"
-
-"buffer@^4.3.0":
- "integrity" "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg=="
- "resolved" "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz"
- "version" "4.9.2"
- dependencies:
- "base64-js" "^1.0.2"
- "ieee754" "^1.1.4"
- "isarray" "^1.0.0"
-
-"buffer@^5.2.1", "buffer@^5.5.0":
- "integrity" "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="
- "resolved" "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz"
- "version" "5.7.1"
- dependencies:
- "base64-js" "^1.3.1"
- "ieee754" "^1.1.13"
-
-"builtin-status-codes@^3.0.0":
- "integrity" "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ=="
- "resolved" "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz"
- "version" "3.0.0"
-
-"bytes@3.1.2":
- "integrity" "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
- "resolved" "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz"
- "version" "3.1.2"
-
-"cacache@^12.0.2":
- "integrity" "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ=="
- "resolved" "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz"
- "version" "12.0.4"
- dependencies:
- "bluebird" "^3.5.5"
- "chownr" "^1.1.1"
- "figgy-pudding" "^3.5.1"
- "glob" "^7.1.4"
- "graceful-fs" "^4.1.15"
- "infer-owner" "^1.0.3"
- "lru-cache" "^5.1.1"
- "mississippi" "^3.0.0"
- "mkdirp" "^0.5.1"
- "move-concurrently" "^1.0.1"
- "promise-inflight" "^1.0.1"
- "rimraf" "^2.6.3"
- "ssri" "^6.0.1"
- "unique-filename" "^1.1.1"
- "y18n" "^4.0.0"
-
-"cache-base@^1.0.1":
- "integrity" "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ=="
- "resolved" "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "collection-visit" "^1.0.0"
- "component-emitter" "^1.2.1"
- "get-value" "^2.0.6"
- "has-value" "^1.0.0"
- "isobject" "^3.0.1"
- "set-value" "^2.0.0"
- "to-object-path" "^0.3.0"
- "union-value" "^1.0.0"
- "unset-value" "^1.0.0"
-
-"call-bind@^1.0.0", "call-bind@^1.0.2":
- "integrity" "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA=="
- "resolved" "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "function-bind" "^1.1.1"
- "get-intrinsic" "^1.0.2"
-
-"caller-callsite@^2.0.0":
- "integrity" "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ== sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ=="
- "resolved" "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "callsites" "^2.0.0"
-
-"caller-path@^2.0.0":
- "integrity" "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A== sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A=="
- "resolved" "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "caller-callsite" "^2.0.0"
-
-"callsites@^2.0.0":
- "integrity" "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ== sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ=="
- "resolved" "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz"
- "version" "2.0.0"
-
-"callsites@^3.0.0":
- "integrity" "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
- "resolved" "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
- "version" "3.1.0"
-
-"camelcase@^5.0.0", "camelcase@^5.3.1":
- "integrity" "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
- "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz"
- "version" "5.3.1"
-
-"camelcase@^6.0.0":
- "integrity" "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
- "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz"
- "version" "6.3.0"
-
-"caniuse-lite@^1.0.30001400":
- "integrity" "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg=="
- "resolved" "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz"
- "version" "1.0.30001414"
-
-"capture-exit@^2.0.0":
- "integrity" "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g=="
- "resolved" "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "rsvp" "^4.8.4"
-
-"chai@^4.2.0":
- "integrity" "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA=="
- "resolved" "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz"
- "version" "4.3.4"
- dependencies:
- "assertion-error" "^1.1.0"
- "check-error" "^1.0.2"
- "deep-eql" "^3.0.1"
- "get-func-name" "^2.0.0"
- "pathval" "^1.1.1"
- "type-detect" "^4.0.5"
-
-"chalk@^2.0.0", "chalk@^2.0.1", "chalk@^2.1.0", "chalk@^2.3.0", "chalk@^2.4.1", "chalk@^2.4.2":
- "integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="
- "resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
- "version" "2.4.2"
- dependencies:
- "ansi-styles" "^3.2.1"
- "escape-string-regexp" "^1.0.5"
- "supports-color" "^5.3.0"
-
-"chalk@^3.0.0":
- "integrity" "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="
- "resolved" "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "ansi-styles" "^4.1.0"
- "supports-color" "^7.1.0"
-
-"chalk@^4.0.0":
- "integrity" "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A=="
- "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz"
- "version" "4.1.0"
- dependencies:
- "ansi-styles" "^4.1.0"
- "supports-color" "^7.1.0"
-
-"chalk@^4.1.0":
- "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="
- "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
- "version" "4.1.2"
- dependencies:
- "ansi-styles" "^4.1.0"
- "supports-color" "^7.1.0"
-
-"char-regex@^1.0.2":
- "integrity" "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="
- "resolved" "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz"
- "version" "1.0.2"
-
-"chardet@^0.7.0":
- "integrity" "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
- "resolved" "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz"
- "version" "0.7.0"
-
-"check-error@^1.0.2":
- "integrity" "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA=="
- "resolved" "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz"
- "version" "1.0.2"
-
-"cheerio-select@^2.1.0":
- "integrity" "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="
- "resolved" "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "boolbase" "^1.0.0"
- "css-select" "^5.1.0"
- "css-what" "^6.1.0"
- "domelementtype" "^2.3.0"
- "domhandler" "^5.0.3"
- "domutils" "^3.0.1"
-
-"cheerio@^1.0.0-rc.3":
- "integrity" "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q=="
- "resolved" "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz"
- "version" "1.0.0-rc.12"
- dependencies:
- "cheerio-select" "^2.1.0"
- "dom-serializer" "^2.0.0"
- "domhandler" "^5.0.3"
- "domutils" "^3.0.1"
- "htmlparser2" "^8.0.1"
- "parse5" "^7.0.0"
- "parse5-htmlparser2-tree-adapter" "^7.0.0"
-
-"chokidar@^2.1.8":
- "integrity" "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg=="
- "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz"
- "version" "2.1.8"
- dependencies:
- "anymatch" "^2.0.0"
- "async-each" "^1.0.1"
- "braces" "^2.3.2"
- "glob-parent" "^3.1.0"
- "inherits" "^2.0.3"
- "is-binary-path" "^1.0.0"
- "is-glob" "^4.0.0"
- "normalize-path" "^3.0.0"
- "path-is-absolute" "^1.0.0"
- "readdirp" "^2.2.1"
- "upath" "^1.1.1"
- optionalDependencies:
- "fsevents" "^1.2.7"
-
-"chokidar@^3.4.0", "chokidar@>=2.0.0 <4.0.0":
- "integrity" "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ=="
- "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz"
- "version" "3.4.0"
- dependencies:
- "anymatch" "~3.1.1"
- "braces" "~3.0.2"
- "glob-parent" "~5.1.0"
- "is-binary-path" "~2.1.0"
- "is-glob" "~4.0.1"
- "normalize-path" "~3.0.0"
- "readdirp" "~3.4.0"
- optionalDependencies:
- "fsevents" "~2.1.2"
-
-"chownr@^1.1.1":
- "integrity" "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
- "resolved" "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz"
- "version" "1.1.4"
-
-"chrome-trace-event@^1.0.2":
- "integrity" "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ=="
- "resolved" "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "tslib" "^1.9.0"
-
-"ci-info@^2.0.0":
- "integrity" "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
- "resolved" "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz"
- "version" "2.0.0"
-
-"cipher-base@^1.0.0", "cipher-base@^1.0.1", "cipher-base@^1.0.3":
- "integrity" "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q=="
- "resolved" "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "inherits" "^2.0.1"
- "safe-buffer" "^5.0.1"
-
-"cjs-module-lexer@^0.6.0":
- "integrity" "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw=="
- "resolved" "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz"
- "version" "0.6.0"
-
-"class-utils@^0.3.5":
- "integrity" "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg=="
- "resolved" "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz"
- "version" "0.3.6"
- dependencies:
- "arr-union" "^3.1.0"
- "define-property" "^0.2.5"
- "isobject" "^3.0.0"
- "static-extend" "^0.1.1"
-
-"classnames@^2.2.5", "classnames@^2.2.6", "classnames@^2.3.1":
- "integrity" "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
- "resolved" "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz"
- "version" "2.3.2"
-
-"cli-cursor@^3.1.0":
- "integrity" "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="
- "resolved" "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "restore-cursor" "^3.1.0"
-
-"cli-width@^3.0.0":
- "integrity" "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw=="
- "resolved" "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz"
- "version" "3.0.0"
-
-"cliui@^5.0.0":
- "integrity" "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA=="
- "resolved" "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz"
- "version" "5.0.0"
- dependencies:
- "string-width" "^3.1.0"
- "strip-ansi" "^5.2.0"
- "wrap-ansi" "^5.1.0"
-
-"cliui@^6.0.0":
- "integrity" "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="
- "resolved" "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz"
- "version" "6.0.0"
- dependencies:
- "string-width" "^4.2.0"
- "strip-ansi" "^6.0.0"
- "wrap-ansi" "^6.2.0"
-
-"clone-deep@^4.0.1":
- "integrity" "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ=="
- "resolved" "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz"
- "version" "4.0.1"
- dependencies:
- "is-plain-object" "^2.0.4"
- "kind-of" "^6.0.2"
- "shallow-clone" "^3.0.0"
-
-"clsx@^1.0.4", "clsx@^1.1.1":
- "integrity" "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
- "resolved" "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz"
- "version" "1.1.1"
-
-"co@^4.6.0":
- "integrity" "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ=="
- "resolved" "https://registry.npmjs.org/co/-/co-4.6.0.tgz"
- "version" "4.6.0"
-
-"collect-v8-coverage@^1.0.0":
- "integrity" "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg=="
- "resolved" "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz"
- "version" "1.0.1"
-
-"collection-visit@^1.0.0":
- "integrity" "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw=="
- "resolved" "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "map-visit" "^1.0.0"
- "object-visit" "^1.0.0"
-
-"color-convert@^1.9.0":
- "integrity" "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="
- "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
- "version" "1.9.3"
- dependencies:
- "color-name" "1.1.3"
-
-"color-convert@^2.0.1":
- "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="
- "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "color-name" "~1.1.4"
-
-"color-name@~1.1.4":
- "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
- "version" "1.1.4"
-
-"color-name@1.1.3":
- "integrity" "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
- "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
- "version" "1.1.3"
-
-"colors@^1.1.2":
- "integrity" "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
- "resolved" "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz"
- "version" "1.4.0"
-
-"combined-stream@^1.0.8":
- "integrity" "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="
- "resolved" "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
- "version" "1.0.8"
- dependencies:
- "delayed-stream" "~1.0.0"
-
-"commander@^2.19.0":
- "integrity" "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
- "resolved" "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
- "version" "2.20.3"
-
-"commander@^2.20.0":
- "integrity" "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
- "resolved" "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
- "version" "2.20.3"
-
-"commander@7":
- "integrity" "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
- "resolved" "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz"
- "version" "7.2.0"
-
-"commondir@^1.0.1":
- "integrity" "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
- "resolved" "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz"
- "version" "1.0.1"
-
-"component-classes@^1.2.5":
- "integrity" "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA== sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA=="
- "resolved" "https://registry.npmjs.org/component-classes/-/component-classes-1.2.6.tgz"
- "version" "1.2.6"
- dependencies:
- "component-indexof" "0.0.3"
-
-"component-emitter@^1.2.1":
- "integrity" "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
- "resolved" "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz"
- "version" "1.3.0"
-
-"component-indexof@0.0.3":
- "integrity" "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ=sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw== sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw=="
- "resolved" "https://registry.npmjs.org/component-indexof/-/component-indexof-0.0.3.tgz"
- "version" "0.0.3"
-
-"concat-map@0.0.1":
- "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
- "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
- "version" "0.0.1"
-
-"concat-stream@^1.5.0":
- "integrity" "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw=="
- "resolved" "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz"
- "version" "1.6.2"
- dependencies:
- "buffer-from" "^1.0.0"
- "inherits" "^2.0.3"
- "readable-stream" "^2.2.2"
- "typedarray" "^0.0.6"
-
-"confusing-browser-globals@^1.0.9":
- "integrity" "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw=="
- "resolved" "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz"
- "version" "1.0.9"
-
-"console-browserify@^1.1.0":
- "integrity" "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="
- "resolved" "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz"
- "version" "1.2.0"
-
-"constants-browserify@^1.0.0":
- "integrity" "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ=="
- "resolved" "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz"
- "version" "1.0.0"
-
-"contains-path@^0.1.0":
- "integrity" "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg== sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg=="
- "resolved" "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz"
- "version" "0.1.0"
-
-"content-disposition@0.5.4":
- "integrity" "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="
- "resolved" "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz"
- "version" "0.5.4"
- dependencies:
- "safe-buffer" "5.2.1"
-
-"content-type@~1.0.4":
- "integrity" "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
- "resolved" "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz"
- "version" "1.0.4"
-
-"convert-source-map@^1.4.0", "convert-source-map@^1.5.0", "convert-source-map@^1.6.0", "convert-source-map@^1.7.0":
- "integrity" "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA=="
- "resolved" "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "safe-buffer" "~5.1.1"
-
-"cookie-signature@1.0.6":
- "integrity" "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
- "resolved" "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
- "version" "1.0.6"
-
-"cookie@0.5.0":
- "integrity" "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
- "resolved" "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz"
- "version" "0.5.0"
-
-"copy-concurrently@^1.0.0":
- "integrity" "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A=="
- "resolved" "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz"
- "version" "1.0.5"
- dependencies:
- "aproba" "^1.1.1"
- "fs-write-stream-atomic" "^1.0.8"
- "iferr" "^0.1.5"
- "mkdirp" "^0.5.1"
- "rimraf" "^2.5.4"
- "run-queue" "^1.0.0"
-
-"copy-descriptor@^0.1.0":
- "integrity" "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw=="
- "resolved" "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz"
- "version" "0.1.1"
-
-"core-js-compat@^3.8.1", "core-js-compat@^3.9.0":
- "integrity" "sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA=="
- "resolved" "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.9.1.tgz"
- "version" "3.9.1"
- dependencies:
- "browserslist" "^4.16.3"
- "semver" "7.0.0"
-
-"core-js-pure@^3.0.0":
- "integrity" "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA=="
- "resolved" "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz"
- "version" "3.6.5"
-
-"core-js@^2.4.0":
- "integrity" "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
- "resolved" "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz"
- "version" "2.6.11"
-
-"core-js@^3.6.5":
- "integrity" "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
- "resolved" "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz"
- "version" "3.6.5"
-
-"core-util-is@~1.0.0":
- "integrity" "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
- "resolved" "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
- "version" "1.0.2"
-
-"cosmiconfig@^5.0.0":
- "integrity" "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA=="
- "resolved" "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz"
- "version" "5.2.1"
- dependencies:
- "import-fresh" "^2.0.0"
- "is-directory" "^0.3.1"
- "js-yaml" "^3.13.1"
- "parse-json" "^4.0.0"
-
-"cosmiconfig@^6.0.0":
- "integrity" "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg=="
- "resolved" "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz"
- "version" "6.0.0"
- dependencies:
- "@types/parse-json" "^4.0.0"
- "import-fresh" "^3.1.0"
- "parse-json" "^5.0.0"
- "path-type" "^4.0.0"
- "yaml" "^1.7.2"
-
-"create-ecdh@^4.0.0":
- "integrity" "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw=="
- "resolved" "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz"
- "version" "4.0.3"
- dependencies:
- "bn.js" "^4.1.0"
- "elliptic" "^6.0.0"
-
-"create-hash@^1.1.0", "create-hash@^1.1.2", "create-hash@^1.2.0":
- "integrity" "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg=="
- "resolved" "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz"
- "version" "1.2.0"
- dependencies:
- "cipher-base" "^1.0.1"
- "inherits" "^2.0.1"
- "md5.js" "^1.3.4"
- "ripemd160" "^2.0.1"
- "sha.js" "^2.4.0"
-
-"create-hmac@^1.1.0", "create-hmac@^1.1.4", "create-hmac@^1.1.7":
- "integrity" "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg=="
- "resolved" "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz"
- "version" "1.1.7"
- dependencies:
- "cipher-base" "^1.0.3"
- "create-hash" "^1.1.0"
- "inherits" "^2.0.1"
- "ripemd160" "^2.0.0"
- "safe-buffer" "^5.0.1"
- "sha.js" "^2.4.8"
-
-"create-jest-runner@^0.5.3":
- "integrity" "sha512-a9VY2doMBmzRollJB3Ft3/Y5fBceSWJ4gdyVsg4/d7nP1S4715VG939s2VnITDj79YBmRgKhjGjNRv1c+Kre1g=="
- "resolved" "https://registry.npmjs.org/create-jest-runner/-/create-jest-runner-0.5.3.tgz"
- "version" "0.5.3"
- dependencies:
- "chalk" "^2.4.2"
- "jest-worker" "^24.0.0"
- "throat" "^4.1.0"
-
-"create-require@^1.1.0":
- "integrity" "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
- "resolved" "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz"
- "version" "1.1.1"
-
-"cross-fetch@3.1.5":
- "integrity" "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw=="
- "resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz"
- "version" "3.1.5"
- dependencies:
- "node-fetch" "2.6.7"
-
-"cross-spawn@^6.0.0", "cross-spawn@^6.0.5":
- "integrity" "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ=="
- "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz"
- "version" "6.0.5"
- dependencies:
- "nice-try" "^1.0.4"
- "path-key" "^2.0.1"
- "semver" "^5.5.0"
- "shebang-command" "^1.2.0"
- "which" "^1.2.9"
-
-"cross-spawn@^7.0.0":
- "integrity" "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="
- "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
- "version" "7.0.3"
- dependencies:
- "path-key" "^3.1.0"
- "shebang-command" "^2.0.0"
- "which" "^2.0.1"
-
-"crypto-browserify@^3.11.0":
- "integrity" "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg=="
- "resolved" "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz"
- "version" "3.12.0"
- dependencies:
- "browserify-cipher" "^1.0.0"
- "browserify-sign" "^4.0.0"
- "create-ecdh" "^4.0.0"
- "create-hash" "^1.1.0"
- "create-hmac" "^1.1.0"
- "diffie-hellman" "^5.0.0"
- "inherits" "^2.0.1"
- "pbkdf2" "^3.0.3"
- "public-encrypt" "^4.0.0"
- "randombytes" "^2.0.0"
- "randomfill" "^1.0.3"
-
-"css-animation@^1.3.2":
- "integrity" "sha512-/48+/BaEaHRY6kNQ2OIPzKf9A6g8WjZYjhiNDNuIVbsm5tXCGIAsHDjB4Xu1C4vXJtUWZo26O68OQkDpNBaPog=="
- "resolved" "https://registry.npmjs.org/css-animation/-/css-animation-1.6.1.tgz"
- "version" "1.6.1"
- dependencies:
- "babel-runtime" "6.x"
- "component-classes" "^1.2.5"
-
-"css-loader@^3.6.0":
- "integrity" "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ=="
- "resolved" "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz"
- "version" "3.6.0"
- dependencies:
- "camelcase" "^5.3.1"
- "cssesc" "^3.0.0"
- "icss-utils" "^4.1.1"
- "loader-utils" "^1.2.3"
- "normalize-path" "^3.0.0"
- "postcss" "^7.0.32"
- "postcss-modules-extract-imports" "^2.0.0"
- "postcss-modules-local-by-default" "^3.0.2"
- "postcss-modules-scope" "^2.2.0"
- "postcss-modules-values" "^3.0.0"
- "postcss-value-parser" "^4.1.0"
- "schema-utils" "^2.7.0"
- "semver" "^6.3.0"
-
-"css-select@^5.1.0":
- "integrity" "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="
- "resolved" "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz"
- "version" "5.1.0"
- dependencies:
- "boolbase" "^1.0.0"
- "css-what" "^6.1.0"
- "domhandler" "^5.0.2"
- "domutils" "^3.0.1"
- "nth-check" "^2.0.1"
-
-"css-vendor@^2.0.8":
- "integrity" "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ=="
- "resolved" "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz"
- "version" "2.0.8"
- dependencies:
- "@babel/runtime" "^7.8.3"
- "is-in-browser" "^1.0.2"
-
-"css-what@^6.1.0":
- "integrity" "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
- "resolved" "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz"
- "version" "6.1.0"
-
-"css.escape@^1.5.1":
- "integrity" "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="
- "resolved" "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz"
- "version" "1.5.1"
-
-"css@^2.2.3":
- "integrity" "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw=="
- "resolved" "https://registry.npmjs.org/css/-/css-2.2.4.tgz"
- "version" "2.2.4"
- dependencies:
- "inherits" "^2.0.3"
- "source-map" "^0.6.1"
- "source-map-resolve" "^0.5.2"
- "urix" "^0.1.0"
-
-"cssesc@^3.0.0":
- "integrity" "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="
- "resolved" "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
- "version" "3.0.0"
-
-"cssom@^0.4.4":
- "integrity" "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw=="
- "resolved" "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz"
- "version" "0.4.4"
-
-"cssom@~0.3.6":
- "integrity" "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
- "resolved" "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz"
- "version" "0.3.8"
-
-"cssstyle@^2.3.0":
- "integrity" "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A=="
- "resolved" "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz"
- "version" "2.3.0"
- dependencies:
- "cssom" "~0.3.6"
-
-"csstype@^2.5.2":
- "integrity" "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
- "resolved" "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz"
- "version" "2.6.16"
-
-"csstype@^2.5.7":
- "integrity" "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
- "resolved" "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz"
- "version" "2.6.16"
-
-"csstype@^2.6.7":
- "integrity" "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
- "resolved" "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz"
- "version" "2.6.16"
-
-"csstype@^3.0.2", "csstype@^3.1.0":
- "integrity" "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
- "resolved" "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz"
- "version" "3.1.0"
-
-"cyclist@^1.0.1":
- "integrity" "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A== sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A=="
- "resolved" "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz"
- "version" "1.0.1"
-
-"d3-array@^2.3.0":
- "integrity" "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="
- "resolved" "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz"
- "version" "2.12.1"
- dependencies:
- "internmap" "^1.0.0"
-
-"d3-array@^3.2.0", "d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", "d3-array@3":
- "integrity" "sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g=="
- "resolved" "https://registry.npmjs.org/d3-array/-/d3-array-3.2.0.tgz"
- "version" "3.2.0"
- dependencies:
- "internmap" "1 - 2"
-
-"d3-array@2":
- "integrity" "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="
- "resolved" "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz"
- "version" "2.12.1"
- dependencies:
- "internmap" "^1.0.0"
-
-"d3-axis@3":
- "integrity" "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw=="
- "resolved" "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz"
- "version" "3.0.0"
-
-"d3-brush@3":
- "integrity" "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ=="
- "resolved" "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "d3-dispatch" "1 - 3"
- "d3-drag" "2 - 3"
- "d3-interpolate" "1 - 3"
- "d3-selection" "3"
- "d3-transition" "3"
-
-"d3-chord@3":
- "integrity" "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g=="
- "resolved" "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "d3-path" "1 - 3"
-
-"d3-color@1 - 3", "d3-color@3":
- "integrity" "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="
- "resolved" "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz"
- "version" "3.1.0"
-
-"d3-color@1":
- "integrity" "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
- "resolved" "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz"
- "version" "1.4.1"
-
-"d3-contour@4":
- "integrity" "sha512-7aQo0QHUTu/Ko3cP9YK9yUTxtoDEiDGwnBHyLxG5M4vqlBkO/uixMRele3nfsfj6UXOcuReVpVXzAboGraYIJw=="
- "resolved" "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.0.tgz"
- "version" "4.0.0"
- dependencies:
- "d3-array" "^3.2.0"
-
-"d3-delaunay@6":
- "integrity" "sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ=="
- "resolved" "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.2.tgz"
- "version" "6.0.2"
- dependencies:
- "delaunator" "5"
-
-"d3-dispatch@1 - 3", "d3-dispatch@3":
- "integrity" "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="
- "resolved" "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz"
- "version" "3.0.1"
-
-"d3-drag@2 - 3", "d3-drag@3":
- "integrity" "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg=="
- "resolved" "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "d3-dispatch" "1 - 3"
- "d3-selection" "3"
-
-"d3-dsv@1 - 3", "d3-dsv@3":
- "integrity" "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q=="
- "resolved" "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "commander" "7"
- "iconv-lite" "0.6"
- "rw" "1"
-
-"d3-ease@1 - 3", "d3-ease@3":
- "integrity" "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="
- "resolved" "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz"
- "version" "3.0.1"
-
-"d3-fetch@3":
- "integrity" "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw=="
- "resolved" "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "d3-dsv" "1 - 3"
-
-"d3-force@3":
- "integrity" "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg=="
- "resolved" "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "d3-dispatch" "1 - 3"
- "d3-quadtree" "1 - 3"
- "d3-timer" "1 - 3"
-
-"d3-format@1 - 2":
- "integrity" "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
- "resolved" "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz"
- "version" "2.0.0"
-
-"d3-format@1 - 3", "d3-format@3":
- "integrity" "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="
- "resolved" "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz"
- "version" "3.1.0"
-
-"d3-geo@3":
- "integrity" "sha512-Wt23xBych5tSy9IYAM1FR2rWIBFWa52B/oF/GYe5zbdHrg08FU8+BuI6X4PvTwPDdqdAdq04fuWJpELtsaEjeA=="
- "resolved" "https://registry.npmjs.org/d3-geo/-/d3-geo-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "d3-array" "2.5.0 - 3"
-
-"d3-hierarchy@^1.1.4":
- "integrity" "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ=="
- "resolved" "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz"
- "version" "1.1.9"
-
-"d3-hierarchy@3":
- "integrity" "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA=="
- "resolved" "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz"
- "version" "3.1.2"
-
-"d3-interpolate@^1.4.0", "d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 2":
- "integrity" "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA=="
- "resolved" "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz"
- "version" "1.4.0"
- dependencies:
- "d3-color" "1"
-
-"d3-interpolate@1.2.0 - 3", "d3-interpolate@3":
- "integrity" "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="
- "resolved" "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "d3-color" "1 - 3"
-
-"d3-path@^1.0.5", "d3-path@1", "d3-path@1 - 2", "d3-path@1 - 3":
- "integrity" "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
- "resolved" "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz"
- "version" "1.0.9"
-
-"d3-path@3":
- "integrity" "sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w=="
- "resolved" "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz"
- "version" "3.0.1"
-
-"d3-polygon@3":
- "integrity" "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg=="
- "resolved" "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz"
- "version" "3.0.1"
-
-"d3-quadtree@1 - 3", "d3-quadtree@3":
- "integrity" "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw=="
- "resolved" "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz"
- "version" "3.0.1"
-
-"d3-random@3":
- "integrity" "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ=="
- "resolved" "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz"
- "version" "3.0.1"
-
-"d3-scale-chromatic@^3.0.0", "d3-scale-chromatic@3":
- "integrity" "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g=="
- "resolved" "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "d3-color" "1 - 3"
- "d3-interpolate" "1 - 3"
-
-"d3-scale@^3.3.0":
- "integrity" "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ=="
- "resolved" "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz"
- "version" "3.3.0"
- dependencies:
- "d3-array" "^2.3.0"
- "d3-format" "1 - 2"
- "d3-interpolate" "1.2.0 - 2"
- "d3-time" "^2.1.1"
- "d3-time-format" "2 - 3"
-
-"d3-scale@4":
- "integrity" "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="
- "resolved" "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz"
- "version" "4.0.2"
- dependencies:
- "d3-array" "2.10.0 - 3"
- "d3-format" "1 - 3"
- "d3-interpolate" "1.2.0 - 3"
- "d3-time" "2.1.1 - 3"
- "d3-time-format" "2 - 4"
-
-"d3-selection@2 - 3", "d3-selection@3":
- "integrity" "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="
- "resolved" "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz"
- "version" "3.0.0"
-
-"d3-shape@^1.0.6":
- "integrity" "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="
- "resolved" "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz"
- "version" "1.3.7"
- dependencies:
- "d3-path" "1"
-
-"d3-shape@^1.2.0":
- "integrity" "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="
- "resolved" "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz"
- "version" "1.3.7"
- dependencies:
- "d3-path" "1"
-
-"d3-shape@^2.0.0":
- "integrity" "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA=="
- "resolved" "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "d3-path" "1 - 2"
-
-"d3-shape@3":
- "integrity" "sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ=="
- "resolved" "https://registry.npmjs.org/d3-shape/-/d3-shape-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "d3-path" "1 - 3"
-
-"d3-time-format@2 - 3":
- "integrity" "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag=="
- "resolved" "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "d3-time" "1 - 2"
-
-"d3-time-format@2 - 4", "d3-time-format@4":
- "integrity" "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="
- "resolved" "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz"
- "version" "4.1.0"
- dependencies:
- "d3-time" "1 - 3"
-
-"d3-time@^2.1.1", "d3-time@1 - 2", "d3-time@1 - 3":
- "integrity" "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ=="
- "resolved" "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "d3-array" "2"
-
-"d3-time@2.1.1 - 3", "d3-time@3":
- "integrity" "sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ=="
- "resolved" "https://registry.npmjs.org/d3-time/-/d3-time-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "d3-array" "2 - 3"
-
-"d3-timer@1 - 3", "d3-timer@3":
- "integrity" "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="
- "resolved" "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz"
- "version" "3.0.1"
-
-"d3-transition@2 - 3", "d3-transition@3":
- "integrity" "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w=="
- "resolved" "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "d3-color" "1 - 3"
- "d3-dispatch" "1 - 3"
- "d3-ease" "1 - 3"
- "d3-interpolate" "1 - 3"
- "d3-timer" "1 - 3"
-
-"d3-zoom@^3.0.0", "d3-zoom@3":
- "integrity" "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="
- "resolved" "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "d3-dispatch" "1 - 3"
- "d3-drag" "2 - 3"
- "d3-interpolate" "1 - 3"
- "d3-selection" "2 - 3"
- "d3-transition" "2 - 3"
-
-"d3@^7.6.1":
- "integrity" "sha512-txMTdIHFbcpLx+8a0IFhZsbp+PfBBPt8yfbmukZTQFroKuFqIwqswF0qE5JXWefylaAVpSXFoKm3yP+jpNLFLw=="
- "resolved" "https://registry.npmjs.org/d3/-/d3-7.6.1.tgz"
- "version" "7.6.1"
- dependencies:
- "d3-array" "3"
- "d3-axis" "3"
- "d3-brush" "3"
- "d3-chord" "3"
- "d3-color" "3"
- "d3-contour" "4"
- "d3-delaunay" "6"
- "d3-dispatch" "3"
- "d3-drag" "3"
- "d3-dsv" "3"
- "d3-ease" "3"
- "d3-fetch" "3"
- "d3-force" "3"
- "d3-format" "3"
- "d3-geo" "3"
- "d3-hierarchy" "3"
- "d3-interpolate" "3"
- "d3-path" "3"
- "d3-polygon" "3"
- "d3-quadtree" "3"
- "d3-random" "3"
- "d3-scale" "4"
- "d3-scale-chromatic" "3"
- "d3-selection" "3"
- "d3-shape" "3"
- "d3-time" "3"
- "d3-time-format" "4"
- "d3-timer" "3"
- "d3-transition" "3"
- "d3-zoom" "3"
-
-"damerau-levenshtein@^1.0.6":
- "integrity" "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug=="
- "resolved" "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz"
- "version" "1.0.6"
-
-"data-urls@^2.0.0":
- "integrity" "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ=="
- "resolved" "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "abab" "^2.0.3"
- "whatwg-mimetype" "^2.3.0"
- "whatwg-url" "^8.0.0"
-
-"debounce@^1.2.0":
- "integrity" "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
- "resolved" "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz"
- "version" "1.2.1"
-
-"debug@^2.2.0":
- "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
- "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
- "version" "2.6.9"
- dependencies:
- "ms" "2.0.0"
-
-"debug@^2.3.3":
- "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
- "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
- "version" "2.6.9"
- dependencies:
- "ms" "2.0.0"
-
-"debug@^2.6.9":
- "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
- "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
- "version" "2.6.9"
- dependencies:
- "ms" "2.0.0"
-
-"debug@^4.0.1", "debug@^4.1.0", "debug@^4.1.1", "debug@4", "debug@4.3.4":
- "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="
- "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
- "version" "4.3.4"
- dependencies:
- "ms" "2.1.2"
-
-"debug@2.6.9":
- "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
- "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
- "version" "2.6.9"
- dependencies:
- "ms" "2.0.0"
-
-"decamelize@^1.2.0":
- "integrity" "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
- "resolved" "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
- "version" "1.2.0"
-
-"decimal.js@^10.2.1":
- "integrity" "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ=="
- "resolved" "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz"
- "version" "10.3.1"
-
-"decode-uri-component@^0.2.0":
- "integrity" "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="
- "resolved" "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz"
- "version" "0.2.2"
-
-"deep-eql@^3.0.1":
- "integrity" "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw=="
- "resolved" "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "type-detect" "^4.0.0"
-
-"deep-equal@^2.0.5":
- "integrity" "sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA=="
- "resolved" "https://registry.npmjs.org/deep-equal/-/deep-equal-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "call-bind" "^1.0.2"
- "es-get-iterator" "^1.1.2"
- "get-intrinsic" "^1.1.3"
- "is-arguments" "^1.1.1"
- "is-date-object" "^1.0.5"
- "is-regex" "^1.1.4"
- "isarray" "^2.0.5"
- "object-is" "^1.1.5"
- "object-keys" "^1.1.1"
- "object.assign" "^4.1.4"
- "regexp.prototype.flags" "^1.4.3"
- "side-channel" "^1.0.4"
- "which-boxed-primitive" "^1.0.2"
- "which-collection" "^1.0.1"
- "which-typed-array" "^1.1.8"
-
-"deep-is@~0.1.3":
- "integrity" "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw== sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw=="
- "resolved" "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz"
- "version" "0.1.3"
-
-"deepmerge@^4.2.2":
- "integrity" "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
- "resolved" "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz"
- "version" "4.2.2"
-
-"define-properties@^1.1.3", "define-properties@^1.1.4":
- "integrity" "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA=="
- "resolved" "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz"
- "version" "1.1.4"
- dependencies:
- "has-property-descriptors" "^1.0.0"
- "object-keys" "^1.1.1"
-
-"define-property@^0.2.5":
- "integrity" "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA=="
- "resolved" "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz"
- "version" "0.2.5"
- dependencies:
- "is-descriptor" "^0.1.0"
-
-"define-property@^1.0.0":
- "integrity" "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA=="
- "resolved" "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "is-descriptor" "^1.0.0"
-
-"define-property@^2.0.2":
- "integrity" "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ=="
- "resolved" "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "is-descriptor" "^1.0.2"
- "isobject" "^3.0.1"
-
-"delaunator@5":
- "integrity" "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw=="
- "resolved" "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz"
- "version" "5.0.0"
- dependencies:
- "robust-predicates" "^3.0.0"
-
-"delayed-stream@~1.0.0":
- "integrity" "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
- "resolved" "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
- "version" "1.0.0"
-
-"depd@2.0.0":
- "integrity" "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
- "resolved" "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz"
- "version" "2.0.0"
-
-"des.js@^1.0.0":
- "integrity" "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA=="
- "resolved" "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "inherits" "^2.0.1"
- "minimalistic-assert" "^1.0.0"
-
-"destroy@1.2.0":
- "integrity" "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
- "resolved" "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz"
- "version" "1.2.0"
-
-"detect-file@^1.0.0":
- "integrity" "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q== sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q=="
- "resolved" "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz"
- "version" "1.0.0"
-
-"detect-newline@^3.0.0":
- "integrity" "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA=="
- "resolved" "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz"
- "version" "3.1.0"
-
-"devtools-protocol@0.0.1001819":
- "integrity" "sha512-G6OsIFnv/rDyxSqBa2lDLR6thp9oJioLsb2Gl+LbQlyoA9/OBAkrTU9jiCcQ8Pnh7z4d6slDiLaogR5hzgJLmQ=="
- "resolved" "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1001819.tgz"
- "version" "0.0.1001819"
-
-"diff-match-patch@^1.0.0":
- "integrity" "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
- "resolved" "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz"
- "version" "1.0.5"
-
-"diff-sequences@^24.9.0":
- "integrity" "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew=="
- "resolved" "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz"
- "version" "24.9.0"
-
-"diff-sequences@^25.2.6":
- "integrity" "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg=="
- "resolved" "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz"
- "version" "25.2.6"
-
-"diff-sequences@^26.6.2":
- "integrity" "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q=="
- "resolved" "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz"
- "version" "26.6.2"
-
-"diff@^3.5.0":
- "integrity" "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
- "resolved" "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz"
- "version" "3.5.0"
-
-"diff@^4.0.1":
- "integrity" "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
- "resolved" "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz"
- "version" "4.0.2"
-
-"diffie-hellman@^5.0.0":
- "integrity" "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg=="
- "resolved" "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz"
- "version" "5.0.3"
- dependencies:
- "bn.js" "^4.1.0"
- "miller-rabin" "^4.0.0"
- "randombytes" "^2.0.0"
-
-"discontinuous-range@1.0.0":
- "integrity" "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ== sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ=="
- "resolved" "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz"
- "version" "1.0.0"
-
-"doctrine@^2.1.0":
- "integrity" "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="
- "resolved" "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "esutils" "^2.0.2"
-
-"doctrine@^3.0.0":
- "integrity" "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="
- "resolved" "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "esutils" "^2.0.2"
-
-"doctrine@1.5.0":
- "integrity" "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg== sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg=="
- "resolved" "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz"
- "version" "1.5.0"
- dependencies:
- "esutils" "^2.0.2"
- "isarray" "^1.0.0"
-
-"dom-accessibility-api@^0.5.9":
- "integrity" "sha512-8o+oVqLQZoruQPYy3uAAQtc6YbtSiRq5aPJBhJ82YTJRHvI6ofhYAkC81WmjFTnfUbqg6T3aCglIpU9p/5e7Cw=="
- "resolved" "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.15.tgz"
- "version" "0.5.15"
-
-"dom-align@^1.7.0":
- "integrity" "sha512-YkoezQuhp3SLFGdOlr5xkqZ640iXrnHAwVYcDg8ZKRUtO7mSzSC2BA5V0VuyAwPSJA4CLIc6EDDJh4bEsD2+zA=="
- "resolved" "https://registry.npmjs.org/dom-align/-/dom-align-1.12.0.tgz"
- "version" "1.12.0"
-
-"dom-helpers@^5.0.1":
- "integrity" "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A=="
- "resolved" "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz"
- "version" "5.1.4"
- dependencies:
- "@babel/runtime" "^7.8.7"
- "csstype" "^2.6.7"
-
-"dom-serializer@^2.0.0":
- "integrity" "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="
- "resolved" "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "domelementtype" "^2.3.0"
- "domhandler" "^5.0.2"
- "entities" "^4.2.0"
-
-"dom-serializer@0":
- "integrity" "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA=="
- "resolved" "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz"
- "version" "0.1.1"
- dependencies:
- "domelementtype" "^1.3.0"
- "entities" "^1.1.1"
-
-"domain-browser@^1.1.1":
- "integrity" "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA=="
- "resolved" "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz"
- "version" "1.2.0"
-
-"domelementtype@^1.3.0", "domelementtype@^1.3.1", "domelementtype@1":
- "integrity" "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
- "resolved" "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz"
- "version" "1.3.1"
-
-"domelementtype@^2.3.0":
- "integrity" "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
- "resolved" "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz"
- "version" "2.3.0"
-
-"domexception@^2.0.1":
- "integrity" "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg=="
- "resolved" "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "webidl-conversions" "^5.0.0"
-
-"domhandler@^2.3.0":
- "integrity" "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA=="
- "resolved" "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz"
- "version" "2.4.2"
- dependencies:
- "domelementtype" "1"
-
-"domhandler@^5.0.1", "domhandler@^5.0.2", "domhandler@^5.0.3":
- "integrity" "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="
- "resolved" "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz"
- "version" "5.0.3"
- dependencies:
- "domelementtype" "^2.3.0"
-
-"domutils@^1.5.1":
- "integrity" "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw== sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw=="
- "resolved" "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz"
- "version" "1.5.1"
- dependencies:
- "dom-serializer" "0"
- "domelementtype" "1"
-
-"domutils@^3.0.1":
- "integrity" "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q=="
- "resolved" "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "dom-serializer" "^2.0.0"
- "domelementtype" "^2.3.0"
- "domhandler" "^5.0.1"
-
-"duplexify@^3.4.2", "duplexify@^3.6.0":
- "integrity" "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g=="
- "resolved" "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz"
- "version" "3.7.1"
- dependencies:
- "end-of-stream" "^1.0.0"
- "inherits" "^2.0.1"
- "readable-stream" "^2.0.0"
- "stream-shift" "^1.0.0"
-
-"ee-first@1.1.1":
- "integrity" "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
- "resolved" "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
- "version" "1.1.1"
-
-"electron-to-chromium@^1.4.251":
- "integrity" "sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg=="
- "resolved" "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.270.tgz"
- "version" "1.4.270"
-
-"elliptic@^6.0.0", "elliptic@^6.5.2":
- "integrity" "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ=="
- "resolved" "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz"
- "version" "6.5.4"
- dependencies:
- "bn.js" "^4.11.9"
- "brorand" "^1.1.0"
- "hash.js" "^1.0.0"
- "hmac-drbg" "^1.0.1"
- "inherits" "^2.0.4"
- "minimalistic-assert" "^1.0.1"
- "minimalistic-crypto-utils" "^1.0.1"
-
-"emittery@^0.7.1":
- "integrity" "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ=="
- "resolved" "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz"
- "version" "0.7.2"
-
-"emoji-regex@^7.0.1":
- "integrity" "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
- "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz"
- "version" "7.0.3"
-
-"emoji-regex@^8.0.0":
- "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
- "version" "8.0.0"
-
-"emoji-regex@^9.0.0":
- "integrity" "sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w=="
- "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.0.0.tgz"
- "version" "9.0.0"
-
-"emojis-list@^3.0.0":
- "integrity" "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
- "resolved" "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz"
- "version" "3.0.0"
-
-"encodeurl@~1.0.2":
- "integrity" "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
- "resolved" "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
- "version" "1.0.2"
-
-"end-of-stream@^1.0.0", "end-of-stream@^1.1.0", "end-of-stream@^1.4.1":
- "integrity" "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="
- "resolved" "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz"
- "version" "1.4.4"
- dependencies:
- "once" "^1.4.0"
-
-"enhanced-resolve@^4.0.0", "enhanced-resolve@^4.1.0", "enhanced-resolve@^4.1.1":
- "integrity" "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ=="
- "resolved" "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz"
- "version" "4.2.0"
- dependencies:
- "graceful-fs" "^4.1.2"
- "memory-fs" "^0.5.0"
- "tapable" "^1.0.0"
-
-"entities@^1.1.1":
- "integrity" "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
- "resolved" "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz"
- "version" "1.1.2"
-
-"entities@^4.2.0", "entities@^4.3.0", "entities@^4.4.0":
- "integrity" "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
- "resolved" "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz"
- "version" "4.4.0"
-
-"enzyme-adapter-react-16@^1.15.6":
- "integrity" "sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g=="
- "resolved" "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.6.tgz"
- "version" "1.15.6"
- dependencies:
- "enzyme-adapter-utils" "^1.14.0"
- "enzyme-shallow-equal" "^1.0.4"
- "has" "^1.0.3"
- "object.assign" "^4.1.2"
- "object.values" "^1.1.2"
- "prop-types" "^15.7.2"
- "react-is" "^16.13.1"
- "react-test-renderer" "^16.0.0-0"
- "semver" "^5.7.0"
-
-"enzyme-adapter-utils@^1.14.0":
- "integrity" "sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg=="
- "resolved" "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz"
- "version" "1.14.0"
- dependencies:
- "airbnb-prop-types" "^2.16.0"
- "function.prototype.name" "^1.1.3"
- "has" "^1.0.3"
- "object.assign" "^4.1.2"
- "object.fromentries" "^2.0.3"
- "prop-types" "^15.7.2"
- "semver" "^5.7.1"
-
-"enzyme-shallow-equal@^1.0.1", "enzyme-shallow-equal@^1.0.4":
- "integrity" "sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q=="
- "resolved" "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "has" "^1.0.3"
- "object-is" "^1.1.2"
-
-"enzyme@^3.0.0", "enzyme@^3.11.0":
- "integrity" "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw=="
- "resolved" "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz"
- "version" "3.11.0"
- dependencies:
- "array.prototype.flat" "^1.2.3"
- "cheerio" "^1.0.0-rc.3"
- "enzyme-shallow-equal" "^1.0.1"
- "function.prototype.name" "^1.1.2"
- "has" "^1.0.3"
- "html-element-map" "^1.2.0"
- "is-boolean-object" "^1.0.1"
- "is-callable" "^1.1.5"
- "is-number-object" "^1.0.4"
- "is-regex" "^1.0.5"
- "is-string" "^1.0.5"
- "is-subset" "^0.1.1"
- "lodash.escape" "^4.0.1"
- "lodash.isequal" "^4.5.0"
- "object-inspect" "^1.7.0"
- "object-is" "^1.0.2"
- "object.assign" "^4.1.0"
- "object.entries" "^1.1.1"
- "object.values" "^1.1.1"
- "raf" "^3.4.1"
- "rst-selector-parser" "^2.2.3"
- "string.prototype.trim" "^1.2.1"
-
-"errno@^0.1.3", "errno@~0.1.7":
- "integrity" "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg=="
- "resolved" "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz"
- "version" "0.1.7"
- dependencies:
- "prr" "~1.0.1"
-
-"error-ex@^1.2.0", "error-ex@^1.3.1":
- "integrity" "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="
- "resolved" "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz"
- "version" "1.3.2"
- dependencies:
- "is-arrayish" "^0.2.1"
-
-"es-abstract@^1.17.0", "es-abstract@^1.17.0-next.1", "es-abstract@^1.17.4", "es-abstract@^1.17.5", "es-abstract@^1.18.0-next.2":
- "integrity" "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w=="
- "resolved" "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz"
- "version" "1.19.1"
- dependencies:
- "call-bind" "^1.0.2"
- "es-to-primitive" "^1.2.1"
- "function-bind" "^1.1.1"
- "get-intrinsic" "^1.1.1"
- "get-symbol-description" "^1.0.0"
- "has" "^1.0.3"
- "has-symbols" "^1.0.2"
- "internal-slot" "^1.0.3"
- "is-callable" "^1.2.4"
- "is-negative-zero" "^2.0.1"
- "is-regex" "^1.1.4"
- "is-shared-array-buffer" "^1.0.1"
- "is-string" "^1.0.7"
- "is-weakref" "^1.0.1"
- "object-inspect" "^1.11.0"
- "object-keys" "^1.1.1"
- "object.assign" "^4.1.2"
- "string.prototype.trimend" "^1.0.4"
- "string.prototype.trimstart" "^1.0.4"
- "unbox-primitive" "^1.0.1"
-
-"es-get-iterator@^1.1.2":
- "integrity" "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ=="
- "resolved" "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz"
- "version" "1.1.2"
- dependencies:
- "call-bind" "^1.0.2"
- "get-intrinsic" "^1.1.0"
- "has-symbols" "^1.0.1"
- "is-arguments" "^1.1.0"
- "is-map" "^2.0.2"
- "is-set" "^2.0.2"
- "is-string" "^1.0.5"
- "isarray" "^2.0.5"
-
-"es-to-primitive@^1.2.1":
- "integrity" "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA=="
- "resolved" "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz"
- "version" "1.2.1"
- dependencies:
- "is-callable" "^1.1.4"
- "is-date-object" "^1.0.1"
- "is-symbol" "^1.0.2"
-
-"escalade@^3.1.1":
- "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
- "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz"
- "version" "3.1.1"
-
-"escape-html@~1.0.3":
- "integrity" "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
- "resolved" "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
- "version" "1.0.3"
-
-"escape-string-regexp@^1.0.5":
- "integrity" "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
- "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
- "version" "1.0.5"
-
-"escape-string-regexp@^2.0.0":
- "integrity" "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="
- "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz"
- "version" "2.0.0"
-
-"escape-string-regexp@^4.0.0":
- "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
- "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
- "version" "4.0.0"
-
-"escodegen@^2.0.0":
- "integrity" "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw=="
- "resolved" "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "esprima" "^4.0.1"
- "estraverse" "^5.2.0"
- "esutils" "^2.0.2"
- "optionator" "^0.8.1"
- optionalDependencies:
- "source-map" "~0.6.1"
-
-"eslint-config-airbnb-base@^14.2.0":
- "integrity" "sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q=="
- "resolved" "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz"
- "version" "14.2.0"
- dependencies:
- "confusing-browser-globals" "^1.0.9"
- "object.assign" "^4.1.0"
- "object.entries" "^1.1.2"
-
-"eslint-config-airbnb@^18.2.0":
- "integrity" "sha512-Fz4JIUKkrhO0du2cg5opdyPKQXOI2MvF8KUvN2710nJMT6jaRUpRE2swrJftAjVGL7T1otLM5ieo5RqS1v9Udg=="
- "resolved" "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.0.tgz"
- "version" "18.2.0"
- dependencies:
- "eslint-config-airbnb-base" "^14.2.0"
- "object.assign" "^4.1.0"
- "object.entries" "^1.1.2"
-
-"eslint-import-resolver-node@^0.3.3":
- "integrity" "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA=="
- "resolved" "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz"
- "version" "0.3.4"
- dependencies:
- "debug" "^2.6.9"
- "resolve" "^1.13.1"
-
-"eslint-module-utils@^2.6.0":
- "integrity" "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA=="
- "resolved" "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz"
- "version" "2.6.0"
- dependencies:
- "debug" "^2.6.9"
- "pkg-dir" "^2.0.0"
-
-"eslint-plugin-import@^2.21.2", "eslint-plugin-import@^2.22.0":
- "integrity" "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg=="
- "resolved" "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz"
- "version" "2.22.0"
- dependencies:
- "array-includes" "^3.1.1"
- "array.prototype.flat" "^1.2.3"
- "contains-path" "^0.1.0"
- "debug" "^2.6.9"
- "doctrine" "1.5.0"
- "eslint-import-resolver-node" "^0.3.3"
- "eslint-module-utils" "^2.6.0"
- "has" "^1.0.3"
- "minimatch" "^3.0.4"
- "object.values" "^1.1.1"
- "read-pkg-up" "^2.0.0"
- "resolve" "^1.17.0"
- "tsconfig-paths" "^3.9.0"
-
-"eslint-plugin-jest@^22.21.0":
- "integrity" "sha512-OaqnSS7uBgcGiqXUiEnjoqxPNKvR4JWG5mSRkzVoR6+vDwlqqp11beeql1hYs0HTbdhiwrxWLxbX0Vx7roG3Ew=="
- "resolved" "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.21.0.tgz"
- "version" "22.21.0"
- dependencies:
- "@typescript-eslint/experimental-utils" "^1.13.0"
-
-"eslint-plugin-jsx-a11y@^6.3.0", "eslint-plugin-jsx-a11y@^6.3.1":
- "integrity" "sha512-i1S+P+c3HOlBJzMFORRbC58tHa65Kbo8b52/TwCwSKLohwvpfT5rm2GjGWzOHTEuq4xxf2aRlHHTtmExDQOP+g=="
- "resolved" "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.3.1.tgz"
- "version" "6.3.1"
- dependencies:
- "@babel/runtime" "^7.10.2"
- "aria-query" "^4.2.2"
- "array-includes" "^3.1.1"
- "ast-types-flow" "^0.0.7"
- "axe-core" "^3.5.4"
- "axobject-query" "^2.1.2"
- "damerau-levenshtein" "^1.0.6"
- "emoji-regex" "^9.0.0"
- "has" "^1.0.3"
- "jsx-ast-utils" "^2.4.1"
- "language-tags" "^1.0.5"
-
-"eslint-plugin-react-hooks@^1.7.0", "eslint-plugin-react-hooks@^4 || ^3 || ^2.3.0 || ^1.7.0":
- "integrity" "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA=="
- "resolved" "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz"
- "version" "1.7.0"
-
-"eslint-plugin-react@^7.20.0", "eslint-plugin-react@^7.20.3":
- "integrity" "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg=="
- "resolved" "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz"
- "version" "7.20.3"
- dependencies:
- "array-includes" "^3.1.1"
- "array.prototype.flatmap" "^1.2.3"
- "doctrine" "^2.1.0"
- "has" "^1.0.3"
- "jsx-ast-utils" "^2.4.1"
- "object.entries" "^1.1.2"
- "object.fromentries" "^2.0.2"
- "object.values" "^1.1.1"
- "prop-types" "^15.7.2"
- "resolve" "^1.17.0"
- "string.prototype.matchall" "^4.0.2"
-
-"eslint-scope@^4.0.0":
- "integrity" "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg=="
- "resolved" "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz"
- "version" "4.0.3"
- dependencies:
- "esrecurse" "^4.1.0"
- "estraverse" "^4.1.1"
-
-"eslint-scope@^4.0.3":
- "integrity" "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg=="
- "resolved" "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz"
- "version" "4.0.3"
- dependencies:
- "esrecurse" "^4.1.0"
- "estraverse" "^4.1.1"
-
-"eslint-scope@^5.0.0":
- "integrity" "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w=="
- "resolved" "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz"
- "version" "5.1.0"
- dependencies:
- "esrecurse" "^4.1.0"
- "estraverse" "^4.1.1"
-
-"eslint-utils@^1.4.3":
- "integrity" "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q=="
- "resolved" "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz"
- "version" "1.4.3"
- dependencies:
- "eslint-visitor-keys" "^1.1.0"
-
-"eslint-utils@^2.0.0":
- "integrity" "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg=="
- "resolved" "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "eslint-visitor-keys" "^1.1.0"
-
-"eslint-visitor-keys@^1.1.0":
- "integrity" "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
- "resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz"
- "version" "1.3.0"
-
-"eslint@*", "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0", "eslint@^3 || ^4 || ^5 || ^6 || ^7", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "eslint@^4.0.0 || ^5.0.0 || ^6.0.0", "eslint@^5.0.0 || ^6.0.0 || ^7.0.0", "eslint@^5.16.0 || ^6.8.0 || ^7.2.0", "eslint@^6.8.0", "eslint@>=5":
- "integrity" "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig=="
- "resolved" "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz"
- "version" "6.8.0"
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "ajv" "^6.10.0"
- "chalk" "^2.1.0"
- "cross-spawn" "^6.0.5"
- "debug" "^4.0.1"
- "doctrine" "^3.0.0"
- "eslint-scope" "^5.0.0"
- "eslint-utils" "^1.4.3"
- "eslint-visitor-keys" "^1.1.0"
- "espree" "^6.1.2"
- "esquery" "^1.0.1"
- "esutils" "^2.0.2"
- "file-entry-cache" "^5.0.1"
- "functional-red-black-tree" "^1.0.1"
- "glob-parent" "^5.0.0"
- "globals" "^12.1.0"
- "ignore" "^4.0.6"
- "import-fresh" "^3.0.0"
- "imurmurhash" "^0.1.4"
- "inquirer" "^7.0.0"
- "is-glob" "^4.0.0"
- "js-yaml" "^3.13.1"
- "json-stable-stringify-without-jsonify" "^1.0.1"
- "levn" "^0.3.0"
- "lodash" "^4.17.14"
- "minimatch" "^3.0.4"
- "mkdirp" "^0.5.1"
- "natural-compare" "^1.4.0"
- "optionator" "^0.8.3"
- "progress" "^2.0.0"
- "regexpp" "^2.0.1"
- "semver" "^6.1.2"
- "strip-ansi" "^5.2.0"
- "strip-json-comments" "^3.0.1"
- "table" "^5.2.3"
- "text-table" "^0.2.0"
- "v8-compile-cache" "^2.0.3"
-
-"espree@^6.1.2":
- "integrity" "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw=="
- "resolved" "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz"
- "version" "6.2.1"
- dependencies:
- "acorn" "^7.1.1"
- "acorn-jsx" "^5.2.0"
- "eslint-visitor-keys" "^1.1.0"
-
-"esprima@^4.0.0", "esprima@^4.0.1":
- "integrity" "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
- "resolved" "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
- "version" "4.0.1"
-
-"esquery@^1.0.1":
- "integrity" "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ=="
- "resolved" "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz"
- "version" "1.3.1"
- dependencies:
- "estraverse" "^5.1.0"
-
-"esrecurse@^4.1.0":
- "integrity" "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ=="
- "resolved" "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz"
- "version" "4.2.1"
- dependencies:
- "estraverse" "^4.1.0"
-
-"estraverse@^4.1.0", "estraverse@^4.1.1":
- "integrity" "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
- "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz"
- "version" "4.3.0"
-
-"estraverse@^5.1.0":
- "integrity" "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw=="
- "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz"
- "version" "5.1.0"
-
-"estraverse@^5.2.0":
- "integrity" "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
- "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
- "version" "5.3.0"
-
-"esutils@^2.0.2":
- "integrity" "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
- "resolved" "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
- "version" "2.0.3"
-
-"etag@~1.8.1":
- "integrity" "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
- "resolved" "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz"
- "version" "1.8.1"
-
-"events@^3.0.0":
- "integrity" "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg=="
- "resolved" "https://registry.npmjs.org/events/-/events-3.1.0.tgz"
- "version" "3.1.0"
-
-"evp_bytestokey@^1.0.0", "evp_bytestokey@^1.0.3":
- "integrity" "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA=="
- "resolved" "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz"
- "version" "1.0.3"
- dependencies:
- "md5.js" "^1.3.4"
- "safe-buffer" "^5.1.1"
-
-"exec-sh@^0.3.2":
- "integrity" "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A=="
- "resolved" "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz"
- "version" "0.3.4"
-
-"execa@^1.0.0":
- "integrity" "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA=="
- "resolved" "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "cross-spawn" "^6.0.0"
- "get-stream" "^4.0.0"
- "is-stream" "^1.1.0"
- "npm-run-path" "^2.0.0"
- "p-finally" "^1.0.0"
- "signal-exit" "^3.0.0"
- "strip-eof" "^1.0.0"
-
-"execa@^4.0.0":
- "integrity" "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA=="
- "resolved" "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz"
- "version" "4.1.0"
- dependencies:
- "cross-spawn" "^7.0.0"
- "get-stream" "^5.0.0"
- "human-signals" "^1.1.1"
- "is-stream" "^2.0.0"
- "merge-stream" "^2.0.0"
- "npm-run-path" "^4.0.0"
- "onetime" "^5.1.0"
- "signal-exit" "^3.0.2"
- "strip-final-newline" "^2.0.0"
-
-"exit@^0.1.2":
- "integrity" "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ=="
- "resolved" "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz"
- "version" "0.1.2"
-
-"expand-brackets@^2.1.4":
- "integrity" "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA=="
- "resolved" "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz"
- "version" "2.1.4"
- dependencies:
- "debug" "^2.3.3"
- "define-property" "^0.2.5"
- "extend-shallow" "^2.0.1"
- "posix-character-classes" "^0.1.0"
- "regex-not" "^1.0.0"
- "snapdragon" "^0.8.1"
- "to-regex" "^3.0.1"
-
-"expand-tilde@^2.0.0", "expand-tilde@^2.0.2":
- "integrity" "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw== sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw=="
- "resolved" "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "homedir-polyfill" "^1.0.1"
-
-"expect@^26.6.2":
- "integrity" "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA=="
- "resolved" "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "ansi-styles" "^4.0.0"
- "jest-get-type" "^26.3.0"
- "jest-matcher-utils" "^26.6.2"
- "jest-message-util" "^26.6.2"
- "jest-regex-util" "^26.0.0"
-
-"express@^4.17.1":
- "integrity" "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ=="
- "resolved" "https://registry.npmjs.org/express/-/express-4.18.2.tgz"
- "version" "4.18.2"
- dependencies:
- "accepts" "~1.3.8"
- "array-flatten" "1.1.1"
- "body-parser" "1.20.1"
- "content-disposition" "0.5.4"
- "content-type" "~1.0.4"
- "cookie" "0.5.0"
- "cookie-signature" "1.0.6"
- "debug" "2.6.9"
- "depd" "2.0.0"
- "encodeurl" "~1.0.2"
- "escape-html" "~1.0.3"
- "etag" "~1.8.1"
- "finalhandler" "1.2.0"
- "fresh" "0.5.2"
- "http-errors" "2.0.0"
- "merge-descriptors" "1.0.1"
- "methods" "~1.1.2"
- "on-finished" "2.4.1"
- "parseurl" "~1.3.3"
- "path-to-regexp" "0.1.7"
- "proxy-addr" "~2.0.7"
- "qs" "6.11.0"
- "range-parser" "~1.2.1"
- "safe-buffer" "5.2.1"
- "send" "0.18.0"
- "serve-static" "1.15.0"
- "setprototypeof" "1.2.0"
- "statuses" "2.0.1"
- "type-is" "~1.6.18"
- "utils-merge" "1.0.1"
- "vary" "~1.1.2"
-
-"extend-shallow@^2.0.1":
- "integrity" "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="
- "resolved" "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "is-extendable" "^0.1.0"
-
-"extend-shallow@^3.0.0", "extend-shallow@^3.0.2":
- "integrity" "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q=="
- "resolved" "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz"
- "version" "3.0.2"
- dependencies:
- "assign-symbols" "^1.0.0"
- "is-extendable" "^1.0.1"
-
-"external-editor@^3.0.3":
- "integrity" "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew=="
- "resolved" "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "chardet" "^0.7.0"
- "iconv-lite" "^0.4.24"
- "tmp" "^0.0.33"
-
-"extglob@^2.0.4":
- "integrity" "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw=="
- "resolved" "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz"
- "version" "2.0.4"
- dependencies:
- "array-unique" "^0.3.2"
- "define-property" "^1.0.0"
- "expand-brackets" "^2.1.4"
- "extend-shallow" "^2.0.1"
- "fragment-cache" "^0.2.1"
- "regex-not" "^1.0.0"
- "snapdragon" "^0.8.1"
- "to-regex" "^3.0.1"
-
-"extract-zip@2.0.1":
- "integrity" "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="
- "resolved" "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "debug" "^4.1.1"
- "get-stream" "^5.1.0"
- "yauzl" "^2.10.0"
- optionalDependencies:
- "@types/yauzl" "^2.9.1"
-
-"fast-deep-equal@^3.1.1":
- "integrity" "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
- "resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
- "version" "3.1.3"
-
-"fast-json-stable-stringify@^2.0.0", "fast-json-stable-stringify@2.x":
- "integrity" "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
- "resolved" "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
- "version" "2.1.0"
-
-"fast-levenshtein@~2.0.6":
- "integrity" "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
- "resolved" "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
- "version" "2.0.6"
-
-"fb-watchman@^2.0.0":
- "integrity" "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg=="
- "resolved" "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "bser" "2.1.1"
-
-"fd-slicer@~1.1.0":
- "integrity" "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="
- "resolved" "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz"
- "version" "1.1.0"
- dependencies:
- "pend" "~1.2.0"
-
-"figgy-pudding@^3.5.1":
- "integrity" "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw=="
- "resolved" "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz"
- "version" "3.5.2"
-
-"figures@^3.0.0":
- "integrity" "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg=="
- "resolved" "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz"
- "version" "3.2.0"
- dependencies:
- "escape-string-regexp" "^1.0.5"
-
-"file-entry-cache@^5.0.1":
- "integrity" "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g=="
- "resolved" "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz"
- "version" "5.0.1"
- dependencies:
- "flat-cache" "^2.0.1"
-
-"fill-range@^4.0.0":
- "integrity" "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ=="
- "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz"
- "version" "4.0.0"
- dependencies:
- "extend-shallow" "^2.0.1"
- "is-number" "^3.0.0"
- "repeat-string" "^1.6.1"
- "to-regex-range" "^2.1.0"
-
-"fill-range@^7.0.1":
- "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ=="
- "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
- "version" "7.0.1"
- dependencies:
- "to-regex-range" "^5.0.1"
-
-"finalhandler@1.2.0":
- "integrity" "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg=="
- "resolved" "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz"
- "version" "1.2.0"
- dependencies:
- "debug" "2.6.9"
- "encodeurl" "~1.0.2"
- "escape-html" "~1.0.3"
- "on-finished" "2.4.1"
- "parseurl" "~1.3.3"
- "statuses" "2.0.1"
- "unpipe" "~1.0.0"
-
-"find-cache-dir@^2.1.0":
- "integrity" "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ=="
- "resolved" "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "commondir" "^1.0.1"
- "make-dir" "^2.0.0"
- "pkg-dir" "^3.0.0"
-
-"find-root@^1.1.0":
- "integrity" "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
- "resolved" "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz"
- "version" "1.1.0"
-
-"find-up@^2.0.0":
- "integrity" "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ=="
- "resolved" "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "locate-path" "^2.0.0"
-
-"find-up@^2.1.0":
- "integrity" "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ=="
- "resolved" "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "locate-path" "^2.0.0"
-
-"find-up@^3.0.0":
- "integrity" "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="
- "resolved" "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "locate-path" "^3.0.0"
-
-"find-up@^4.0.0", "find-up@^4.1.0":
- "integrity" "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="
- "resolved" "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
- "version" "4.1.0"
- dependencies:
- "locate-path" "^5.0.0"
- "path-exists" "^4.0.0"
-
-"findup-sync@^3.0.0":
- "integrity" "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg=="
- "resolved" "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "detect-file" "^1.0.0"
- "is-glob" "^4.0.0"
- "micromatch" "^3.0.4"
- "resolve-dir" "^1.0.1"
-
-"flat-cache@^2.0.1":
- "integrity" "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA=="
- "resolved" "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "flatted" "^2.0.0"
- "rimraf" "2.6.3"
- "write" "1.0.3"
-
-"flatted@^2.0.0":
- "integrity" "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA=="
- "resolved" "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz"
- "version" "2.0.2"
-
-"flush-write-stream@^1.0.0":
- "integrity" "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w=="
- "resolved" "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz"
- "version" "1.1.1"
- dependencies:
- "inherits" "^2.0.3"
- "readable-stream" "^2.3.6"
-
-"for-each@^0.3.3":
- "integrity" "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw=="
- "resolved" "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz"
- "version" "0.3.3"
- dependencies:
- "is-callable" "^1.1.3"
-
-"for-in@^1.0.2":
- "integrity" "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ=="
- "resolved" "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz"
- "version" "1.0.2"
-
-"form-data@^3.0.0":
- "integrity" "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg=="
- "resolved" "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "asynckit" "^0.4.0"
- "combined-stream" "^1.0.8"
- "mime-types" "^2.1.12"
-
-"forwarded@0.2.0":
- "integrity" "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
- "resolved" "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz"
- "version" "0.2.0"
-
-"fragment-cache@^0.2.1":
- "integrity" "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA=="
- "resolved" "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz"
- "version" "0.2.1"
- dependencies:
- "map-cache" "^0.2.2"
-
-"fresh@0.5.2":
- "integrity" "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
- "resolved" "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz"
- "version" "0.5.2"
-
-"from2@^2.1.0":
- "integrity" "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g=="
- "resolved" "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz"
- "version" "2.3.0"
- dependencies:
- "inherits" "^2.0.1"
- "readable-stream" "^2.0.0"
-
-"fs-constants@^1.0.0":
- "integrity" "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
- "resolved" "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz"
- "version" "1.0.0"
-
-"fs-extra@^8.1.0":
- "integrity" "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="
- "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz"
- "version" "8.1.0"
- dependencies:
- "graceful-fs" "^4.2.0"
- "jsonfile" "^4.0.0"
- "universalify" "^0.1.0"
-
-"fs-write-stream-atomic@^1.0.8":
- "integrity" "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA=="
- "resolved" "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz"
- "version" "1.0.10"
- dependencies:
- "graceful-fs" "^4.1.2"
- "iferr" "^0.1.5"
- "imurmurhash" "^0.1.4"
- "readable-stream" "1 || 2"
-
-"fs.realpath@^1.0.0":
- "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
- "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
- "version" "1.0.0"
-
-"function-bind@^1.1.1":
- "integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
- "resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
- "version" "1.1.1"
-
-"function.prototype.name@^1.1.2", "function.prototype.name@^1.1.3":
- "integrity" "sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ=="
- "resolved" "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.4.tgz"
- "version" "1.1.4"
- dependencies:
- "call-bind" "^1.0.2"
- "define-properties" "^1.1.3"
- "es-abstract" "^1.18.0-next.2"
- "functions-have-names" "^1.2.2"
-
-"functional-red-black-tree@^1.0.1":
- "integrity" "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g=="
- "resolved" "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz"
- "version" "1.0.1"
-
-"functions-have-names@^1.2.2":
- "integrity" "sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA=="
- "resolved" "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.2.tgz"
- "version" "1.2.2"
-
-"gensync@^1.0.0-beta.2":
- "integrity" "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
- "resolved" "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz"
- "version" "1.0.0-beta.2"
-
-"get-caller-file@^2.0.1":
- "integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
- "resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
- "version" "2.0.5"
-
-"get-func-name@^2.0.0":
- "integrity" "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig=="
- "resolved" "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz"
- "version" "2.0.0"
-
-"get-intrinsic@^1.0.2", "get-intrinsic@^1.1.0", "get-intrinsic@^1.1.1", "get-intrinsic@^1.1.3":
- "integrity" "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A=="
- "resolved" "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz"
- "version" "1.1.3"
- dependencies:
- "function-bind" "^1.1.1"
- "has" "^1.0.3"
- "has-symbols" "^1.0.3"
-
-"get-package-type@^0.1.0":
- "integrity" "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q=="
- "resolved" "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz"
- "version" "0.1.0"
-
-"get-stream@^4.0.0":
- "integrity" "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w=="
- "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz"
- "version" "4.1.0"
- dependencies:
- "pump" "^3.0.0"
-
-"get-stream@^5.0.0", "get-stream@^5.1.0":
- "integrity" "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="
- "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz"
- "version" "5.2.0"
- dependencies:
- "pump" "^3.0.0"
-
-"get-symbol-description@^1.0.0":
- "integrity" "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw=="
- "resolved" "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "call-bind" "^1.0.2"
- "get-intrinsic" "^1.1.1"
-
-"get-value@^2.0.3", "get-value@^2.0.6":
- "integrity" "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA=="
- "resolved" "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz"
- "version" "2.0.6"
-
-"glob-parent@^3.1.0":
- "integrity" "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA=="
- "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "is-glob" "^3.1.0"
- "path-dirname" "^1.0.0"
-
-"glob-parent@^5.0.0", "glob-parent@~5.1.0":
- "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="
- "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
- "version" "5.1.2"
- dependencies:
- "is-glob" "^4.0.1"
-
-"glob@^7.0.0", "glob@^7.1.1", "glob@^7.1.2", "glob@^7.1.3", "glob@^7.1.4", "glob@^7.1.6":
- "integrity" "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA=="
- "resolved" "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz"
- "version" "7.1.6"
- dependencies:
- "fs.realpath" "^1.0.0"
- "inflight" "^1.0.4"
- "inherits" "2"
- "minimatch" "^3.0.4"
- "once" "^1.3.0"
- "path-is-absolute" "^1.0.0"
-
-"global-modules@^1.0.0":
- "integrity" "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg=="
- "resolved" "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "global-prefix" "^1.0.1"
- "is-windows" "^1.0.1"
- "resolve-dir" "^1.0.0"
-
-"global-modules@^2.0.0":
- "integrity" "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A=="
- "resolved" "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "global-prefix" "^3.0.0"
-
-"global-prefix@^1.0.1":
- "integrity" "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg== sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg=="
- "resolved" "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "expand-tilde" "^2.0.2"
- "homedir-polyfill" "^1.0.1"
- "ini" "^1.3.4"
- "is-windows" "^1.0.1"
- "which" "^1.2.14"
-
-"global-prefix@^3.0.0":
- "integrity" "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg=="
- "resolved" "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "ini" "^1.3.5"
- "kind-of" "^6.0.2"
- "which" "^1.3.1"
-
-"globals@^11.1.0":
- "integrity" "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
- "resolved" "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
- "version" "11.12.0"
-
-"globals@^12.1.0":
- "integrity" "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg=="
- "resolved" "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz"
- "version" "12.4.0"
- dependencies:
- "type-fest" "^0.8.1"
-
-"gopd@^1.0.1":
- "integrity" "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA=="
- "resolved" "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "get-intrinsic" "^1.1.3"
-
-"graceful-fs@^4.1.11", "graceful-fs@^4.1.15", "graceful-fs@^4.1.2", "graceful-fs@^4.1.6", "graceful-fs@^4.2.0", "graceful-fs@^4.2.4":
- "integrity" "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
- "resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz"
- "version" "4.2.10"
-
-"growly@^1.3.0":
- "integrity" "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw=="
- "resolved" "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz"
- "version" "1.3.0"
-
-"handlebars@^4.7.6":
- "integrity" "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA=="
- "resolved" "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz"
- "version" "4.7.7"
- dependencies:
- "minimist" "^1.2.5"
- "neo-async" "^2.6.0"
- "source-map" "^0.6.1"
- "wordwrap" "^1.0.0"
- optionalDependencies:
- "uglify-js" "^3.1.4"
-
-"has-bigints@^1.0.1":
- "integrity" "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA=="
- "resolved" "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz"
- "version" "1.0.1"
-
-"has-flag@^3.0.0":
- "integrity" "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
- "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
- "version" "3.0.0"
-
-"has-flag@^4.0.0":
- "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
- "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
- "version" "4.0.0"
-
-"has-property-descriptors@^1.0.0":
- "integrity" "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ=="
- "resolved" "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "get-intrinsic" "^1.1.1"
-
-"has-symbols@^1.0.1", "has-symbols@^1.0.2", "has-symbols@^1.0.3":
- "integrity" "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
- "resolved" "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz"
- "version" "1.0.3"
-
-"has-tostringtag@^1.0.0":
- "integrity" "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ=="
- "resolved" "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "has-symbols" "^1.0.2"
-
-"has-value@^0.3.1":
- "integrity" "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q=="
- "resolved" "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz"
- "version" "0.3.1"
- dependencies:
- "get-value" "^2.0.3"
- "has-values" "^0.1.4"
- "isobject" "^2.0.0"
-
-"has-value@^1.0.0":
- "integrity" "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw=="
- "resolved" "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "get-value" "^2.0.6"
- "has-values" "^1.0.0"
- "isobject" "^3.0.0"
-
-"has-values@^0.1.4":
- "integrity" "sha1-bWHeldkd/Km5oCCJrThL/49it3E=sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ=="
- "resolved" "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz"
- "version" "0.1.4"
-
-"has-values@^1.0.0":
- "integrity" "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ=="
- "resolved" "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "is-number" "^3.0.0"
- "kind-of" "^4.0.0"
-
-"has@^1.0.3":
- "integrity" "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw=="
- "resolved" "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
- "version" "1.0.3"
- dependencies:
- "function-bind" "^1.1.1"
-
-"hash-base@^3.0.0":
- "integrity" "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA=="
- "resolved" "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "inherits" "^2.0.4"
- "readable-stream" "^3.6.0"
- "safe-buffer" "^5.2.0"
-
-"hash.js@^1.0.0", "hash.js@^1.0.3":
- "integrity" "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA=="
- "resolved" "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz"
- "version" "1.1.7"
- dependencies:
- "inherits" "^2.0.3"
- "minimalistic-assert" "^1.0.1"
-
-"highlight.js@^10.0.0":
- "integrity" "sha512-S6G97tHGqJ/U8DsXcEdnACbirtbx58Bx9CzIVeYli8OuswCfYI/LsXH2EiGcoGio1KAC3x4mmUwulOllJ2ZyRA=="
- "resolved" "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.1.tgz"
- "version" "10.7.1"
-
-"history@^4.9.0":
- "integrity" "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew=="
- "resolved" "https://registry.npmjs.org/history/-/history-4.10.1.tgz"
- "version" "4.10.1"
- dependencies:
- "@babel/runtime" "^7.1.2"
- "loose-envify" "^1.2.0"
- "resolve-pathname" "^3.0.0"
- "tiny-invariant" "^1.0.2"
- "tiny-warning" "^1.0.0"
- "value-equal" "^1.0.1"
-
-"hmac-drbg@^1.0.1":
- "integrity" "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg=="
- "resolved" "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "hash.js" "^1.0.3"
- "minimalistic-assert" "^1.0.0"
- "minimalistic-crypto-utils" "^1.0.1"
-
-"hoist-non-react-statics@^3.1.0", "hoist-non-react-statics@^3.3.1", "hoist-non-react-statics@^3.3.2":
- "integrity" "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="
- "resolved" "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
- "version" "3.3.2"
- dependencies:
- "react-is" "^16.7.0"
-
-"homedir-polyfill@^1.0.1":
- "integrity" "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA=="
- "resolved" "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz"
- "version" "1.0.3"
- dependencies:
- "parse-passwd" "^1.0.0"
-
-"hosted-git-info@^2.1.4":
- "integrity" "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
- "resolved" "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz"
- "version" "2.8.9"
-
-"html-element-map@^1.2.0":
- "integrity" "sha512-0uXq8HsuG1v2TmQ8QkIhzbrqeskE4kn52Q18QJ9iAA/SnHoEKXWiUxHQtclRsCFWEUD2So34X+0+pZZu862nnw=="
- "resolved" "https://registry.npmjs.org/html-element-map/-/html-element-map-1.2.0.tgz"
- "version" "1.2.0"
- dependencies:
- "array-filter" "^1.0.0"
-
-"html-encoding-sniffer@^2.0.1":
- "integrity" "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ=="
- "resolved" "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "whatwg-encoding" "^1.0.5"
-
-"html-escaper@^2.0.0":
- "integrity" "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="
- "resolved" "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz"
- "version" "2.0.2"
-
-"htmlparser2@^3.9.0":
- "integrity" "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ=="
- "resolved" "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz"
- "version" "3.10.1"
- dependencies:
- "domelementtype" "^1.3.1"
- "domhandler" "^2.3.0"
- "domutils" "^1.5.1"
- "entities" "^1.1.1"
- "inherits" "^2.0.1"
- "readable-stream" "^3.1.1"
-
-"htmlparser2@^8.0.1":
- "integrity" "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA=="
- "resolved" "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz"
- "version" "8.0.1"
- dependencies:
- "domelementtype" "^2.3.0"
- "domhandler" "^5.0.2"
- "domutils" "^3.0.1"
- "entities" "^4.3.0"
-
-"http-errors@2.0.0":
- "integrity" "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="
- "resolved" "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "depd" "2.0.0"
- "inherits" "2.0.4"
- "setprototypeof" "1.2.0"
- "statuses" "2.0.1"
- "toidentifier" "1.0.1"
-
-"http-proxy-agent@^4.0.1":
- "integrity" "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg=="
- "resolved" "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz"
- "version" "4.0.1"
- dependencies:
- "@tootallnate/once" "1"
- "agent-base" "6"
- "debug" "4"
-
-"https-browserify@^1.0.0":
- "integrity" "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg=="
- "resolved" "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz"
- "version" "1.0.0"
-
-"https-proxy-agent@^5.0.0", "https-proxy-agent@5.0.1":
- "integrity" "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="
- "resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz"
- "version" "5.0.1"
- dependencies:
- "agent-base" "6"
- "debug" "4"
-
-"human-signals@^1.1.1":
- "integrity" "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw=="
- "resolved" "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz"
- "version" "1.1.1"
-
-"hyphenate-style-name@^1.0.3":
- "integrity" "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
- "resolved" "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz"
- "version" "1.0.4"
-
-"iconv-lite@^0.4.24":
- "integrity" "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="
- "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
- "version" "0.4.24"
- dependencies:
- "safer-buffer" ">= 2.1.2 < 3"
-
-"iconv-lite@0.4.24":
- "integrity" "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="
- "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
- "version" "0.4.24"
- dependencies:
- "safer-buffer" ">= 2.1.2 < 3"
-
-"iconv-lite@0.6":
- "integrity" "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="
- "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz"
- "version" "0.6.3"
- dependencies:
- "safer-buffer" ">= 2.1.2 < 3.0.0"
-
-"icss-utils@^4.0.0", "icss-utils@^4.1.1":
- "integrity" "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA=="
- "resolved" "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz"
- "version" "4.1.1"
- dependencies:
- "postcss" "^7.0.14"
-
-"ieee754@^1.1.13", "ieee754@^1.1.4":
- "integrity" "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
- "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz"
- "version" "1.1.13"
-
-"iferr@^0.1.5":
- "integrity" "sha1-xg7taebY/bazEEofy8ocGS3FtQE=sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA=="
- "resolved" "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz"
- "version" "0.1.5"
-
-"ignore@^4.0.6":
- "integrity" "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
- "resolved" "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz"
- "version" "4.0.6"
-
-"immer@^9.0.12":
- "integrity" "sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA=="
- "resolved" "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz"
- "version" "9.0.12"
-
-"import-fresh@^2.0.0":
- "integrity" "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg== sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg=="
- "resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "caller-path" "^2.0.0"
- "resolve-from" "^3.0.0"
-
-"import-fresh@^3.0.0", "import-fresh@^3.1.0":
- "integrity" "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ=="
- "resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz"
- "version" "3.2.1"
- dependencies:
- "parent-module" "^1.0.0"
- "resolve-from" "^4.0.0"
-
-"import-local@^2.0.0":
- "integrity" "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ=="
- "resolved" "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "pkg-dir" "^3.0.0"
- "resolve-cwd" "^2.0.0"
-
-"import-local@^3.0.2":
- "integrity" "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg=="
- "resolved" "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "pkg-dir" "^4.2.0"
- "resolve-cwd" "^3.0.0"
-
-"imurmurhash@^0.1.4":
- "integrity" "sha1-khi5srkoojixPcT7a21XbyMUU+o=sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
- "resolved" "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
- "version" "0.1.4"
-
-"indefinite-observable@^2.0.1":
- "integrity" "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ=="
- "resolved" "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "symbol-observable" "1.2.0"
-
-"indent-string@^4.0.0":
- "integrity" "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="
- "resolved" "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz"
- "version" "4.0.0"
-
-"indexes-of@^1.0.1":
- "integrity" "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA== sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA=="
- "resolved" "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz"
- "version" "1.0.1"
-
-"infer-owner@^1.0.3":
- "integrity" "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
- "resolved" "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz"
- "version" "1.0.4"
-
-"inflight@^1.0.4":
- "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="
- "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
- "version" "1.0.6"
- dependencies:
- "once" "^1.3.0"
- "wrappy" "1"
-
-"inherits@^2.0.1", "inherits@^2.0.3", "inherits@^2.0.4", "inherits@~2.0.1", "inherits@~2.0.3", "inherits@2", "inherits@2.0.4":
- "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
- "version" "2.0.4"
-
-"inherits@2.0.1":
- "integrity" "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA== sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA=="
- "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
- "version" "2.0.1"
-
-"inherits@2.0.3":
- "integrity" "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
- "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
- "version" "2.0.3"
-
-"ini@^1.3.4", "ini@^1.3.5":
- "integrity" "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
- "resolved" "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
- "version" "1.3.8"
-
-"inquirer@^7.0.0":
- "integrity" "sha512-DF4osh1FM6l0RJc5YWYhSDB6TawiBRlbV9Cox8MWlidU218Tb7fm3lQTULyUJDfJ0tjbzl0W4q651mrCCEM55w=="
- "resolved" "https://registry.npmjs.org/inquirer/-/inquirer-7.3.2.tgz"
- "version" "7.3.2"
- dependencies:
- "ansi-escapes" "^4.2.1"
- "chalk" "^4.1.0"
- "cli-cursor" "^3.1.0"
- "cli-width" "^3.0.0"
- "external-editor" "^3.0.3"
- "figures" "^3.0.0"
- "lodash" "^4.17.16"
- "mute-stream" "0.0.8"
- "run-async" "^2.4.0"
- "rxjs" "^6.6.0"
- "string-width" "^4.1.0"
- "strip-ansi" "^6.0.0"
- "through" "^2.3.6"
-
-"internal-slot@^1.0.2", "internal-slot@^1.0.3":
- "integrity" "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA=="
- "resolved" "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz"
- "version" "1.0.3"
- dependencies:
- "get-intrinsic" "^1.1.0"
- "has" "^1.0.3"
- "side-channel" "^1.0.4"
-
-"internmap@^1.0.0":
- "integrity" "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="
- "resolved" "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz"
- "version" "1.0.1"
-
-"internmap@1 - 2":
- "integrity" "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="
- "resolved" "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz"
- "version" "2.0.3"
-
-"interpret@^1.0.0", "interpret@^1.4.0":
- "integrity" "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
- "resolved" "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz"
- "version" "1.4.0"
-
-"intro.js-react@^0.6.0":
- "integrity" "sha512-Ozkx1w89zXPM4Uufc3eoolq0svLQLoDon28YaxqhN1ZmS0oG5Fb2Tui6AZQJXDY8HC2kwq+Smzv3QXa0kf5ZGg=="
- "resolved" "https://registry.npmjs.org/intro.js-react/-/intro.js-react-0.6.0.tgz"
- "version" "0.6.0"
-
-"intro.js@^5.0.0", "intro.js@>=2.5.0":
- "integrity" "sha512-bj3R8Fb9h5I/oJIit60KciZUXBDviA4qV1iM9O/AXQvrfv78Szx9ILuRWET1W2jGge8RcM11TApxwQ0007Y1nQ=="
- "resolved" "https://registry.npmjs.org/intro.js/-/intro.js-5.0.0.tgz"
- "version" "5.0.0"
-
-"ipaddr.js@1.9.1":
- "integrity" "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
- "resolved" "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz"
- "version" "1.9.1"
-
-"is-accessor-descriptor@^0.1.6":
- "integrity" "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A=="
- "resolved" "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz"
- "version" "0.1.6"
- dependencies:
- "kind-of" "^3.0.2"
-
-"is-accessor-descriptor@^1.0.0":
- "integrity" "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ=="
- "resolved" "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "kind-of" "^6.0.0"
-
-"is-arguments@^1.0.4", "is-arguments@^1.1.0", "is-arguments@^1.1.1":
- "integrity" "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA=="
- "resolved" "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz"
- "version" "1.1.1"
- dependencies:
- "call-bind" "^1.0.2"
- "has-tostringtag" "^1.0.0"
-
-"is-arrayish@^0.2.1":
- "integrity" "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
- "resolved" "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
- "version" "0.2.1"
-
-"is-bigint@^1.0.1":
- "integrity" "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg=="
- "resolved" "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "has-bigints" "^1.0.1"
-
-"is-binary-path@^1.0.0":
- "integrity" "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q=="
- "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "binary-extensions" "^1.0.0"
-
-"is-binary-path@~2.1.0":
- "integrity" "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="
- "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "binary-extensions" "^2.0.0"
-
-"is-boolean-object@^1.0.1", "is-boolean-object@^1.1.0":
- "integrity" "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA=="
- "resolved" "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz"
- "version" "1.1.0"
- dependencies:
- "call-bind" "^1.0.0"
-
-"is-buffer@^1.1.5":
- "integrity" "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
- "resolved" "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz"
- "version" "1.1.6"
-
-"is-callable@^1.1.3", "is-callable@^1.1.4", "is-callable@^1.1.5", "is-callable@^1.2.4":
- "integrity" "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w=="
- "resolved" "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz"
- "version" "1.2.4"
-
-"is-ci@^2.0.0":
- "integrity" "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w=="
- "resolved" "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "ci-info" "^2.0.0"
-
-"is-core-module@^2.2.0":
- "integrity" "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ=="
- "resolved" "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz"
- "version" "2.2.0"
- dependencies:
- "has" "^1.0.3"
-
-"is-data-descriptor@^0.1.4":
- "integrity" "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg=="
- "resolved" "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz"
- "version" "0.1.4"
- dependencies:
- "kind-of" "^3.0.2"
-
-"is-data-descriptor@^1.0.0":
- "integrity" "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ=="
- "resolved" "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "kind-of" "^6.0.0"
-
-"is-date-object@^1.0.1", "is-date-object@^1.0.5":
- "integrity" "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ=="
- "resolved" "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz"
- "version" "1.0.5"
- dependencies:
- "has-tostringtag" "^1.0.0"
-
-"is-descriptor@^0.1.0":
- "integrity" "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg=="
- "resolved" "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz"
- "version" "0.1.6"
- dependencies:
- "is-accessor-descriptor" "^0.1.6"
- "is-data-descriptor" "^0.1.4"
- "kind-of" "^5.0.0"
-
-"is-descriptor@^1.0.0", "is-descriptor@^1.0.2":
- "integrity" "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg=="
- "resolved" "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "is-accessor-descriptor" "^1.0.0"
- "is-data-descriptor" "^1.0.0"
- "kind-of" "^6.0.2"
-
-"is-directory@^0.3.1":
- "integrity" "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw== sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw=="
- "resolved" "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz"
- "version" "0.3.1"
-
-"is-docker@^2.0.0":
- "integrity" "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="
- "resolved" "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
- "version" "2.2.1"
-
-"is-extendable@^0.1.0", "is-extendable@^0.1.1":
- "integrity" "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="
- "resolved" "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz"
- "version" "0.1.1"
-
-"is-extendable@^0.1.1":
- "integrity" "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="
- "resolved" "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz"
- "version" "0.1.1"
-
-"is-extendable@^1.0.1":
- "integrity" "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA=="
- "resolved" "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "is-plain-object" "^2.0.4"
-
-"is-extglob@^2.1.0", "is-extglob@^2.1.1":
- "integrity" "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
- "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
- "version" "2.1.1"
-
-"is-fullwidth-code-point@^2.0.0":
- "integrity" "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w=="
- "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz"
- "version" "2.0.0"
-
-"is-fullwidth-code-point@^3.0.0":
- "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz"
- "version" "3.0.0"
-
-"is-generator-fn@^2.0.0":
- "integrity" "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ=="
- "resolved" "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz"
- "version" "2.1.0"
-
-"is-generator-function@^1.0.7":
- "integrity" "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A=="
- "resolved" "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz"
- "version" "1.0.10"
- dependencies:
- "has-tostringtag" "^1.0.0"
-
-"is-glob@^3.1.0":
- "integrity" "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw=="
- "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "is-extglob" "^2.1.0"
-
-"is-glob@^4.0.0", "is-glob@^4.0.1", "is-glob@~4.0.1":
- "integrity" "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg=="
- "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz"
- "version" "4.0.1"
- dependencies:
- "is-extglob" "^2.1.1"
-
-"is-in-browser@^1.0.2", "is-in-browser@^1.1.3":
- "integrity" "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g== sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g=="
- "resolved" "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz"
- "version" "1.1.3"
-
-"is-map@^2.0.1", "is-map@^2.0.2":
- "integrity" "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg=="
- "resolved" "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz"
- "version" "2.0.2"
-
-"is-negative-zero@^2.0.1":
- "integrity" "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w=="
- "resolved" "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz"
- "version" "2.0.1"
-
-"is-number-object@^1.0.4":
- "integrity" "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw=="
- "resolved" "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz"
- "version" "1.0.4"
-
-"is-number@^3.0.0":
- "integrity" "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg=="
- "resolved" "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "kind-of" "^3.0.2"
-
-"is-number@^7.0.0":
- "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
- "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
- "version" "7.0.0"
-
-"is-plain-object@^2.0.3", "is-plain-object@^2.0.4":
- "integrity" "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og=="
- "resolved" "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz"
- "version" "2.0.4"
- dependencies:
- "isobject" "^3.0.1"
-
-"is-potential-custom-element-name@^1.0.1":
- "integrity" "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
- "resolved" "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz"
- "version" "1.0.1"
-
-"is-regex@^1.0.5", "is-regex@^1.1.0", "is-regex@^1.1.4":
- "integrity" "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg=="
- "resolved" "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz"
- "version" "1.1.4"
- dependencies:
- "call-bind" "^1.0.2"
- "has-tostringtag" "^1.0.0"
-
-"is-set@^2.0.1", "is-set@^2.0.2":
- "integrity" "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g=="
- "resolved" "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz"
- "version" "2.0.2"
-
-"is-shared-array-buffer@^1.0.1":
- "integrity" "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA=="
- "resolved" "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz"
- "version" "1.0.1"
-
-"is-stream@^1.1.0":
- "integrity" "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="
- "resolved" "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz"
- "version" "1.1.0"
-
-"is-stream@^2.0.0":
- "integrity" "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
- "resolved" "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz"
- "version" "2.0.1"
-
-"is-string@^1.0.5", "is-string@^1.0.7":
- "integrity" "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg=="
- "resolved" "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz"
- "version" "1.0.7"
- dependencies:
- "has-tostringtag" "^1.0.0"
-
-"is-subset@^0.1.1":
- "integrity" "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw== sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw=="
- "resolved" "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz"
- "version" "0.1.1"
-
-"is-symbol@^1.0.2", "is-symbol@^1.0.3":
- "integrity" "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ=="
- "resolved" "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz"
- "version" "1.0.3"
- dependencies:
- "has-symbols" "^1.0.1"
-
-"is-typed-array@^1.1.10", "is-typed-array@^1.1.3":
- "integrity" "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A=="
- "resolved" "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz"
- "version" "1.1.10"
- dependencies:
- "available-typed-arrays" "^1.0.5"
- "call-bind" "^1.0.2"
- "for-each" "^0.3.3"
- "gopd" "^1.0.1"
- "has-tostringtag" "^1.0.0"
-
-"is-typedarray@^1.0.0":
- "integrity" "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
- "resolved" "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz"
- "version" "1.0.0"
-
-"is-weakmap@^2.0.1":
- "integrity" "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA=="
- "resolved" "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz"
- "version" "2.0.1"
-
-"is-weakref@^1.0.1":
- "integrity" "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ=="
- "resolved" "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "call-bind" "^1.0.2"
-
-"is-weakset@^2.0.1":
- "integrity" "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg=="
- "resolved" "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "call-bind" "^1.0.2"
- "get-intrinsic" "^1.1.1"
-
-"is-windows@^1.0.1", "is-windows@^1.0.2":
- "integrity" "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
- "resolved" "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz"
- "version" "1.0.2"
-
-"is-wsl@^1.1.0":
- "integrity" "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw=="
- "resolved" "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz"
- "version" "1.1.0"
-
-"is-wsl@^2.2.0":
- "integrity" "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="
- "resolved" "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz"
- "version" "2.2.0"
- dependencies:
- "is-docker" "^2.0.0"
-
-"isarray@^1.0.0", "isarray@~1.0.0", "isarray@1.0.0":
- "integrity" "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
- "resolved" "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
- "version" "1.0.0"
-
-"isarray@^2.0.5":
- "integrity" "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
- "resolved" "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz"
- "version" "2.0.5"
-
-"isarray@0.0.1":
- "integrity" "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
- "resolved" "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
- "version" "0.0.1"
-
-"isexe@^2.0.0":
- "integrity" "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
- "resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
- "version" "2.0.0"
-
-"isobject@^2.0.0":
- "integrity" "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA=="
- "resolved" "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "isarray" "1.0.0"
-
-"isobject@^3.0.0", "isobject@^3.0.1":
- "integrity" "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="
- "resolved" "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz"
- "version" "3.0.1"
-
-"istanbul-lib-coverage@^3.0.0", "istanbul-lib-coverage@^3.2.0":
- "integrity" "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw=="
- "resolved" "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz"
- "version" "3.2.0"
-
-"istanbul-lib-instrument@^4.0.3":
- "integrity" "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ=="
- "resolved" "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz"
- "version" "4.0.3"
- dependencies:
- "@babel/core" "^7.7.5"
- "@istanbuljs/schema" "^0.1.2"
- "istanbul-lib-coverage" "^3.0.0"
- "semver" "^6.3.0"
-
-"istanbul-lib-instrument@^5.0.4":
- "integrity" "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A=="
- "resolved" "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz"
- "version" "5.2.0"
- dependencies:
- "@babel/core" "^7.12.3"
- "@babel/parser" "^7.14.7"
- "@istanbuljs/schema" "^0.1.2"
- "istanbul-lib-coverage" "^3.2.0"
- "semver" "^6.3.0"
-
-"istanbul-lib-report@^3.0.0":
- "integrity" "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw=="
- "resolved" "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "istanbul-lib-coverage" "^3.0.0"
- "make-dir" "^3.0.0"
- "supports-color" "^7.1.0"
-
-"istanbul-lib-source-maps@^4.0.0":
- "integrity" "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw=="
- "resolved" "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz"
- "version" "4.0.1"
- dependencies:
- "debug" "^4.1.1"
- "istanbul-lib-coverage" "^3.0.0"
- "source-map" "^0.6.1"
-
-"istanbul-reports@^3.0.2":
- "integrity" "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw=="
- "resolved" "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz"
- "version" "3.1.4"
- dependencies:
- "html-escaper" "^2.0.0"
- "istanbul-lib-report" "^3.0.0"
-
-"jest-changed-files@^26.6.2":
- "integrity" "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ=="
- "resolved" "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "execa" "^4.0.0"
- "throat" "^5.0.0"
-
-"jest-cli@^26.1.0", "jest-cli@^26.6.3":
- "integrity" "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg=="
- "resolved" "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@jest/core" "^26.6.3"
- "@jest/test-result" "^26.6.2"
- "@jest/types" "^26.6.2"
- "chalk" "^4.0.0"
- "exit" "^0.1.2"
- "graceful-fs" "^4.2.4"
- "import-local" "^3.0.2"
- "is-ci" "^2.0.0"
- "jest-config" "^26.6.3"
- "jest-util" "^26.6.2"
- "jest-validate" "^26.6.2"
- "prompts" "^2.0.1"
- "yargs" "^15.4.1"
-
-"jest-config@^26.6.3":
- "integrity" "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg=="
- "resolved" "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@babel/core" "^7.1.0"
- "@jest/test-sequencer" "^26.6.3"
- "@jest/types" "^26.6.2"
- "babel-jest" "^26.6.3"
- "chalk" "^4.0.0"
- "deepmerge" "^4.2.2"
- "glob" "^7.1.1"
- "graceful-fs" "^4.2.4"
- "jest-environment-jsdom" "^26.6.2"
- "jest-environment-node" "^26.6.2"
- "jest-get-type" "^26.3.0"
- "jest-jasmine2" "^26.6.3"
- "jest-regex-util" "^26.0.0"
- "jest-resolve" "^26.6.2"
- "jest-util" "^26.6.2"
- "jest-validate" "^26.6.2"
- "micromatch" "^4.0.2"
- "pretty-format" "^26.6.2"
-
-"jest-diff@^24.0.0":
- "integrity" "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ=="
- "resolved" "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz"
- "version" "24.9.0"
- dependencies:
- "chalk" "^2.0.1"
- "diff-sequences" "^24.9.0"
- "jest-get-type" "^24.9.0"
- "pretty-format" "^24.9.0"
-
-"jest-diff@^24.9.0":
- "integrity" "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ=="
- "resolved" "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz"
- "version" "24.9.0"
- dependencies:
- "chalk" "^2.0.1"
- "diff-sequences" "^24.9.0"
- "jest-get-type" "^24.9.0"
- "pretty-format" "^24.9.0"
-
-"jest-diff@^25.2.1":
- "integrity" "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A=="
- "resolved" "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz"
- "version" "25.5.0"
- dependencies:
- "chalk" "^3.0.0"
- "diff-sequences" "^25.2.6"
- "jest-get-type" "^25.2.6"
- "pretty-format" "^25.5.0"
-
-"jest-diff@^26.1.0", "jest-diff@^26.6.2":
- "integrity" "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA=="
- "resolved" "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "chalk" "^4.0.0"
- "diff-sequences" "^26.6.2"
- "jest-get-type" "^26.3.0"
- "pretty-format" "^26.6.2"
-
-"jest-docblock@^26.0.0":
- "integrity" "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w=="
- "resolved" "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz"
- "version" "26.0.0"
- dependencies:
- "detect-newline" "^3.0.0"
-
-"jest-each@^26.6.2":
- "integrity" "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A=="
- "resolved" "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "chalk" "^4.0.0"
- "jest-get-type" "^26.3.0"
- "jest-util" "^26.6.2"
- "pretty-format" "^26.6.2"
-
-"jest-environment-jsdom@^26.6.2":
- "integrity" "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q=="
- "resolved" "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/environment" "^26.6.2"
- "@jest/fake-timers" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "jest-mock" "^26.6.2"
- "jest-util" "^26.6.2"
- "jsdom" "^16.4.0"
-
-"jest-environment-node@^26.6.2":
- "integrity" "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag=="
- "resolved" "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/environment" "^26.6.2"
- "@jest/fake-timers" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "jest-mock" "^26.6.2"
- "jest-util" "^26.6.2"
-
-"jest-get-type@^24.9.0":
- "integrity" "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q=="
- "resolved" "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz"
- "version" "24.9.0"
-
-"jest-get-type@^25.2.6":
- "integrity" "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig=="
- "resolved" "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz"
- "version" "25.2.6"
-
-"jest-get-type@^26.3.0":
- "integrity" "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig=="
- "resolved" "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz"
- "version" "26.3.0"
-
-"jest-haste-map@^26.6.2":
- "integrity" "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w=="
- "resolved" "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "@types/graceful-fs" "^4.1.2"
- "@types/node" "*"
- "anymatch" "^3.0.3"
- "fb-watchman" "^2.0.0"
- "graceful-fs" "^4.2.4"
- "jest-regex-util" "^26.0.0"
- "jest-serializer" "^26.6.2"
- "jest-util" "^26.6.2"
- "jest-worker" "^26.6.2"
- "micromatch" "^4.0.2"
- "sane" "^4.0.3"
- "walker" "^1.0.7"
- optionalDependencies:
- "fsevents" "^2.1.2"
-
-"jest-jasmine2@^26.6.3":
- "integrity" "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg=="
- "resolved" "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@babel/traverse" "^7.1.0"
- "@jest/environment" "^26.6.2"
- "@jest/source-map" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "chalk" "^4.0.0"
- "co" "^4.6.0"
- "expect" "^26.6.2"
- "is-generator-fn" "^2.0.0"
- "jest-each" "^26.6.2"
- "jest-matcher-utils" "^26.6.2"
- "jest-message-util" "^26.6.2"
- "jest-runtime" "^26.6.3"
- "jest-snapshot" "^26.6.2"
- "jest-util" "^26.6.2"
- "pretty-format" "^26.6.2"
- "throat" "^5.0.0"
-
-"jest-leak-detector@^26.6.2":
- "integrity" "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg=="
- "resolved" "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "jest-get-type" "^26.3.0"
- "pretty-format" "^26.6.2"
-
-"jest-matcher-utils@^24.0.0":
- "integrity" "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA=="
- "resolved" "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz"
- "version" "24.9.0"
- dependencies:
- "chalk" "^2.0.1"
- "jest-diff" "^24.9.0"
- "jest-get-type" "^24.9.0"
- "pretty-format" "^24.9.0"
-
-"jest-matcher-utils@^26.6.2":
- "integrity" "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw=="
- "resolved" "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "chalk" "^4.0.0"
- "jest-diff" "^26.6.2"
- "jest-get-type" "^26.3.0"
- "pretty-format" "^26.6.2"
-
-"jest-message-util@^26.6.2":
- "integrity" "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA=="
- "resolved" "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@jest/types" "^26.6.2"
- "@types/stack-utils" "^2.0.0"
- "chalk" "^4.0.0"
- "graceful-fs" "^4.2.4"
- "micromatch" "^4.0.2"
- "pretty-format" "^26.6.2"
- "slash" "^3.0.0"
- "stack-utils" "^2.0.2"
-
-"jest-mock@^26.6.2":
- "integrity" "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew=="
- "resolved" "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "@types/node" "*"
-
-"jest-pnp-resolver@^1.2.2":
- "integrity" "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w=="
- "resolved" "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz"
- "version" "1.2.2"
-
-"jest-regex-util@^26.0.0":
- "integrity" "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A=="
- "resolved" "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz"
- "version" "26.0.0"
-
-"jest-resolve-dependencies@^26.6.3":
- "integrity" "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg=="
- "resolved" "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@jest/types" "^26.6.2"
- "jest-regex-util" "^26.0.0"
- "jest-snapshot" "^26.6.2"
-
-"jest-resolve@*", "jest-resolve@^26.6.2":
- "integrity" "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ=="
- "resolved" "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "chalk" "^4.0.0"
- "graceful-fs" "^4.2.4"
- "jest-pnp-resolver" "^1.2.2"
- "jest-util" "^26.6.2"
- "read-pkg-up" "^7.0.1"
- "resolve" "^1.18.1"
- "slash" "^3.0.0"
-
-"jest-runner-eslint@^0.7.7":
- "integrity" "sha512-N87Lpd8MdqrCmYJLhhDfIFTWqeqhCPIvtozFY5fjptGd1rZxoU4GN1sr2LtA1wvM+O4vcljrRsw23Ybk145Jjw=="
- "resolved" "https://registry.npmjs.org/jest-runner-eslint/-/jest-runner-eslint-0.7.7.tgz"
- "version" "0.7.7"
- dependencies:
- "chalk" "^2.4.1"
- "cosmiconfig" "^5.0.0"
- "create-jest-runner" "^0.5.3"
- "eslint" "^4.0.0 || ^5.0.0 || ^6.0.0"
-
-"jest-runner@^26.1.0", "jest-runner@^26.6.3":
- "integrity" "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ=="
- "resolved" "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@jest/console" "^26.6.2"
- "@jest/environment" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "chalk" "^4.0.0"
- "emittery" "^0.7.1"
- "exit" "^0.1.2"
- "graceful-fs" "^4.2.4"
- "jest-config" "^26.6.3"
- "jest-docblock" "^26.0.0"
- "jest-haste-map" "^26.6.2"
- "jest-leak-detector" "^26.6.2"
- "jest-message-util" "^26.6.2"
- "jest-resolve" "^26.6.2"
- "jest-runtime" "^26.6.3"
- "jest-util" "^26.6.2"
- "jest-worker" "^26.6.2"
- "source-map-support" "^0.5.6"
- "throat" "^5.0.0"
-
-"jest-runtime@^26.6.3":
- "integrity" "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw=="
- "resolved" "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@jest/console" "^26.6.2"
- "@jest/environment" "^26.6.2"
- "@jest/fake-timers" "^26.6.2"
- "@jest/globals" "^26.6.2"
- "@jest/source-map" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/transform" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/yargs" "^15.0.0"
- "chalk" "^4.0.0"
- "cjs-module-lexer" "^0.6.0"
- "collect-v8-coverage" "^1.0.0"
- "exit" "^0.1.2"
- "glob" "^7.1.3"
- "graceful-fs" "^4.2.4"
- "jest-config" "^26.6.3"
- "jest-haste-map" "^26.6.2"
- "jest-message-util" "^26.6.2"
- "jest-mock" "^26.6.2"
- "jest-regex-util" "^26.0.0"
- "jest-resolve" "^26.6.2"
- "jest-snapshot" "^26.6.2"
- "jest-util" "^26.6.2"
- "jest-validate" "^26.6.2"
- "slash" "^3.0.0"
- "strip-bom" "^4.0.0"
- "yargs" "^15.4.1"
-
-"jest-serializer@^26.6.2":
- "integrity" "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g=="
- "resolved" "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@types/node" "*"
- "graceful-fs" "^4.2.4"
-
-"jest-snapshot@^26.6.2":
- "integrity" "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og=="
- "resolved" "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@babel/types" "^7.0.0"
- "@jest/types" "^26.6.2"
- "@types/babel__traverse" "^7.0.4"
- "@types/prettier" "^2.0.0"
- "chalk" "^4.0.0"
- "expect" "^26.6.2"
- "graceful-fs" "^4.2.4"
- "jest-diff" "^26.6.2"
- "jest-get-type" "^26.3.0"
- "jest-haste-map" "^26.6.2"
- "jest-matcher-utils" "^26.6.2"
- "jest-message-util" "^26.6.2"
- "jest-resolve" "^26.6.2"
- "natural-compare" "^1.4.0"
- "pretty-format" "^26.6.2"
- "semver" "^7.3.2"
-
-"jest-util@^26.1.0", "jest-util@^26.6.2":
- "integrity" "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q=="
- "resolved" "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "chalk" "^4.0.0"
- "graceful-fs" "^4.2.4"
- "is-ci" "^2.0.0"
- "micromatch" "^4.0.2"
-
-"jest-validate@^26.6.2":
- "integrity" "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ=="
- "resolved" "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "camelcase" "^6.0.0"
- "chalk" "^4.0.0"
- "jest-get-type" "^26.3.0"
- "leven" "^3.1.0"
- "pretty-format" "^26.6.2"
-
-"jest-watcher@^26.6.2":
- "integrity" "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ=="
- "resolved" "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/test-result" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- "ansi-escapes" "^4.2.1"
- "chalk" "^4.0.0"
- "jest-util" "^26.6.2"
- "string-length" "^4.0.1"
-
-"jest-worker@^24.0.0":
- "integrity" "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw=="
- "resolved" "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz"
- "version" "24.9.0"
- dependencies:
- "merge-stream" "^2.0.0"
- "supports-color" "^6.1.0"
-
-"jest-worker@^26.6.2":
- "integrity" "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ=="
- "resolved" "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@types/node" "*"
- "merge-stream" "^2.0.0"
- "supports-color" "^7.0.0"
-
-"jest@^21.0.0 || ^22.0.0 || ^23.0.0 || ^24.0.0 || ^25.1.0", "jest@^26.1.0", "jest@>=26 <27":
- "integrity" "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q=="
- "resolved" "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz"
- "version" "26.6.3"
- dependencies:
- "@jest/core" "^26.6.3"
- "import-local" "^3.0.2"
- "jest-cli" "^26.6.3"
-
-"js-tokens@^3.0.0 || ^4.0.0", "js-tokens@^4.0.0":
- "integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
- "resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
- "version" "4.0.0"
-
-"js-yaml@^3.13.1":
- "integrity" "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A=="
- "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz"
- "version" "3.14.0"
- dependencies:
- "argparse" "^1.0.7"
- "esprima" "^4.0.0"
-
-"jscharting-react@^1.2.1":
- "integrity" "sha512-09sFgQTry46Nha7jF4uYJOACjUEMkMUwJvmW4X2B0DS1EI2Rbf/nIxzIaT+R0CMd76S038RptrxcXXeKhEns5A=="
- "resolved" "https://registry.npmjs.org/jscharting-react/-/jscharting-react-1.2.1.tgz"
- "version" "1.2.1"
- dependencies:
- "jscharting" "^3.0.2"
-
-"jscharting@^3.0.2":
- "integrity" "sha512-8Yb8iV1FUXEM9CuyO9wxV/1giw/gPgxqtnzTw5C+AvSsODXXzJOXtzkWtl6sZ3loQpoNPl+ZGsc6ZYKRxHGc9A=="
- "resolved" "https://registry.npmjs.org/jscharting/-/jscharting-3.0.2.tgz"
- "version" "3.0.2"
-
-"jsdom@^16.4.0":
- "integrity" "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw=="
- "resolved" "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz"
- "version" "16.7.0"
- dependencies:
- "abab" "^2.0.5"
- "acorn" "^8.2.4"
- "acorn-globals" "^6.0.0"
- "cssom" "^0.4.4"
- "cssstyle" "^2.3.0"
- "data-urls" "^2.0.0"
- "decimal.js" "^10.2.1"
- "domexception" "^2.0.1"
- "escodegen" "^2.0.0"
- "form-data" "^3.0.0"
- "html-encoding-sniffer" "^2.0.1"
- "http-proxy-agent" "^4.0.1"
- "https-proxy-agent" "^5.0.0"
- "is-potential-custom-element-name" "^1.0.1"
- "nwsapi" "^2.2.0"
- "parse5" "6.0.1"
- "saxes" "^5.0.1"
- "symbol-tree" "^3.2.4"
- "tough-cookie" "^4.0.0"
- "w3c-hr-time" "^1.0.2"
- "w3c-xmlserializer" "^2.0.0"
- "webidl-conversions" "^6.1.0"
- "whatwg-encoding" "^1.0.5"
- "whatwg-mimetype" "^2.3.0"
- "whatwg-url" "^8.5.0"
- "ws" "^7.4.6"
- "xml-name-validator" "^3.0.0"
-
-"jsesc@^2.5.1":
- "integrity" "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
- "resolved" "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
- "version" "2.5.2"
-
-"jsesc@~0.5.0":
- "integrity" "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA=="
- "resolved" "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz"
- "version" "0.5.0"
-
-"json-parse-better-errors@^1.0.1", "json-parse-better-errors@^1.0.2":
- "integrity" "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
- "resolved" "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz"
- "version" "1.0.2"
-
-"json-parse-even-better-errors@^2.3.0":
- "integrity" "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
- "resolved" "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz"
- "version" "2.3.1"
-
-"json-schema-traverse@^0.4.1":
- "integrity" "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
- "resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
- "version" "0.4.1"
-
-"json-stable-stringify-without-jsonify@^1.0.1":
- "integrity" "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
- "resolved" "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
- "version" "1.0.1"
-
-"json5@^1.0.1":
- "integrity" "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow=="
- "resolved" "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "minimist" "^1.2.0"
-
-"json5@^2.1.2", "json5@2.x":
- "integrity" "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA=="
- "resolved" "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz"
- "version" "2.1.3"
- dependencies:
- "minimist" "^1.2.5"
-
-"jsondiffpatch@^0.3.11":
- "integrity" "sha512-Xi3Iygdt/BGhml6bdUFhgDki1TgOsp3hG3iiH3KtzP+CahtGcdPfKRLlnZbSw+3b1umZkhmKrqXUgUcKenyhtA=="
- "resolved" "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.3.11.tgz"
- "version" "0.3.11"
- dependencies:
- "chalk" "^2.3.0"
- "diff-match-patch" "^1.0.0"
-
-"jsonfile@^4.0.0":
- "integrity" "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="
- "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz"
- "version" "4.0.0"
- optionalDependencies:
- "graceful-fs" "^4.1.6"
-
-"jss-plugin-camel-case@^10.5.1":
- "integrity" "sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A=="
- "resolved" "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz"
- "version" "10.6.0"
- dependencies:
- "@babel/runtime" "^7.3.1"
- "hyphenate-style-name" "^1.0.3"
- "jss" "10.6.0"
-
-"jss-plugin-default-unit@^10.5.1":
- "integrity" "sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w=="
- "resolved" "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz"
- "version" "10.6.0"
- dependencies:
- "@babel/runtime" "^7.3.1"
- "jss" "10.6.0"
-
-"jss-plugin-global@^10.5.1":
- "integrity" "sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w=="
- "resolved" "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz"
- "version" "10.6.0"
- dependencies:
- "@babel/runtime" "^7.3.1"
- "jss" "10.6.0"
-
-"jss-plugin-nested@^10.5.1":
- "integrity" "sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g=="
- "resolved" "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz"
- "version" "10.6.0"
- dependencies:
- "@babel/runtime" "^7.3.1"
- "jss" "10.6.0"
- "tiny-warning" "^1.0.2"
-
-"jss-plugin-props-sort@^10.5.1":
- "integrity" "sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw=="
- "resolved" "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz"
- "version" "10.6.0"
- dependencies:
- "@babel/runtime" "^7.3.1"
- "jss" "10.6.0"
-
-"jss-plugin-rule-value-function@^10.5.1":
- "integrity" "sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA=="
- "resolved" "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz"
- "version" "10.6.0"
- dependencies:
- "@babel/runtime" "^7.3.1"
- "jss" "10.6.0"
- "tiny-warning" "^1.0.2"
-
-"jss-plugin-vendor-prefixer@^10.5.1":
- "integrity" "sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ=="
- "resolved" "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz"
- "version" "10.6.0"
- dependencies:
- "@babel/runtime" "^7.3.1"
- "css-vendor" "^2.0.8"
- "jss" "10.6.0"
-
-"jss@^10.5.1", "jss@10.6.0":
- "integrity" "sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw=="
- "resolved" "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz"
- "version" "10.6.0"
- dependencies:
- "@babel/runtime" "^7.3.1"
- "csstype" "^3.0.2"
- "indefinite-observable" "^2.0.1"
- "is-in-browser" "^1.1.3"
- "tiny-warning" "^1.0.2"
-
-"jsx-ast-utils@^2.4.1":
- "integrity" "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w=="
- "resolved" "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz"
- "version" "2.4.1"
- dependencies:
- "array-includes" "^3.1.1"
- "object.assign" "^4.1.0"
-
-"just-extend@^4.0.2":
- "integrity" "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA=="
- "resolved" "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz"
- "version" "4.1.0"
-
-"kind-of@^3.0.2", "kind-of@^3.0.3":
- "integrity" "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ=="
- "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"
- "version" "3.2.2"
- dependencies:
- "is-buffer" "^1.1.5"
-
-"kind-of@^3.2.0":
- "integrity" "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ=="
- "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz"
- "version" "3.2.2"
- dependencies:
- "is-buffer" "^1.1.5"
-
-"kind-of@^4.0.0":
- "integrity" "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw=="
- "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz"
- "version" "4.0.0"
- dependencies:
- "is-buffer" "^1.1.5"
-
-"kind-of@^5.0.0":
- "integrity" "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
- "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz"
- "version" "5.1.0"
-
-"kind-of@^6.0.0", "kind-of@^6.0.2":
- "integrity" "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
- "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz"
- "version" "6.0.3"
-
-"kleur@^3.0.3":
- "integrity" "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="
- "resolved" "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz"
- "version" "3.0.3"
-
-"language-subtag-registry@~0.3.2":
- "integrity" "sha512-KPMwROklF4tEx283Xw0pNKtfTj1gZ4UByp4EsIFWLgBavJltF4TiYPc39k06zSTsLzxTVXXDSpbwaQXaFB4Qeg=="
- "resolved" "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz"
- "version" "0.3.20"
-
-"language-tags@^1.0.5":
- "integrity" "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ=="
- "resolved" "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz"
- "version" "1.0.5"
- dependencies:
- "language-subtag-registry" "~0.3.2"
-
-"leven@^3.1.0":
- "integrity" "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="
- "resolved" "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz"
- "version" "3.1.0"
-
-"levn@^0.3.0", "levn@~0.3.0":
- "integrity" "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA=="
- "resolved" "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz"
- "version" "0.3.0"
- dependencies:
- "prelude-ls" "~1.1.2"
- "type-check" "~0.3.2"
-
-"lines-and-columns@^1.1.6":
- "integrity" "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ==sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ== sha512-8ZmlJFVK9iCmtLz19HpSsR8HaAMWBT284VMNednLwlIMDP2hJDCIhUp0IZ2xUcZ+Ob6BM0VvCSJwzASDM45NLQ=="
- "resolved" "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz"
- "version" "1.1.6"
-
-"load-json-file@^2.0.0":
- "integrity" "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ== sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ=="
- "resolved" "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "graceful-fs" "^4.1.2"
- "parse-json" "^2.2.0"
- "pify" "^2.0.0"
- "strip-bom" "^3.0.0"
-
-"loader-runner@^2.4.0":
- "integrity" "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw=="
- "resolved" "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz"
- "version" "2.4.0"
-
-"loader-utils@^1.0.1", "loader-utils@^1.0.2", "loader-utils@^1.1.0", "loader-utils@^1.2.3", "loader-utils@^1.4.0":
- "integrity" "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg=="
- "resolved" "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz"
- "version" "1.4.2"
- dependencies:
- "big.js" "^5.2.2"
- "emojis-list" "^3.0.0"
- "json5" "^1.0.1"
-
-"locate-path@^2.0.0":
- "integrity" "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA=="
- "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "p-locate" "^2.0.0"
- "path-exists" "^3.0.0"
-
-"locate-path@^3.0.0":
- "integrity" "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="
- "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "p-locate" "^3.0.0"
- "path-exists" "^3.0.0"
-
-"locate-path@^5.0.0":
- "integrity" "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="
- "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz"
- "version" "5.0.0"
- dependencies:
- "p-locate" "^4.1.0"
-
-"lodash.clone@^4.5.0":
- "integrity" "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg== sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg=="
- "resolved" "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz"
- "version" "4.5.0"
-
-"lodash.curry@^4.0.1":
- "integrity" "sha1-JI42By7ekGUB11lmIAqG2riyMXA=sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA== sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA=="
- "resolved" "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz"
- "version" "4.1.1"
-
-"lodash.debounce@^4.0.8":
- "integrity" "sha1-gteb/zCmfEAF/9XiUVMArZyk168=sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
- "resolved" "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz"
- "version" "4.0.8"
-
-"lodash.escape@^4.0.1":
- "integrity" "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw== sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw=="
- "resolved" "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz"
- "version" "4.0.1"
-
-"lodash.flattendeep@^4.4.0":
- "integrity" "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ== sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ=="
- "resolved" "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz"
- "version" "4.4.0"
-
-"lodash.flow@^3.3.0":
- "integrity" "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw== sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw=="
- "resolved" "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz"
- "version" "3.5.0"
-
-"lodash.isequal@^4.5.0":
- "integrity" "sha1-QVxEePK8wwEgwizhDtMib30+GOA=sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
- "resolved" "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz"
- "version" "4.5.0"
-
-"lodash.merge@^4.6.0":
- "integrity" "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
- "resolved" "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
- "version" "4.6.2"
-
-"lodash.unescape@4.0.1":
- "integrity" "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg== sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg=="
- "resolved" "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz"
- "version" "4.0.1"
-
-"lodash@^4.16.3", "lodash@^4.17.10", "lodash@^4.17.11", "lodash@^4.17.14", "lodash@^4.17.15", "lodash@^4.17.16", "lodash@^4.17.19", "lodash@^4.17.20", "lodash@^4.17.21", "lodash@^4.17.4", "lodash@^4.7.0", "lodash@4.x":
- "integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
- "version" "4.17.21"
-
-"lolex@^4.2.0":
- "integrity" "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg=="
- "resolved" "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz"
- "version" "4.2.0"
-
-"lolex@^5.0.1":
- "integrity" "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A=="
- "resolved" "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz"
- "version" "5.1.2"
- dependencies:
- "@sinonjs/commons" "^1.7.0"
-
-"loose-envify@^1.0.0", "loose-envify@^1.1.0", "loose-envify@^1.2.0", "loose-envify@^1.3.1", "loose-envify@^1.4.0":
- "integrity" "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="
- "resolved" "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
- "version" "1.4.0"
- dependencies:
- "js-tokens" "^3.0.0 || ^4.0.0"
-
-"lru-cache@^5.1.1":
- "integrity" "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="
- "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz"
- "version" "5.1.1"
- dependencies:
- "yallist" "^3.0.2"
-
-"lunr@^2.3.8":
- "integrity" "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
- "resolved" "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz"
- "version" "2.3.9"
-
-"lz-string@^1.4.4":
- "integrity" "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ=="
- "resolved" "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz"
- "version" "1.4.4"
-
-"make-dir@^2.0.0":
- "integrity" "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA=="
- "resolved" "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "pify" "^4.0.1"
- "semver" "^5.6.0"
-
-"make-dir@^3.0.0":
- "integrity" "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw=="
- "resolved" "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "semver" "^6.0.0"
-
-"make-error@^1.1.1", "make-error@1.x":
- "integrity" "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
- "resolved" "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz"
- "version" "1.3.6"
-
-"makeerror@1.0.x":
- "integrity" "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=sha512-M/XvMZ6oK4edXjvg/ZYyzByg8kjpVrF/m0x3wbhOlzJfsQgFkqP1rJnLnJExOcslmLSSeLiN6NmF+cBoKJHGTg==sha512-M/XvMZ6oK4edXjvg/ZYyzByg8kjpVrF/m0x3wbhOlzJfsQgFkqP1rJnLnJExOcslmLSSeLiN6NmF+cBoKJHGTg==sha512-M/XvMZ6oK4edXjvg/ZYyzByg8kjpVrF/m0x3wbhOlzJfsQgFkqP1rJnLnJExOcslmLSSeLiN6NmF+cBoKJHGTg==sha512-M/XvMZ6oK4edXjvg/ZYyzByg8kjpVrF/m0x3wbhOlzJfsQgFkqP1rJnLnJExOcslmLSSeLiN6NmF+cBoKJHGTg==sha512-M/XvMZ6oK4edXjvg/ZYyzByg8kjpVrF/m0x3wbhOlzJfsQgFkqP1rJnLnJExOcslmLSSeLiN6NmF+cBoKJHGTg==sha512-M/XvMZ6oK4edXjvg/ZYyzByg8kjpVrF/m0x3wbhOlzJfsQgFkqP1rJnLnJExOcslmLSSeLiN6NmF+cBoKJHGTg==sha512-M/XvMZ6oK4edXjvg/ZYyzByg8kjpVrF/m0x3wbhOlzJfsQgFkqP1rJnLnJExOcslmLSSeLiN6NmF+cBoKJHGTg== sha512-M/XvMZ6oK4edXjvg/ZYyzByg8kjpVrF/m0x3wbhOlzJfsQgFkqP1rJnLnJExOcslmLSSeLiN6NmF+cBoKJHGTg=="
- "resolved" "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz"
- "version" "1.0.11"
- dependencies:
- "tmpl" "1.0.x"
-
-"map-cache@^0.2.2":
- "integrity" "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="
- "resolved" "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz"
- "version" "0.2.2"
-
-"map-visit@^1.0.0":
- "integrity" "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w=="
- "resolved" "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "object-visit" "^1.0.0"
-
-"marked@1.0.0":
- "integrity" "sha512-Wo+L1pWTVibfrSr+TTtMuiMfNzmZWiOPeO7rZsQUY5bgsxpHesBEcIWJloWVTFnrMXnf/TL30eTFSGJddmQAng=="
- "resolved" "https://registry.npmjs.org/marked/-/marked-1.0.0.tgz"
- "version" "1.0.0"
-
-"math-expression-evaluator@^1.2.14":
- "integrity" "sha512-nrbaifCl42w37hYd6oRLvoymFK42tWB+WQTMFtksDGQMi5GvlJwnz/CsS30FFAISFLtX+A0csJ0xLiuuyyec7w=="
- "resolved" "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.3.7.tgz"
- "version" "1.3.7"
-
-"md5.js@^1.3.4":
- "integrity" "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg=="
- "resolved" "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz"
- "version" "1.3.5"
- dependencies:
- "hash-base" "^3.0.0"
- "inherits" "^2.0.1"
- "safe-buffer" "^5.1.2"
-
-"media-typer@0.3.0":
- "integrity" "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
- "resolved" "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz"
- "version" "0.3.0"
-
-"memoize-one@^5.0.0":
- "integrity" "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA=="
- "resolved" "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz"
- "version" "5.1.1"
-
-"memory-fs@^0.4.1":
- "integrity" "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ=="
- "resolved" "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz"
- "version" "0.4.1"
- dependencies:
- "errno" "^0.1.3"
- "readable-stream" "^2.0.1"
-
-"memory-fs@^0.5.0":
- "integrity" "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA=="
- "resolved" "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz"
- "version" "0.5.0"
- dependencies:
- "errno" "^0.1.3"
- "readable-stream" "^2.0.1"
-
-"merge-descriptors@1.0.1":
- "integrity" "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
- "resolved" "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz"
- "version" "1.0.1"
-
-"merge-stream@^2.0.0":
- "integrity" "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
- "resolved" "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
- "version" "2.0.0"
-
-"methods@~1.1.2":
- "integrity" "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
- "resolved" "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz"
- "version" "1.1.2"
-
-"micromatch@^3.0.4":
- "integrity" "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg=="
- "resolved" "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz"
- "version" "3.1.10"
- dependencies:
- "arr-diff" "^4.0.0"
- "array-unique" "^0.3.2"
- "braces" "^2.3.1"
- "define-property" "^2.0.2"
- "extend-shallow" "^3.0.2"
- "extglob" "^2.0.4"
- "fragment-cache" "^0.2.1"
- "kind-of" "^6.0.2"
- "nanomatch" "^1.2.9"
- "object.pick" "^1.3.0"
- "regex-not" "^1.0.0"
- "snapdragon" "^0.8.1"
- "to-regex" "^3.0.2"
-
-"micromatch@^3.1.10", "micromatch@^3.1.4":
- "integrity" "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg=="
- "resolved" "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz"
- "version" "3.1.10"
- dependencies:
- "arr-diff" "^4.0.0"
- "array-unique" "^0.3.2"
- "braces" "^2.3.1"
- "define-property" "^2.0.2"
- "extend-shallow" "^3.0.2"
- "extglob" "^2.0.4"
- "fragment-cache" "^0.2.1"
- "kind-of" "^6.0.2"
- "nanomatch" "^1.2.9"
- "object.pick" "^1.3.0"
- "regex-not" "^1.0.0"
- "snapdragon" "^0.8.1"
- "to-regex" "^3.0.2"
-
-"micromatch@^4.0.0", "micromatch@^4.0.2":
- "integrity" "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA=="
- "resolved" "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
- "version" "4.0.5"
- dependencies:
- "braces" "^3.0.2"
- "picomatch" "^2.3.1"
-
-"miller-rabin@^4.0.0":
- "integrity" "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA=="
- "resolved" "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz"
- "version" "4.0.1"
- dependencies:
- "bn.js" "^4.0.0"
- "brorand" "^1.0.1"
-
-"mime-db@1.52.0":
- "integrity" "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
- "resolved" "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
- "version" "1.52.0"
-
-"mime-types@^2.1.12", "mime-types@~2.1.24", "mime-types@~2.1.34":
- "integrity" "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="
- "resolved" "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
- "version" "2.1.35"
- dependencies:
- "mime-db" "1.52.0"
-
-"mime@1.6.0":
- "integrity" "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
- "resolved" "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz"
- "version" "1.6.0"
-
-"mimic-fn@^2.1.0":
- "integrity" "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
- "resolved" "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
- "version" "2.1.0"
-
-"min-indent@^1.0.0":
- "integrity" "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
- "resolved" "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz"
- "version" "1.0.1"
-
-"mini-create-react-context@^0.4.0":
- "integrity" "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA=="
- "resolved" "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz"
- "version" "0.4.0"
- dependencies:
- "@babel/runtime" "^7.5.5"
- "tiny-warning" "^1.0.3"
-
-"minimalistic-assert@^1.0.0", "minimalistic-assert@^1.0.1":
- "integrity" "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
- "resolved" "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz"
- "version" "1.0.1"
-
-"minimalistic-crypto-utils@^1.0.1":
- "integrity" "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="
- "resolved" "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz"
- "version" "1.0.1"
-
-"minimatch@^3.0.0", "minimatch@^3.0.4":
- "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="
- "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
- "version" "3.1.2"
- dependencies:
- "brace-expansion" "^1.1.7"
-
-"minimist@^1.1.1", "minimist@^1.2.0", "minimist@^1.2.5":
- "integrity" "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
- "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz"
- "version" "1.2.6"
-
-"mississippi@^3.0.0":
- "integrity" "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA=="
- "resolved" "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "concat-stream" "^1.5.0"
- "duplexify" "^3.4.2"
- "end-of-stream" "^1.1.0"
- "flush-write-stream" "^1.0.0"
- "from2" "^2.1.0"
- "parallel-transform" "^1.1.0"
- "pump" "^3.0.0"
- "pumpify" "^1.3.3"
- "stream-each" "^1.1.0"
- "through2" "^2.0.0"
-
-"mixin-deep@^1.2.0":
- "integrity" "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA=="
- "resolved" "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz"
- "version" "1.3.2"
- dependencies:
- "for-in" "^1.0.2"
- "is-extendable" "^1.0.1"
-
-"mkdirp-classic@^0.5.2":
- "integrity" "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
- "resolved" "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz"
- "version" "0.5.3"
-
-"mkdirp@^0.5.1", "mkdirp@^0.5.3":
- "integrity" "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ=="
- "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz"
- "version" "0.5.5"
- dependencies:
- "minimist" "^1.2.5"
-
-"mkdirp@1.x":
- "integrity" "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
- "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
- "version" "1.0.4"
-
-"moo@^0.5.0":
- "integrity" "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w=="
- "resolved" "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz"
- "version" "0.5.1"
-
-"move-concurrently@^1.0.1":
- "integrity" "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ=="
- "resolved" "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "aproba" "^1.1.1"
- "copy-concurrently" "^1.0.0"
- "fs-write-stream-atomic" "^1.0.8"
- "mkdirp" "^0.5.1"
- "rimraf" "^2.5.4"
- "run-queue" "^1.0.3"
-
-"ms@2.0.0":
- "integrity" "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- "resolved" "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
- "version" "2.0.0"
-
-"ms@2.1.2":
- "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
- "version" "2.1.2"
-
-"ms@2.1.3":
- "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
- "version" "2.1.3"
-
-"mute-stream@0.0.8":
- "integrity" "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
- "resolved" "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
- "version" "0.0.8"
-
-"nanomatch@^1.2.9":
- "integrity" "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA=="
- "resolved" "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz"
- "version" "1.2.13"
- dependencies:
- "arr-diff" "^4.0.0"
- "array-unique" "^0.3.2"
- "define-property" "^2.0.2"
- "extend-shallow" "^3.0.2"
- "fragment-cache" "^0.2.1"
- "is-windows" "^1.0.2"
- "kind-of" "^6.0.2"
- "object.pick" "^1.3.0"
- "regex-not" "^1.0.0"
- "snapdragon" "^0.8.1"
- "to-regex" "^3.0.1"
-
-"natural-compare@^1.4.0":
- "integrity" "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
- "resolved" "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
- "version" "1.4.0"
-
-"nearley@^2.7.10":
- "integrity" "sha512-oqj3m4oqwKsN77pETa9IPvxHHHLW68KrDc2KYoWMUOhDlrNUo7finubwffQMBRnwNCOXc4kRxCZO0Rvx4L6Zrw=="
- "resolved" "https://registry.npmjs.org/nearley/-/nearley-2.19.4.tgz"
- "version" "2.19.4"
- dependencies:
- "commander" "^2.19.0"
- "moo" "^0.5.0"
- "railroad-diagrams" "^1.0.0"
- "randexp" "0.4.6"
- "semver" "^5.4.1"
-
-"negotiator@0.6.3":
- "integrity" "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
- "resolved" "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
- "version" "0.6.3"
-
-"neo-async@^2.5.0", "neo-async@^2.6.0", "neo-async@^2.6.1":
- "integrity" "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
- "resolved" "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz"
- "version" "2.6.2"
-
-"nice-try@^1.0.4":
- "integrity" "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
- "resolved" "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz"
- "version" "1.0.5"
-
-"nise@^1.5.2":
- "integrity" "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ=="
- "resolved" "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz"
- "version" "1.5.3"
- dependencies:
- "@sinonjs/formatio" "^3.2.1"
- "@sinonjs/text-encoding" "^0.7.1"
- "just-extend" "^4.0.2"
- "lolex" "^5.0.1"
- "path-to-regexp" "^1.7.0"
-
-"node-fetch@2.6.7":
- "integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="
- "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz"
- "version" "2.6.7"
- dependencies:
- "whatwg-url" "^5.0.0"
-
-"node-int64@^0.4.0":
- "integrity" "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="
- "resolved" "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz"
- "version" "0.4.0"
-
-"node-libs-browser@^2.2.1":
- "integrity" "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q=="
- "resolved" "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz"
- "version" "2.2.1"
- dependencies:
- "assert" "^1.1.1"
- "browserify-zlib" "^0.2.0"
- "buffer" "^4.3.0"
- "console-browserify" "^1.1.0"
- "constants-browserify" "^1.0.0"
- "crypto-browserify" "^3.11.0"
- "domain-browser" "^1.1.1"
- "events" "^3.0.0"
- "https-browserify" "^1.0.0"
- "os-browserify" "^0.3.0"
- "path-browserify" "0.0.1"
- "process" "^0.11.10"
- "punycode" "^1.2.4"
- "querystring-es3" "^0.2.0"
- "readable-stream" "^2.3.3"
- "stream-browserify" "^2.0.1"
- "stream-http" "^2.7.2"
- "string_decoder" "^1.0.0"
- "timers-browserify" "^2.0.4"
- "tty-browserify" "0.0.0"
- "url" "^0.11.0"
- "util" "^0.11.0"
- "vm-browserify" "^1.0.1"
-
-"node-notifier@^8.0.0":
- "integrity" "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg=="
- "resolved" "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz"
- "version" "8.0.2"
- dependencies:
- "growly" "^1.3.0"
- "is-wsl" "^2.2.0"
- "semver" "^7.3.2"
- "shellwords" "^0.1.1"
- "uuid" "^8.3.0"
- "which" "^2.0.2"
-
-"node-releases@^2.0.6":
- "integrity" "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg=="
- "resolved" "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz"
- "version" "2.0.6"
-
-"normalize-package-data@^2.3.2", "normalize-package-data@^2.5.0":
- "integrity" "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA=="
- "resolved" "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz"
- "version" "2.5.0"
- dependencies:
- "hosted-git-info" "^2.1.4"
- "resolve" "^1.10.0"
- "semver" "2 || 3 || 4 || 5"
- "validate-npm-package-license" "^3.0.1"
-
-"normalize-path@^2.1.1":
- "integrity" "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w=="
- "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "remove-trailing-separator" "^1.0.1"
-
-"normalize-path@^3.0.0", "normalize-path@~3.0.0":
- "integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
- "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
- "version" "3.0.0"
-
-"npm-run-path@^2.0.0":
- "integrity" "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw=="
- "resolved" "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "path-key" "^2.0.0"
-
-"npm-run-path@^4.0.0":
- "integrity" "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="
- "resolved" "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz"
- "version" "4.0.1"
- dependencies:
- "path-key" "^3.0.0"
-
-"nth-check@^2.0.1":
- "integrity" "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="
- "resolved" "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "boolbase" "^1.0.0"
-
-"nwsapi@^2.2.0":
- "integrity" "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ=="
- "resolved" "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz"
- "version" "2.2.0"
-
-"object-assign@^4.1.1", "object-assign@4.x":
- "integrity" "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
- "resolved" "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
- "version" "4.1.1"
-
-"object-copy@^0.1.0":
- "integrity" "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ=="
- "resolved" "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz"
- "version" "0.1.0"
- dependencies:
- "copy-descriptor" "^0.1.0"
- "define-property" "^0.2.5"
- "kind-of" "^3.0.3"
-
-"object-inspect@^1.11.0", "object-inspect@^1.7.0", "object-inspect@^1.9.0":
- "integrity" "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g=="
- "resolved" "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz"
- "version" "1.12.0"
-
-"object-is@^1.0.2", "object-is@^1.1.2", "object-is@^1.1.5":
- "integrity" "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw=="
- "resolved" "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz"
- "version" "1.1.5"
- dependencies:
- "call-bind" "^1.0.2"
- "define-properties" "^1.1.3"
-
-"object-keys@^1.1.1":
- "integrity" "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
- "resolved" "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
- "version" "1.1.1"
-
-"object-visit@^1.0.0":
- "integrity" "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA=="
- "resolved" "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "isobject" "^3.0.0"
-
-"object.assign@^4.1.0", "object.assign@^4.1.2", "object.assign@^4.1.4":
- "integrity" "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ=="
- "resolved" "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz"
- "version" "4.1.4"
- dependencies:
- "call-bind" "^1.0.2"
- "define-properties" "^1.1.4"
- "has-symbols" "^1.0.3"
- "object-keys" "^1.1.1"
-
-"object.entries@^1.1.1", "object.entries@^1.1.2":
- "integrity" "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA=="
- "resolved" "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz"
- "version" "1.1.2"
- dependencies:
- "define-properties" "^1.1.3"
- "es-abstract" "^1.17.5"
- "has" "^1.0.3"
-
-"object.fromentries@^2.0.2", "object.fromentries@^2.0.3":
- "integrity" "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ=="
- "resolved" "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz"
- "version" "2.0.4"
- dependencies:
- "call-bind" "^1.0.2"
- "define-properties" "^1.1.3"
- "es-abstract" "^1.18.0-next.2"
- "has" "^1.0.3"
-
-"object.pick@^1.3.0":
- "integrity" "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ=="
- "resolved" "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz"
- "version" "1.3.0"
- dependencies:
- "isobject" "^3.0.1"
-
-"object.values@^1.1.1", "object.values@^1.1.2":
- "integrity" "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw=="
- "resolved" "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz"
- "version" "1.1.3"
- dependencies:
- "call-bind" "^1.0.2"
- "define-properties" "^1.1.3"
- "es-abstract" "^1.18.0-next.2"
- "has" "^1.0.3"
-
-"on-finished@2.4.1":
- "integrity" "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="
- "resolved" "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz"
- "version" "2.4.1"
- dependencies:
- "ee-first" "1.1.1"
-
-"once@^1.3.0", "once@^1.3.1", "once@^1.4.0":
- "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="
- "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
- "version" "1.4.0"
- dependencies:
- "wrappy" "1"
-
-"onetime@^5.1.0":
- "integrity" "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="
- "resolved" "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz"
- "version" "5.1.2"
- dependencies:
- "mimic-fn" "^2.1.0"
-
-"optionator@^0.8.1", "optionator@^0.8.3":
- "integrity" "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA=="
- "resolved" "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz"
- "version" "0.8.3"
- dependencies:
- "deep-is" "~0.1.3"
- "fast-levenshtein" "~2.0.6"
- "levn" "~0.3.0"
- "prelude-ls" "~1.1.2"
- "type-check" "~0.3.2"
- "word-wrap" "~1.2.3"
-
-"os-browserify@^0.3.0":
- "integrity" "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A=="
- "resolved" "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz"
- "version" "0.3.0"
-
-"os-tmpdir@~1.0.2":
- "integrity" "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g=="
- "resolved" "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz"
- "version" "1.0.2"
-
-"p-each-series@^2.1.0":
- "integrity" "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA=="
- "resolved" "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz"
- "version" "2.2.0"
-
-"p-finally@^1.0.0":
- "integrity" "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow=="
- "resolved" "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz"
- "version" "1.0.0"
-
-"p-limit@^1.1.0":
- "integrity" "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q=="
- "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz"
- "version" "1.3.0"
- dependencies:
- "p-try" "^1.0.0"
-
-"p-limit@^2.0.0", "p-limit@^2.2.0":
- "integrity" "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="
- "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz"
- "version" "2.3.0"
- dependencies:
- "p-try" "^2.0.0"
-
-"p-locate@^2.0.0":
- "integrity" "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg=="
- "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "p-limit" "^1.1.0"
-
-"p-locate@^3.0.0":
- "integrity" "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="
- "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "p-limit" "^2.0.0"
-
-"p-locate@^4.1.0":
- "integrity" "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="
- "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz"
- "version" "4.1.0"
- dependencies:
- "p-limit" "^2.2.0"
-
-"p-try@^1.0.0":
- "integrity" "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww=="
- "resolved" "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz"
- "version" "1.0.0"
-
-"p-try@^2.0.0":
- "integrity" "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
- "resolved" "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
- "version" "2.2.0"
-
-"pako@~1.0.5":
- "integrity" "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
- "resolved" "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz"
- "version" "1.0.11"
-
-"parallel-transform@^1.1.0":
- "integrity" "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg=="
- "resolved" "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz"
- "version" "1.2.0"
- dependencies:
- "cyclist" "^1.0.1"
- "inherits" "^2.0.3"
- "readable-stream" "^2.1.5"
-
-"parent-module@^1.0.0":
- "integrity" "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="
- "resolved" "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "callsites" "^3.0.0"
-
-"parse-asn1@^5.0.0", "parse-asn1@^5.1.5":
- "integrity" "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ=="
- "resolved" "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz"
- "version" "5.1.5"
- dependencies:
- "asn1.js" "^4.0.0"
- "browserify-aes" "^1.0.0"
- "create-hash" "^1.1.0"
- "evp_bytestokey" "^1.0.0"
- "pbkdf2" "^3.0.3"
- "safe-buffer" "^5.1.1"
-
-"parse-json@^2.2.0":
- "integrity" "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ=="
- "resolved" "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz"
- "version" "2.2.0"
- dependencies:
- "error-ex" "^1.2.0"
-
-"parse-json@^4.0.0":
- "integrity" "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw=="
- "resolved" "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz"
- "version" "4.0.0"
- dependencies:
- "error-ex" "^1.3.1"
- "json-parse-better-errors" "^1.0.1"
-
-"parse-json@^5.0.0":
- "integrity" "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="
- "resolved" "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz"
- "version" "5.2.0"
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "error-ex" "^1.3.1"
- "json-parse-even-better-errors" "^2.3.0"
- "lines-and-columns" "^1.1.6"
-
-"parse-passwd@^1.0.0":
- "integrity" "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q=="
- "resolved" "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz"
- "version" "1.0.0"
-
-"parse5-htmlparser2-tree-adapter@^7.0.0":
- "integrity" "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g=="
- "resolved" "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz"
- "version" "7.0.0"
- dependencies:
- "domhandler" "^5.0.2"
- "parse5" "^7.0.0"
-
-"parse5@^7.0.0":
- "integrity" "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg=="
- "resolved" "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz"
- "version" "7.1.1"
- dependencies:
- "entities" "^4.4.0"
-
-"parse5@6.0.1":
- "integrity" "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
- "resolved" "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz"
- "version" "6.0.1"
-
-"parseurl@~1.3.3":
- "integrity" "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
- "resolved" "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz"
- "version" "1.3.3"
-
-"pascalcase@^0.1.1":
- "integrity" "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw=="
- "resolved" "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz"
- "version" "0.1.1"
-
-"path-browserify@0.0.1":
- "integrity" "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ=="
- "resolved" "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz"
- "version" "0.0.1"
-
-"path-dirname@^1.0.0":
- "integrity" "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q=="
- "resolved" "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz"
- "version" "1.0.2"
-
-"path-exists@^3.0.0":
- "integrity" "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="
- "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz"
- "version" "3.0.0"
-
-"path-exists@^4.0.0":
- "integrity" "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
- "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
- "version" "4.0.0"
-
-"path-is-absolute@^1.0.0":
- "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
- "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
- "version" "1.0.1"
-
-"path-key@^2.0.0", "path-key@^2.0.1":
- "integrity" "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="
- "resolved" "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz"
- "version" "2.0.1"
-
-"path-key@^3.0.0":
- "integrity" "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
- "resolved" "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
- "version" "3.1.1"
-
-"path-key@^3.1.0":
- "integrity" "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
- "resolved" "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
- "version" "3.1.1"
-
-"path-parse@^1.0.6":
- "integrity" "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
- "resolved" "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
- "version" "1.0.7"
-
-"path-to-regexp@^1.7.0":
- "integrity" "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA=="
- "resolved" "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz"
- "version" "1.8.0"
- dependencies:
- "isarray" "0.0.1"
-
-"path-to-regexp@0.1.7":
- "integrity" "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
- "resolved" "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz"
- "version" "0.1.7"
-
-"path-type@^2.0.0":
- "integrity" "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ== sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ=="
- "resolved" "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "pify" "^2.0.0"
-
-"path-type@^4.0.0":
- "integrity" "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
- "resolved" "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
- "version" "4.0.0"
-
-"pathval@^1.1.1":
- "integrity" "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ=="
- "resolved" "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz"
- "version" "1.1.1"
-
-"pbkdf2@^3.0.3":
- "integrity" "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg=="
- "resolved" "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz"
- "version" "3.1.1"
- dependencies:
- "create-hash" "^1.1.2"
- "create-hmac" "^1.1.4"
- "ripemd160" "^2.0.1"
- "safe-buffer" "^5.0.1"
- "sha.js" "^2.4.8"
-
-"pend@~1.2.0":
- "integrity" "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
- "resolved" "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz"
- "version" "1.2.0"
-
-"performance-now@^2.1.0":
- "integrity" "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
- "resolved" "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz"
- "version" "2.1.0"
-
-"picocolors@^0.2.1":
- "integrity" "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
- "resolved" "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz"
- "version" "0.2.1"
-
-"picocolors@^1.0.0":
- "integrity" "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
- "resolved" "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
- "version" "1.0.0"
-
-"picomatch@^2.0.4", "picomatch@^2.2.1", "picomatch@^2.3.1":
- "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
- "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
- "version" "2.3.1"
-
-"pify@^2.0.0":
- "integrity" "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="
- "resolved" "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
- "version" "2.3.0"
-
-"pify@^4.0.1":
- "integrity" "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
- "resolved" "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz"
- "version" "4.0.1"
-
-"pirates@^4.0.1":
- "integrity" "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ=="
- "resolved" "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz"
- "version" "4.0.5"
-
-"pkg-dir@^2.0.0":
- "integrity" "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw== sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw=="
- "resolved" "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "find-up" "^2.1.0"
-
-"pkg-dir@^3.0.0":
- "integrity" "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw=="
- "resolved" "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "find-up" "^3.0.0"
-
-"pkg-dir@^4.2.0":
- "integrity" "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ=="
- "resolved" "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz"
- "version" "4.2.0"
- dependencies:
- "find-up" "^4.0.0"
-
-"pkg-dir@4.2.0":
- "integrity" "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ=="
- "resolved" "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz"
- "version" "4.2.0"
- dependencies:
- "find-up" "^4.0.0"
-
-"popper.js@1.16.1-lts":
- "integrity" "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
- "resolved" "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz"
- "version" "1.16.1-lts"
-
-"posix-character-classes@^0.1.0":
- "integrity" "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg=="
- "resolved" "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz"
- "version" "0.1.1"
-
-"postcss-modules-extract-imports@^2.0.0":
- "integrity" "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ=="
- "resolved" "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "postcss" "^7.0.5"
-
-"postcss-modules-local-by-default@^3.0.2":
- "integrity" "sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ=="
- "resolved" "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz"
- "version" "3.0.2"
- dependencies:
- "icss-utils" "^4.1.1"
- "postcss" "^7.0.16"
- "postcss-selector-parser" "^6.0.2"
- "postcss-value-parser" "^4.0.0"
-
-"postcss-modules-scope@^2.2.0":
- "integrity" "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ=="
- "resolved" "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz"
- "version" "2.2.0"
- dependencies:
- "postcss" "^7.0.6"
- "postcss-selector-parser" "^6.0.0"
-
-"postcss-modules-values@^3.0.0":
- "integrity" "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg=="
- "resolved" "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "icss-utils" "^4.0.0"
- "postcss" "^7.0.6"
-
-"postcss-selector-parser@^6.0.0", "postcss-selector-parser@^6.0.2":
- "integrity" "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg=="
- "resolved" "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz"
- "version" "6.0.2"
- dependencies:
- "cssesc" "^3.0.0"
- "indexes-of" "^1.0.1"
- "uniq" "^1.0.1"
-
-"postcss-value-parser@^4.0.0", "postcss-value-parser@^4.1.0":
- "integrity" "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
- "resolved" "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz"
- "version" "4.1.0"
-
-"postcss@^7.0.14", "postcss@^7.0.16", "postcss@^7.0.32", "postcss@^7.0.5", "postcss@^7.0.6":
- "integrity" "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA=="
- "resolved" "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz"
- "version" "7.0.39"
- dependencies:
- "picocolors" "^0.2.1"
- "source-map" "^0.6.1"
-
-"prelude-ls@~1.1.2":
- "integrity" "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w=="
- "resolved" "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz"
- "version" "1.1.2"
-
-"pretty-format@^24.0.0", "pretty-format@^24.9.0":
- "integrity" "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA=="
- "resolved" "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz"
- "version" "24.9.0"
- dependencies:
- "@jest/types" "^24.9.0"
- "ansi-regex" "^4.0.0"
- "ansi-styles" "^3.2.0"
- "react-is" "^16.8.4"
-
-"pretty-format@^25.2.1", "pretty-format@^25.5.0":
- "integrity" "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ=="
- "resolved" "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz"
- "version" "25.5.0"
- dependencies:
- "@jest/types" "^25.5.0"
- "ansi-regex" "^5.0.0"
- "ansi-styles" "^4.0.0"
- "react-is" "^16.12.0"
-
-"pretty-format@^26.6.2":
- "integrity" "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg=="
- "resolved" "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz"
- "version" "26.6.2"
- dependencies:
- "@jest/types" "^26.6.2"
- "ansi-regex" "^5.0.0"
- "ansi-styles" "^4.0.0"
- "react-is" "^17.0.1"
-
-"pretty-format@^27.0.2":
- "integrity" "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="
- "resolved" "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz"
- "version" "27.5.1"
- dependencies:
- "ansi-regex" "^5.0.1"
- "ansi-styles" "^5.0.0"
- "react-is" "^17.0.1"
-
-"process-nextick-args@~2.0.0":
- "integrity" "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
- "resolved" "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
- "version" "2.0.1"
-
-"process@^0.11.10":
- "integrity" "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
- "resolved" "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
- "version" "0.11.10"
-
-"progress@^2.0.0", "progress@^2.0.3", "progress@2.0.3":
- "integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
- "resolved" "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
- "version" "2.0.3"
-
-"promise-inflight@^1.0.1":
- "integrity" "sha1-mEcocL8igTL8vdhoEputEsPAKeM=sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="
- "resolved" "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz"
- "version" "1.0.1"
-
-"prompts@^2.0.1":
- "integrity" "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="
- "resolved" "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz"
- "version" "2.4.2"
- dependencies:
- "kleur" "^3.0.3"
- "sisteransi" "^1.0.5"
-
-"prop-types-exact@^1.2.0":
- "integrity" "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA=="
- "resolved" "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz"
- "version" "1.2.0"
- dependencies:
- "has" "^1.0.3"
- "object.assign" "^4.1.0"
- "reflect.ownkeys" "^0.2.0"
-
-"prop-types@^15.0.0", "prop-types@^15.5.10", "prop-types@^15.5.4", "prop-types@^15.5.7", "prop-types@^15.5.8", "prop-types@^15.6.0", "prop-types@^15.6.1", "prop-types@^15.6.2", "prop-types@^15.7.2", "prop-types@^15.8.1", "prop-types@15.x":
- "integrity" "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="
- "resolved" "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
- "version" "15.8.1"
- dependencies:
- "loose-envify" "^1.4.0"
- "object-assign" "^4.1.1"
- "react-is" "^16.13.1"
-
-"proxy-addr@~2.0.7":
- "integrity" "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="
- "resolved" "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz"
- "version" "2.0.7"
- dependencies:
- "forwarded" "0.2.0"
- "ipaddr.js" "1.9.1"
-
-"proxy-from-env@1.1.0":
- "integrity" "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
- "resolved" "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
- "version" "1.1.0"
-
-"prr@~1.0.1":
- "integrity" "sha1-0/wRS6BplaRexok/SEzrHXj19HY=sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw=="
- "resolved" "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz"
- "version" "1.0.1"
-
-"psl@^1.1.33":
- "integrity" "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
- "resolved" "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz"
- "version" "1.8.0"
-
-"public-encrypt@^4.0.0":
- "integrity" "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q=="
- "resolved" "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz"
- "version" "4.0.3"
- dependencies:
- "bn.js" "^4.1.0"
- "browserify-rsa" "^4.0.0"
- "create-hash" "^1.1.0"
- "parse-asn1" "^5.0.0"
- "randombytes" "^2.0.1"
- "safe-buffer" "^5.1.2"
-
-"pump@^2.0.0":
- "integrity" "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA=="
- "resolved" "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "end-of-stream" "^1.1.0"
- "once" "^1.3.1"
-
-"pump@^3.0.0":
- "integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="
- "resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "end-of-stream" "^1.1.0"
- "once" "^1.3.1"
-
-"pumpify@^1.3.3":
- "integrity" "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ=="
- "resolved" "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz"
- "version" "1.5.1"
- dependencies:
- "duplexify" "^3.6.0"
- "inherits" "^2.0.3"
- "pump" "^2.0.0"
-
-"punycode@^1.2.4":
- "integrity" "sha1-wNWmOycYgArY4esPpSachN1BhF4=sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
- "resolved" "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz"
- "version" "1.4.1"
-
-"punycode@^2.1.0", "punycode@^2.1.1":
- "integrity" "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
- "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
- "version" "2.1.1"
-
-"punycode@1.3.2":
- "integrity" "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="
- "resolved" "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz"
- "version" "1.3.2"
-
-"puppeteer@^14.3.0":
- "integrity" "sha512-pDtg1+vyw1UPIhUjh2/VW1HUdQnaZJHfMacrJciR3AVm+PBiqdCEcFeFb3UJ/CDEQlHOClm3/WFa7IjY25zIGg=="
- "resolved" "https://registry.npmjs.org/puppeteer/-/puppeteer-14.3.0.tgz"
- "version" "14.3.0"
- dependencies:
- "cross-fetch" "3.1.5"
- "debug" "4.3.4"
- "devtools-protocol" "0.0.1001819"
- "extract-zip" "2.0.1"
- "https-proxy-agent" "5.0.1"
- "pkg-dir" "4.2.0"
- "progress" "2.0.3"
- "proxy-from-env" "1.1.0"
- "rimraf" "3.0.2"
- "tar-fs" "2.1.1"
- "unbzip2-stream" "1.4.3"
- "ws" "8.7.0"
-
-"pure-color@^1.2.0":
- "integrity" "sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA== sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA=="
- "resolved" "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz"
- "version" "1.3.0"
-
-"qs@6.11.0":
- "integrity" "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q=="
- "resolved" "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz"
- "version" "6.11.0"
- dependencies:
- "side-channel" "^1.0.4"
-
-"querystring-es3@^0.2.0":
- "integrity" "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA=="
- "resolved" "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz"
- "version" "0.2.1"
-
-"querystring@0.2.0":
- "integrity" "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g=="
- "resolved" "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz"
- "version" "0.2.0"
-
-"raf@^3.4.0", "raf@^3.4.1":
- "integrity" "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA=="
- "resolved" "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz"
- "version" "3.4.1"
- dependencies:
- "performance-now" "^2.1.0"
-
-"railroad-diagrams@^1.0.0":
- "integrity" "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A== sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A=="
- "resolved" "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz"
- "version" "1.0.0"
-
-"randexp@0.4.6":
- "integrity" "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ=="
- "resolved" "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz"
- "version" "0.4.6"
- dependencies:
- "discontinuous-range" "1.0.0"
- "ret" "~0.1.10"
-
-"randombytes@^2.0.0", "randombytes@^2.0.1", "randombytes@^2.0.5", "randombytes@^2.1.0":
- "integrity" "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="
- "resolved" "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "safe-buffer" "^5.1.0"
-
-"randomfill@^1.0.3":
- "integrity" "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw=="
- "resolved" "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "randombytes" "^2.0.5"
- "safe-buffer" "^5.1.0"
-
-"range-parser@~1.2.1":
- "integrity" "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
- "resolved" "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz"
- "version" "1.2.1"
-
-"raw-body@2.5.1":
- "integrity" "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig=="
- "resolved" "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz"
- "version" "2.5.1"
- dependencies:
- "bytes" "3.1.2"
- "http-errors" "2.0.0"
- "iconv-lite" "0.4.24"
- "unpipe" "1.0.0"
-
-"rc-align@^2.4.0":
- "integrity" "sha512-nv9wYUYdfyfK+qskThf4BQUSIadeI/dCsfaMZfNEoxm9HwOIioQ+LyqmMK6jWHAZQgOzMLaqawhuBXlF63vgjw=="
- "resolved" "https://registry.npmjs.org/rc-align/-/rc-align-2.4.5.tgz"
- "version" "2.4.5"
- dependencies:
- "babel-runtime" "^6.26.0"
- "dom-align" "^1.7.0"
- "prop-types" "^15.5.8"
- "rc-util" "^4.0.4"
-
-"rc-animate@2.x":
- "integrity" "sha512-1NyuCGFJG/0Y+9RKh5y/i/AalUCA51opyyS/jO2seELpgymZm2u9QV3xwODwEuzkmeQ1BDPxMLmYLcTJedPlkQ=="
- "resolved" "https://registry.npmjs.org/rc-animate/-/rc-animate-2.11.1.tgz"
- "version" "2.11.1"
- dependencies:
- "babel-runtime" "6.x"
- "classnames" "^2.2.6"
- "css-animation" "^1.3.2"
- "prop-types" "15.x"
- "raf" "^3.4.0"
- "rc-util" "^4.15.3"
- "react-lifecycles-compat" "^3.0.4"
-
-"rc-slider@^8.7.1":
- "integrity" "sha512-WMT5mRFUEcrLWwTxsyS8jYmlaMsTVCZIGENLikHsNv+tE8ThU2lCoPfi/xFNUfJFNFSBFP3MwPez9ZsJmNp13g=="
- "resolved" "https://registry.npmjs.org/rc-slider/-/rc-slider-8.7.1.tgz"
- "version" "8.7.1"
- dependencies:
- "babel-runtime" "6.x"
- "classnames" "^2.2.5"
- "prop-types" "^15.5.4"
- "rc-tooltip" "^3.7.0"
- "rc-util" "^4.0.4"
- "react-lifecycles-compat" "^3.0.4"
- "shallowequal" "^1.1.0"
- "warning" "^4.0.3"
-
-"rc-tooltip@^3.7.0", "rc-tooltip@^3.7.3":
- "integrity" "sha512-dE2ibukxxkrde7wH9W8ozHKUO4aQnPZ6qBHtrTH9LoO836PjDdiaWO73fgPB05VfJs9FbZdmGPVEbXCeOP99Ww=="
- "resolved" "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-3.7.3.tgz"
- "version" "3.7.3"
- dependencies:
- "babel-runtime" "6.x"
- "prop-types" "^15.5.8"
- "rc-trigger" "^2.2.2"
-
-"rc-trigger@^2.2.2":
- "integrity" "sha512-m6Cts9hLeZWsTvWnuMm7oElhf+03GOjOLfTuU0QmdB9ZrW7jR2IpI5rpNM7i9MvAAlMAmTx5Zr7g3uu/aMvZAw=="
- "resolved" "https://registry.npmjs.org/rc-trigger/-/rc-trigger-2.6.5.tgz"
- "version" "2.6.5"
- dependencies:
- "babel-runtime" "6.x"
- "classnames" "^2.2.6"
- "prop-types" "15.x"
- "rc-align" "^2.4.0"
- "rc-animate" "2.x"
- "rc-util" "^4.4.0"
- "react-lifecycles-compat" "^3.0.4"
-
-"rc-util@^4.0.4", "rc-util@^4.15.3", "rc-util@^4.4.0":
- "integrity" "sha512-Z+vlkSQVc1l8O2UjR3WQ+XdWlhj5q9BMQNLk2iOBch75CqPfrJyGtcWMcnhRlNuDu0Ndtt4kLVO8JI8BrABobg=="
- "resolved" "https://registry.npmjs.org/rc-util/-/rc-util-4.21.1.tgz"
- "version" "4.21.1"
- dependencies:
- "add-dom-event-listener" "^1.1.0"
- "prop-types" "^15.5.10"
- "react-is" "^16.12.0"
- "react-lifecycles-compat" "^3.0.4"
- "shallowequal" "^1.1.0"
-
-"react-apexcharts@^1.3.7":
- "integrity" "sha512-2OFhEHd70/WHN0kmrJtVx37UfaL71ZogVkwezmDqwQWgwhK6upuhlnEEX7tEq4xvjA+RFDn6hiUTNIuC/Q7Zqw=="
- "resolved" "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.3.7.tgz"
- "version" "1.3.7"
- dependencies:
- "prop-types" "^15.5.7"
-
-"react-base16-styling@^0.5.1":
- "integrity" "sha1-OFjyTpxN2MvT9wLz901YHKKRcmk=sha512-EPuchwVvYPSFFIjGpH0k6wM0HQsmJ0vCk7BSl5ryxMVFIWW4hX4Kksu4PNtxfgOxDebTLkJQ8iC7zwAql0eusg==sha512-EPuchwVvYPSFFIjGpH0k6wM0HQsmJ0vCk7BSl5ryxMVFIWW4hX4Kksu4PNtxfgOxDebTLkJQ8iC7zwAql0eusg==sha512-EPuchwVvYPSFFIjGpH0k6wM0HQsmJ0vCk7BSl5ryxMVFIWW4hX4Kksu4PNtxfgOxDebTLkJQ8iC7zwAql0eusg==sha512-EPuchwVvYPSFFIjGpH0k6wM0HQsmJ0vCk7BSl5ryxMVFIWW4hX4Kksu4PNtxfgOxDebTLkJQ8iC7zwAql0eusg==sha512-EPuchwVvYPSFFIjGpH0k6wM0HQsmJ0vCk7BSl5ryxMVFIWW4hX4Kksu4PNtxfgOxDebTLkJQ8iC7zwAql0eusg==sha512-EPuchwVvYPSFFIjGpH0k6wM0HQsmJ0vCk7BSl5ryxMVFIWW4hX4Kksu4PNtxfgOxDebTLkJQ8iC7zwAql0eusg== sha512-EPuchwVvYPSFFIjGpH0k6wM0HQsmJ0vCk7BSl5ryxMVFIWW4hX4Kksu4PNtxfgOxDebTLkJQ8iC7zwAql0eusg=="
- "resolved" "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.5.3.tgz"
- "version" "0.5.3"
- dependencies:
- "base16" "^1.0.0"
- "lodash.curry" "^4.0.1"
- "lodash.flow" "^3.3.0"
- "pure-color" "^1.2.0"
-
-"react-dom@^15.0.0 || ^16.0.0", "react-dom@^15.0.0-0 || ^16.0.0-0", "react-dom@^16.0.0 || ^17.0.0", "react-dom@^16.0.0-0", "react-dom@^16.13.1", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^16.8.0-0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^18.0.0", "react-dom@>=16.13", "react-dom@>=16.6.0":
- "integrity" "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag=="
- "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz"
- "version" "16.13.1"
- dependencies:
- "loose-envify" "^1.1.0"
- "object-assign" "^4.1.1"
- "prop-types" "^15.6.2"
- "scheduler" "^0.19.1"
-
-"react-hover@^2.0.0":
- "integrity" "sha512-3fb7OsDCwR4CWBp+1gpy5LezyQnlCV5LxIk3FM+9RcO7ckMh+27rPHrPkld7jfBPO/ZTvNANkhZU9IFynSn+ZQ=="
- "resolved" "https://registry.npmjs.org/react-hover/-/react-hover-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "prop-types" "^15.5.10"
-
-"react-html-parser@^2.0.2":
- "integrity" "sha512-XeerLwCVjTs3njZcgCOeDUqLgNIt/t+6Jgi5/qPsO/krUWl76kWKXMeVs2LhY2gwM6X378DkhLjur0zUQdpz0g=="
- "resolved" "https://registry.npmjs.org/react-html-parser/-/react-html-parser-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "htmlparser2" "^3.9.0"
-
-"react-input-autosize@^3.0.0":
- "integrity" "sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg=="
- "resolved" "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "prop-types" "^15.5.8"
-
-"react-is@^16.12.0":
- "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- "version" "16.13.1"
-
-"react-is@^16.13.1":
- "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- "version" "16.13.1"
-
-"react-is@^16.6.0":
- "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- "version" "16.13.1"
-
-"react-is@^16.7.0":
- "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- "version" "16.13.1"
-
-"react-is@^16.8.0 || ^17.0.0", "react-is@^17.0.1", "react-is@^17.0.2":
- "integrity" "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
- "resolved" "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
- "version" "17.0.2"
-
-"react-is@^16.8.4":
- "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- "version" "16.13.1"
-
-"react-is@^16.8.6":
- "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- "version" "16.13.1"
-
-"react-json-tree@^0.11.2":
- "integrity" "sha512-aYhUPj1y5jR3ZQ+G3N7aL8FbTyO03iLwnVvvEikLcNFqNTyabdljo9xDftZndUBFyyyL0aK3qGO9+8EilILHUw=="
- "resolved" "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.11.2.tgz"
- "version" "0.11.2"
- dependencies:
- "babel-runtime" "^6.6.1"
- "prop-types" "^15.5.8"
- "react-base16-styling" "^0.5.1"
-
-"react-lifecycles-compat@^3.0.4":
- "integrity" "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
- "resolved" "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz"
- "version" "3.0.4"
-
-"react-router-dom@^5.2.0":
- "integrity" "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA=="
- "resolved" "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz"
- "version" "5.2.0"
- dependencies:
- "@babel/runtime" "^7.1.2"
- "history" "^4.9.0"
- "loose-envify" "^1.3.1"
- "prop-types" "^15.6.2"
- "react-router" "5.2.0"
- "tiny-invariant" "^1.0.2"
- "tiny-warning" "^1.0.0"
-
-"react-router@5.2.0":
- "integrity" "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw=="
- "resolved" "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz"
- "version" "5.2.0"
- dependencies:
- "@babel/runtime" "^7.1.2"
- "history" "^4.9.0"
- "hoist-non-react-statics" "^3.1.0"
- "loose-envify" "^1.3.1"
- "mini-create-react-context" "^0.4.0"
- "path-to-regexp" "^1.7.0"
- "prop-types" "^15.6.2"
- "react-is" "^16.6.0"
- "tiny-invariant" "^1.0.2"
- "tiny-warning" "^1.0.0"
-
-"react-select@^3.2.0":
- "integrity" "sha512-B/q3TnCZXEKItO0fFN/I0tWOX3WJvi/X2wtdffmwSQVRwg5BpValScTO1vdic9AxlUgmeSzib2hAZAwIUQUZGQ=="
- "resolved" "https://registry.npmjs.org/react-select/-/react-select-3.2.0.tgz"
- "version" "3.2.0"
- dependencies:
- "@babel/runtime" "^7.4.4"
- "@emotion/cache" "^10.0.9"
- "@emotion/core" "^10.0.9"
- "@emotion/css" "^10.0.9"
- "memoize-one" "^5.0.0"
- "prop-types" "^15.6.0"
- "react-input-autosize" "^3.0.0"
- "react-transition-group" "^4.3.0"
-
-"react-spinners@^0.11.0":
- "integrity" "sha512-rDZc0ABWn/M1OryboGsWVmIPg8uYWl0L35jPUhr40+Yg+syVPjeHwvnB7XWaRpaKus3M0cG9BiJA+ZB0dAwWyw=="
- "resolved" "https://registry.npmjs.org/react-spinners/-/react-spinners-0.11.0.tgz"
- "version" "0.11.0"
- dependencies:
- "@emotion/react" "^11.1.4"
-
-"react-split@^2.0.14":
- "integrity" "sha512-bKWydgMgaKTg/2JGQnaJPg51T6dmumTWZppFgEbbY0Fbme0F5TuatAScCLaqommbGQQf/ZT1zaejuPDriscISA=="
- "resolved" "https://registry.npmjs.org/react-split/-/react-split-2.0.14.tgz"
- "version" "2.0.14"
- dependencies:
- "prop-types" "^15.5.7"
- "split.js" "^1.6.0"
-
-"react-test-renderer@^16.0.0-0":
- "integrity" "sha512-Sn2VRyOK2YJJldOqoh8Tn/lWQ+ZiKhyZTPtaO0Q6yNj+QDbmRkVFap6pZPy3YQk8DScRDfyqm/KxKYP9gCMRiQ=="
- "resolved" "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.13.1.tgz"
- "version" "16.13.1"
- dependencies:
- "object-assign" "^4.1.1"
- "prop-types" "^15.6.2"
- "react-is" "^16.8.6"
- "scheduler" "^0.19.1"
-
-"react-transition-group@^4.3.0", "react-transition-group@^4.4.0", "react-transition-group@^4.4.2":
- "integrity" "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg=="
- "resolved" "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz"
- "version" "4.4.2"
- dependencies:
- "@babel/runtime" "^7.5.5"
- "dom-helpers" "^5.0.1"
- "loose-envify" "^1.4.0"
- "prop-types" "^15.6.2"
-
-"react-use-measure@^2.0.4":
- "integrity" "sha512-7K2HIGaPMl3Q9ZQiEVjen3tRXl4UDda8LiTPy/QxP8dP2rl5gPBhf7mMH6MVjjRNv3loU7sNzey/ycPNnHVTxQ=="
- "resolved" "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.0.4.tgz"
- "version" "2.0.4"
- dependencies:
- "debounce" "^1.2.0"
-
-"react@*", "react@^0.14 || ^15.0.0 || ^16.0.0-alpha", "react@^0.14.0 || ^15.0.0 || ^16.0.0", "react@^0.14.0 || ^15.0.0 || ^16.0.0-0", "react@^15.0.0 || ^16.0.0", "react@^15.0.0-0 || ^16.0.0-0", "react@^16.0.0 || ^17.0.0", "react@^16.0.0-0", "react@^16.13.1", "react@^16.14.0", "react@^16.3.0 || ^17.0.0", "react@^16.3.0-0", "react@^16.8.0 || ^17.0.0", "react@^16.8.0-0", "react@^17.0.0 || ^18.0.0", "react@^18.0.0", "react@>=0.13", "react@>=0.14.0", "react@>=15", "react@>=16.13", "react@>=16.3.0", "react@>=16.6.0", "react@>=16.8.0", "react@>=16.x", "react@0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0":
- "integrity" "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g=="
- "resolved" "https://registry.npmjs.org/react/-/react-16.14.0.tgz"
- "version" "16.14.0"
- dependencies:
- "loose-envify" "^1.1.0"
- "object-assign" "^4.1.1"
- "prop-types" "^15.6.2"
-
-"read-pkg-up@^2.0.0":
- "integrity" "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w== sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w=="
- "resolved" "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "find-up" "^2.0.0"
- "read-pkg" "^2.0.0"
-
-"read-pkg-up@^7.0.1":
- "integrity" "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg=="
- "resolved" "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz"
- "version" "7.0.1"
- dependencies:
- "find-up" "^4.1.0"
- "read-pkg" "^5.2.0"
- "type-fest" "^0.8.1"
-
-"read-pkg@^2.0.0":
- "integrity" "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA== sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA=="
- "resolved" "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "load-json-file" "^2.0.0"
- "normalize-package-data" "^2.3.2"
- "path-type" "^2.0.0"
-
-"read-pkg@^5.2.0":
- "integrity" "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg=="
- "resolved" "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz"
- "version" "5.2.0"
- dependencies:
- "@types/normalize-package-data" "^2.4.0"
- "normalize-package-data" "^2.5.0"
- "parse-json" "^5.0.0"
- "type-fest" "^0.6.0"
-
-"readable-stream@^2.0.0":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readable-stream@^2.0.1":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readable-stream@^2.0.2":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readable-stream@^2.1.5":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readable-stream@^2.2.2":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readable-stream@^2.3.3":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readable-stream@^2.3.6":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readable-stream@^3.1.1", "readable-stream@^3.4.0", "readable-stream@^3.6.0":
- "integrity" "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz"
- "version" "3.6.0"
- dependencies:
- "inherits" "^2.0.3"
- "string_decoder" "^1.1.1"
- "util-deprecate" "^1.0.1"
-
-"readable-stream@~2.3.6":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readable-stream@1 || 2":
- "integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
- "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
- "version" "2.3.7"
- dependencies:
- "core-util-is" "~1.0.0"
- "inherits" "~2.0.3"
- "isarray" "~1.0.0"
- "process-nextick-args" "~2.0.0"
- "safe-buffer" "~5.1.1"
- "string_decoder" "~1.1.1"
- "util-deprecate" "~1.0.1"
-
-"readdirp@^2.2.1":
- "integrity" "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ=="
- "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz"
- "version" "2.2.1"
- dependencies:
- "graceful-fs" "^4.1.11"
- "micromatch" "^3.1.10"
- "readable-stream" "^2.0.2"
-
-"readdirp@~3.4.0":
- "integrity" "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ=="
- "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz"
- "version" "3.4.0"
- dependencies:
- "picomatch" "^2.2.1"
-
-"rechoir@^0.6.2":
- "integrity" "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw=="
- "resolved" "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz"
- "version" "0.6.2"
- dependencies:
- "resolve" "^1.1.6"
-
-"recoil@0.0.10":
- "integrity" "sha512-+9gRqehw3yKETmoZbhSnWu4GO10HDb5xYf1CjLF1oXGK2uT6GX5Lu9mfTXwjxV/jXxEKx8MIRUUbgPxvbJ8SEw=="
- "resolved" "https://registry.npmjs.org/recoil/-/recoil-0.0.10.tgz"
- "version" "0.0.10"
-
-"redent@^3.0.0":
- "integrity" "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg=="
- "resolved" "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "indent-string" "^4.0.0"
- "strip-indent" "^3.0.0"
-
-"reduce-css-calc@^1.3.0":
- "integrity" "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA== sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA=="
- "resolved" "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz"
- "version" "1.3.0"
- dependencies:
- "balanced-match" "^0.4.2"
- "math-expression-evaluator" "^1.2.14"
- "reduce-function-call" "^1.0.1"
-
-"reduce-function-call@^1.0.1":
- "integrity" "sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ=="
- "resolved" "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz"
- "version" "1.0.3"
- dependencies:
- "balanced-match" "^1.0.0"
-
-"reflect.ownkeys@^0.2.0":
- "integrity" "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg==sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg==sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg==sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg==sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg==sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg== sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg=="
- "resolved" "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz"
- "version" "0.2.0"
-
-"regenerate-unicode-properties@^8.2.0":
- "integrity" "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA=="
- "resolved" "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz"
- "version" "8.2.0"
- dependencies:
- "regenerate" "^1.4.0"
-
-"regenerate@^1.4.0":
- "integrity" "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A=="
- "resolved" "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz"
- "version" "1.4.1"
-
-"regenerator-runtime@^0.11.0":
- "integrity" "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
- "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz"
- "version" "0.11.1"
-
-"regenerator-runtime@^0.13.4":
- "integrity" "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
- "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz"
- "version" "0.13.5"
-
-"regenerator-transform@^0.14.2":
- "integrity" "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw=="
- "resolved" "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz"
- "version" "0.14.5"
- dependencies:
- "@babel/runtime" "^7.8.4"
-
-"regex-not@^1.0.0", "regex-not@^1.0.2":
- "integrity" "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A=="
- "resolved" "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "extend-shallow" "^3.0.2"
- "safe-regex" "^1.1.0"
-
-"regexp.prototype.flags@^1.3.0", "regexp.prototype.flags@^1.4.3":
- "integrity" "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA=="
- "resolved" "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz"
- "version" "1.4.3"
- dependencies:
- "call-bind" "^1.0.2"
- "define-properties" "^1.1.3"
- "functions-have-names" "^1.2.2"
-
-"regexpp@^2.0.1":
- "integrity" "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw=="
- "resolved" "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz"
- "version" "2.0.1"
-
-"regexpp@^3.0.0":
- "integrity" "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q=="
- "resolved" "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz"
- "version" "3.1.0"
-
-"regexpu-core@^4.7.1":
- "integrity" "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ=="
- "resolved" "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz"
- "version" "4.7.1"
- dependencies:
- "regenerate" "^1.4.0"
- "regenerate-unicode-properties" "^8.2.0"
- "regjsgen" "^0.5.1"
- "regjsparser" "^0.6.4"
- "unicode-match-property-ecmascript" "^1.0.4"
- "unicode-match-property-value-ecmascript" "^1.2.0"
-
-"regjsgen@^0.5.1":
- "integrity" "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A=="
- "resolved" "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz"
- "version" "0.5.2"
-
-"regjsparser@^0.6.4":
- "integrity" "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw=="
- "resolved" "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz"
- "version" "0.6.4"
- dependencies:
- "jsesc" "~0.5.0"
-
-"remove-trailing-separator@^1.0.1":
- "integrity" "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="
- "resolved" "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz"
- "version" "1.1.0"
-
-"repeat-element@^1.1.2":
- "integrity" "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
- "resolved" "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz"
- "version" "1.1.3"
-
-"repeat-string@^1.6.1":
- "integrity" "sha1-jcrkcOHIirwtYA//Sndihtp15jc=sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w=="
- "resolved" "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz"
- "version" "1.6.1"
-
-"require-directory@^2.1.1":
- "integrity" "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
- "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz"
- "version" "2.1.1"
-
-"require-main-filename@^2.0.0":
- "integrity" "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
- "resolved" "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz"
- "version" "2.0.0"
-
-"resize-observer-polyfill@1.5.1":
- "integrity" "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
- "resolved" "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz"
- "version" "1.5.1"
-
-"resolve-cwd@^2.0.0":
- "integrity" "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg== sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg=="
- "resolved" "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "resolve-from" "^3.0.0"
-
-"resolve-cwd@^3.0.0":
- "integrity" "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg=="
- "resolved" "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "resolve-from" "^5.0.0"
-
-"resolve-dir@^1.0.0", "resolve-dir@^1.0.1":
- "integrity" "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg== sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg=="
- "resolved" "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "expand-tilde" "^2.0.0"
- "global-modules" "^1.0.0"
-
-"resolve-from@^3.0.0":
- "integrity" "sha1-six699nWiBvItuZTM17rywoYh0g=sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw=="
- "resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz"
- "version" "3.0.0"
-
-"resolve-from@^4.0.0":
- "integrity" "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
- "resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
- "version" "4.0.0"
-
-"resolve-from@^5.0.0":
- "integrity" "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="
- "resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz"
- "version" "5.0.0"
-
-"resolve-pathname@^3.0.0":
- "integrity" "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
- "resolved" "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz"
- "version" "3.0.0"
-
-"resolve-url@^0.2.1":
- "integrity" "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg=="
- "resolved" "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz"
- "version" "0.2.1"
-
-"resolve@^1.1.6", "resolve@^1.10.0", "resolve@^1.12.0", "resolve@^1.13.1", "resolve@^1.14.2", "resolve@^1.17.0", "resolve@^1.18.1":
- "integrity" "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A=="
- "resolved" "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz"
- "version" "1.20.0"
- dependencies:
- "is-core-module" "^2.2.0"
- "path-parse" "^1.0.6"
-
-"restore-cursor@^3.1.0":
- "integrity" "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA=="
- "resolved" "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "onetime" "^5.1.0"
- "signal-exit" "^3.0.2"
-
-"ret@~0.1.10":
- "integrity" "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
- "resolved" "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz"
- "version" "0.1.15"
-
-"rimraf@^2.5.4", "rimraf@^2.6.3", "rimraf@2.6.3":
- "integrity" "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="
- "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz"
- "version" "2.6.3"
- dependencies:
- "glob" "^7.1.3"
-
-"rimraf@^3.0.0":
- "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="
- "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
- "version" "3.0.2"
- dependencies:
- "glob" "^7.1.3"
-
-"rimraf@3.0.2":
- "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="
- "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
- "version" "3.0.2"
- dependencies:
- "glob" "^7.1.3"
-
-"ripemd160@^2.0.0", "ripemd160@^2.0.1":
- "integrity" "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA=="
- "resolved" "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "hash-base" "^3.0.0"
- "inherits" "^2.0.1"
-
-"robust-predicates@^3.0.0":
- "integrity" "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g=="
- "resolved" "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz"
- "version" "3.0.1"
-
-"rst-selector-parser@^2.2.3":
- "integrity" "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA== sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA=="
- "resolved" "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz"
- "version" "2.2.3"
- dependencies:
- "lodash.flattendeep" "^4.4.0"
- "nearley" "^2.7.10"
-
-"rsvp@^4.8.4":
- "integrity" "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA=="
- "resolved" "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz"
- "version" "4.8.5"
-
-"run-async@^2.4.0":
- "integrity" "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ=="
- "resolved" "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz"
- "version" "2.4.1"
-
-"run-queue@^1.0.0", "run-queue@^1.0.3":
- "integrity" "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg=="
- "resolved" "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz"
- "version" "1.0.3"
- dependencies:
- "aproba" "^1.1.1"
-
-"rw@1":
- "integrity" "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
- "resolved" "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz"
- "version" "1.3.3"
-
-"rxjs@^6.6.0":
- "integrity" "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg=="
- "resolved" "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz"
- "version" "6.6.0"
- dependencies:
- "tslib" "^1.9.0"
-
-"safe-buffer@^5.0.1", "safe-buffer@^5.1.0", "safe-buffer@^5.1.1", "safe-buffer@^5.1.2", "safe-buffer@~5.1.0", "safe-buffer@~5.1.1":
- "integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
- "version" "5.1.2"
-
-"safe-buffer@^5.2.0":
- "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
- "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
- "version" "5.2.1"
-
-"safe-buffer@~5.2.0":
- "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
- "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
- "version" "5.2.1"
-
-"safe-buffer@5.2.1":
- "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
- "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
- "version" "5.2.1"
-
-"safe-regex@^1.1.0":
- "integrity" "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg=="
- "resolved" "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz"
- "version" "1.1.0"
- dependencies:
- "ret" "~0.1.10"
-
-"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
- "integrity" "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- "resolved" "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
- "version" "2.1.2"
-
-"sane@^4.0.3":
- "integrity" "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA=="
- "resolved" "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz"
- "version" "4.1.0"
- dependencies:
- "@cnakazawa/watch" "^1.0.3"
- "anymatch" "^2.0.0"
- "capture-exit" "^2.0.0"
- "exec-sh" "^0.3.2"
- "execa" "^1.0.0"
- "fb-watchman" "^2.0.0"
- "micromatch" "^3.1.4"
- "minimist" "^1.1.1"
- "walker" "~1.0.5"
-
-"sass-loader@^7.3.1":
- "integrity" "sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA=="
- "resolved" "https://registry.npmjs.org/sass-loader/-/sass-loader-7.3.1.tgz"
- "version" "7.3.1"
- dependencies:
- "clone-deep" "^4.0.1"
- "loader-utils" "^1.0.1"
- "neo-async" "^2.5.0"
- "pify" "^4.0.1"
- "semver" "^6.3.0"
-
-"sass@^1.26.10":
- "integrity" "sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw=="
- "resolved" "https://registry.npmjs.org/sass/-/sass-1.26.10.tgz"
- "version" "1.26.10"
- dependencies:
- "chokidar" ">=2.0.0 <4.0.0"
-
-"saxes@^5.0.1":
- "integrity" "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw=="
- "resolved" "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz"
- "version" "5.0.1"
- dependencies:
- "xmlchars" "^2.2.0"
-
-"scheduler@^0.19.1":
- "integrity" "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA=="
- "resolved" "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz"
- "version" "0.19.1"
- dependencies:
- "loose-envify" "^1.1.0"
- "object-assign" "^4.1.1"
-
-"schema-utils@^1.0.0":
- "integrity" "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g=="
- "resolved" "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "ajv" "^6.1.0"
- "ajv-errors" "^1.0.0"
- "ajv-keywords" "^3.1.0"
-
-"schema-utils@^2.6.5", "schema-utils@^2.7.0":
- "integrity" "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A=="
- "resolved" "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz"
- "version" "2.7.0"
- dependencies:
- "@types/json-schema" "^7.0.4"
- "ajv" "^6.12.2"
- "ajv-keywords" "^3.4.1"
-
-"semver@^5.4.1":
- "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
- "version" "5.7.1"
-
-"semver@^5.5.0":
- "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
- "version" "5.7.1"
-
-"semver@^5.6.0":
- "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
- "version" "5.7.1"
-
-"semver@^5.7.0":
- "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
- "version" "5.7.1"
-
-"semver@^5.7.1":
- "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
- "version" "5.7.1"
-
-"semver@^6.0.0", "semver@^6.1.1", "semver@^6.1.2", "semver@^6.3.0":
- "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
- "version" "6.3.0"
-
-"semver@^7.3.2":
- "integrity" "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz"
- "version" "7.3.2"
-
-"semver@2 || 3 || 4 || 5":
- "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
- "version" "5.7.1"
-
-"semver@5.5.0":
- "integrity" "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz"
- "version" "5.5.0"
-
-"semver@7.0.0":
- "integrity" "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz"
- "version" "7.0.0"
-
-"semver@7.x":
- "integrity" "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
- "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz"
- "version" "7.3.2"
-
-"send@0.18.0":
- "integrity" "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg=="
- "resolved" "https://registry.npmjs.org/send/-/send-0.18.0.tgz"
- "version" "0.18.0"
- dependencies:
- "debug" "2.6.9"
- "depd" "2.0.0"
- "destroy" "1.2.0"
- "encodeurl" "~1.0.2"
- "escape-html" "~1.0.3"
- "etag" "~1.8.1"
- "fresh" "0.5.2"
- "http-errors" "2.0.0"
- "mime" "1.6.0"
- "ms" "2.1.3"
- "on-finished" "2.4.1"
- "range-parser" "~1.2.1"
- "statuses" "2.0.1"
-
-"serialize-javascript@^3.1.0":
- "integrity" "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg=="
- "resolved" "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "randombytes" "^2.1.0"
-
-"serve-static@1.15.0":
- "integrity" "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g=="
- "resolved" "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz"
- "version" "1.15.0"
- dependencies:
- "encodeurl" "~1.0.2"
- "escape-html" "~1.0.3"
- "parseurl" "~1.3.3"
- "send" "0.18.0"
-
-"set-blocking@^2.0.0":
- "integrity" "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
- "resolved" "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz"
- "version" "2.0.0"
-
-"set-value@^2.0.0", "set-value@^2.0.1":
- "integrity" "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw=="
- "resolved" "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "extend-shallow" "^2.0.1"
- "is-extendable" "^0.1.1"
- "is-plain-object" "^2.0.3"
- "split-string" "^3.0.1"
-
-"setimmediate@^1.0.4":
- "integrity" "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
- "resolved" "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz"
- "version" "1.0.5"
-
-"setprototypeof@1.2.0":
- "integrity" "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
- "resolved" "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz"
- "version" "1.2.0"
-
-"sha.js@^2.4.0", "sha.js@^2.4.8":
- "integrity" "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ=="
- "resolved" "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz"
- "version" "2.4.11"
- dependencies:
- "inherits" "^2.0.1"
- "safe-buffer" "^5.0.1"
-
-"shallow-clone@^3.0.0":
- "integrity" "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA=="
- "resolved" "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "kind-of" "^6.0.2"
-
-"shallowequal@^1.1.0":
- "integrity" "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
- "resolved" "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz"
- "version" "1.1.0"
-
-"shebang-command@^1.2.0":
- "integrity" "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg=="
- "resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz"
- "version" "1.2.0"
- dependencies:
- "shebang-regex" "^1.0.0"
-
-"shebang-command@^2.0.0":
- "integrity" "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="
- "resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "shebang-regex" "^3.0.0"
-
-"shebang-regex@^1.0.0":
- "integrity" "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="
- "resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz"
- "version" "1.0.0"
-
-"shebang-regex@^3.0.0":
- "integrity" "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
- "resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
- "version" "3.0.0"
-
-"shelljs@^0.8.4":
- "integrity" "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow=="
- "resolved" "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz"
- "version" "0.8.5"
- dependencies:
- "glob" "^7.0.0"
- "interpret" "^1.0.0"
- "rechoir" "^0.6.2"
-
-"shellwords@^0.1.1":
- "integrity" "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww=="
- "resolved" "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz"
- "version" "0.1.1"
-
-"side-channel@^1.0.2", "side-channel@^1.0.4":
- "integrity" "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw=="
- "resolved" "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "call-bind" "^1.0.0"
- "get-intrinsic" "^1.0.2"
- "object-inspect" "^1.9.0"
-
-"signal-exit@^3.0.0", "signal-exit@^3.0.2":
- "integrity" "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
- "resolved" "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz"
- "version" "3.0.3"
-
-"sinon-chrome@^3.0.1":
- "integrity" "sha512-NTEFhyuiWEMnRmIqldUiA2DhKn2EqnZxyEk5Ez5rBXj+Nl54aJ0MEmF4wjltrxecxd8zlNLxyE0HyLabev9JsQ=="
- "resolved" "https://registry.npmjs.org/sinon-chrome/-/sinon-chrome-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "lodash" "^4.16.3"
- "sinon" "^7.2.3"
- "urijs" "^1.18.2"
-
-"sinon@^7.2.3":
- "integrity" "sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q=="
- "resolved" "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz"
- "version" "7.5.0"
- dependencies:
- "@sinonjs/commons" "^1.4.0"
- "@sinonjs/formatio" "^3.2.1"
- "@sinonjs/samsam" "^3.3.3"
- "diff" "^3.5.0"
- "lolex" "^4.2.0"
- "nise" "^1.5.2"
- "supports-color" "^5.5.0"
-
-"sisteransi@^1.0.5":
- "integrity" "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="
- "resolved" "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz"
- "version" "1.0.5"
-
-"slash@^3.0.0":
- "integrity" "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
- "resolved" "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
- "version" "3.0.0"
-
-"slice-ansi@^2.1.0":
- "integrity" "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ=="
- "resolved" "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "ansi-styles" "^3.2.0"
- "astral-regex" "^1.0.0"
- "is-fullwidth-code-point" "^2.0.0"
-
-"snapdragon-node@^2.0.1":
- "integrity" "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw=="
- "resolved" "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "define-property" "^1.0.0"
- "isobject" "^3.0.0"
- "snapdragon-util" "^3.0.1"
-
-"snapdragon-util@^3.0.1":
- "integrity" "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ=="
- "resolved" "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "kind-of" "^3.2.0"
-
-"snapdragon@^0.8.1":
- "integrity" "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg=="
- "resolved" "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz"
- "version" "0.8.2"
- dependencies:
- "base" "^0.11.1"
- "debug" "^2.2.0"
- "define-property" "^0.2.5"
- "extend-shallow" "^2.0.1"
- "map-cache" "^0.2.2"
- "source-map" "^0.5.6"
- "source-map-resolve" "^0.5.0"
- "use" "^3.1.0"
-
-"source-list-map@^2.0.0":
- "integrity" "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw=="
- "resolved" "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz"
- "version" "2.0.1"
-
-"source-map-resolve@^0.5.0", "source-map-resolve@^0.5.2":
- "integrity" "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw=="
- "resolved" "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz"
- "version" "0.5.3"
- dependencies:
- "atob" "^2.1.2"
- "decode-uri-component" "^0.2.0"
- "resolve-url" "^0.2.1"
- "source-map-url" "^0.4.0"
- "urix" "^0.1.0"
-
-"source-map-support@^0.5.17", "source-map-support@^0.5.6", "source-map-support@~0.5.12":
- "integrity" "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw=="
- "resolved" "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz"
- "version" "0.5.19"
- dependencies:
- "buffer-from" "^1.0.0"
- "source-map" "^0.6.0"
-
-"source-map-url@^0.4.0":
- "integrity" "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=sha512-liJwHPI9x9d9w5WSIjM58MqGmmb7XzNqwdUA3kSBQ4lmDngexlKwawGzK3J1mKXi6+sysoMDlpVyZh9sv5vRfw==sha512-liJwHPI9x9d9w5WSIjM58MqGmmb7XzNqwdUA3kSBQ4lmDngexlKwawGzK3J1mKXi6+sysoMDlpVyZh9sv5vRfw==sha512-liJwHPI9x9d9w5WSIjM58MqGmmb7XzNqwdUA3kSBQ4lmDngexlKwawGzK3J1mKXi6+sysoMDlpVyZh9sv5vRfw==sha512-liJwHPI9x9d9w5WSIjM58MqGmmb7XzNqwdUA3kSBQ4lmDngexlKwawGzK3J1mKXi6+sysoMDlpVyZh9sv5vRfw==sha512-liJwHPI9x9d9w5WSIjM58MqGmmb7XzNqwdUA3kSBQ4lmDngexlKwawGzK3J1mKXi6+sysoMDlpVyZh9sv5vRfw==sha512-liJwHPI9x9d9w5WSIjM58MqGmmb7XzNqwdUA3kSBQ4lmDngexlKwawGzK3J1mKXi6+sysoMDlpVyZh9sv5vRfw== sha512-liJwHPI9x9d9w5WSIjM58MqGmmb7XzNqwdUA3kSBQ4lmDngexlKwawGzK3J1mKXi6+sysoMDlpVyZh9sv5vRfw=="
- "resolved" "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz"
- "version" "0.4.0"
-
-"source-map@^0.5.0", "source-map@^0.5.6", "source-map@^0.5.7":
- "integrity" "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="
- "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
- "version" "0.5.7"
-
-"source-map@^0.6.0":
- "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
- "version" "0.6.1"
-
-"source-map@^0.6.1":
- "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
- "version" "0.6.1"
-
-"source-map@^0.7.3":
- "integrity" "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="
- "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz"
- "version" "0.7.4"
-
-"source-map@~0.6.1":
- "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
- "version" "0.6.1"
-
-"spdx-correct@^3.0.0":
- "integrity" "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w=="
- "resolved" "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz"
- "version" "3.1.1"
- dependencies:
- "spdx-expression-parse" "^3.0.0"
- "spdx-license-ids" "^3.0.0"
-
-"spdx-exceptions@^2.1.0":
- "integrity" "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
- "resolved" "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz"
- "version" "2.3.0"
-
-"spdx-expression-parse@^3.0.0":
- "integrity" "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="
- "resolved" "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "spdx-exceptions" "^2.1.0"
- "spdx-license-ids" "^3.0.0"
-
-"spdx-license-ids@^3.0.0":
- "integrity" "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q=="
- "resolved" "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz"
- "version" "3.0.5"
-
-"split-string@^3.0.1", "split-string@^3.0.2":
- "integrity" "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw=="
- "resolved" "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "extend-shallow" "^3.0.0"
-
-"split.js@^1.6.0":
- "integrity" "sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw=="
- "resolved" "https://registry.npmjs.org/split.js/-/split.js-1.6.5.tgz"
- "version" "1.6.5"
-
-"sprintf-js@~1.0.2":
- "integrity" "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
- "resolved" "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
- "version" "1.0.3"
-
-"ssri@^6.0.1":
- "integrity" "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q=="
- "resolved" "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz"
- "version" "6.0.2"
- dependencies:
- "figgy-pudding" "^3.5.1"
-
-"stack-utils@^2.0.2":
- "integrity" "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA=="
- "resolved" "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz"
- "version" "2.0.5"
- dependencies:
- "escape-string-regexp" "^2.0.0"
-
-"static-extend@^0.1.1":
- "integrity" "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g=="
- "resolved" "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz"
- "version" "0.1.2"
- dependencies:
- "define-property" "^0.2.5"
- "object-copy" "^0.1.0"
-
-"statuses@2.0.1":
- "integrity" "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
- "resolved" "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz"
- "version" "2.0.1"
-
-"stream-browserify@^2.0.1":
- "integrity" "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg=="
- "resolved" "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "inherits" "~2.0.1"
- "readable-stream" "^2.0.2"
-
-"stream-each@^1.1.0":
- "integrity" "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw=="
- "resolved" "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz"
- "version" "1.2.3"
- dependencies:
- "end-of-stream" "^1.1.0"
- "stream-shift" "^1.0.0"
-
-"stream-http@^2.7.2":
- "integrity" "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw=="
- "resolved" "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz"
- "version" "2.8.3"
- dependencies:
- "builtin-status-codes" "^3.0.0"
- "inherits" "^2.0.1"
- "readable-stream" "^2.3.6"
- "to-arraybuffer" "^1.0.0"
- "xtend" "^4.0.0"
-
-"stream-shift@^1.0.0":
- "integrity" "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
- "resolved" "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz"
- "version" "1.0.1"
-
-"string_decoder@^1.0.0", "string_decoder@~1.1.1":
- "integrity" "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="
- "resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
- "version" "1.1.1"
- dependencies:
- "safe-buffer" "~5.1.0"
-
-"string_decoder@^1.1.1":
- "integrity" "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="
- "resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
- "version" "1.3.0"
- dependencies:
- "safe-buffer" "~5.2.0"
-
-"string-length@^4.0.1":
- "integrity" "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ=="
- "resolved" "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz"
- "version" "4.0.2"
- dependencies:
- "char-regex" "^1.0.2"
- "strip-ansi" "^6.0.0"
-
-"string-width@^3.0.0", "string-width@^3.1.0":
- "integrity" "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w=="
- "resolved" "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz"
- "version" "3.1.0"
- dependencies:
- "emoji-regex" "^7.0.1"
- "is-fullwidth-code-point" "^2.0.0"
- "strip-ansi" "^5.1.0"
-
-"string-width@^4.1.0", "string-width@^4.2.0":
- "integrity" "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg=="
- "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz"
- "version" "4.2.0"
- dependencies:
- "emoji-regex" "^8.0.0"
- "is-fullwidth-code-point" "^3.0.0"
- "strip-ansi" "^6.0.0"
-
-"string.prototype.matchall@^4.0.2":
- "integrity" "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg=="
- "resolved" "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz"
- "version" "4.0.2"
- dependencies:
- "define-properties" "^1.1.3"
- "es-abstract" "^1.17.0"
- "has-symbols" "^1.0.1"
- "internal-slot" "^1.0.2"
- "regexp.prototype.flags" "^1.3.0"
- "side-channel" "^1.0.2"
-
-"string.prototype.trim@^1.2.1":
- "integrity" "sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw=="
- "resolved" "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz"
- "version" "1.2.1"
- dependencies:
- "define-properties" "^1.1.3"
- "es-abstract" "^1.17.0-next.1"
- "function-bind" "^1.1.1"
-
-"string.prototype.trimend@^1.0.4":
- "integrity" "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A=="
- "resolved" "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "call-bind" "^1.0.2"
- "define-properties" "^1.1.3"
-
-"string.prototype.trimstart@^1.0.4":
- "integrity" "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw=="
- "resolved" "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "call-bind" "^1.0.2"
- "define-properties" "^1.1.3"
-
-"strip-ansi@^5.0.0", "strip-ansi@^5.1.0", "strip-ansi@^5.2.0":
- "integrity" "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="
- "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz"
- "version" "5.2.0"
- dependencies:
- "ansi-regex" "^4.1.0"
-
-"strip-ansi@^6.0.0":
- "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="
- "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
- "version" "6.0.1"
- dependencies:
- "ansi-regex" "^5.0.1"
-
-"strip-bom@^3.0.0":
- "integrity" "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="
- "resolved" "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz"
- "version" "3.0.0"
-
-"strip-bom@^4.0.0":
- "integrity" "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w=="
- "resolved" "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz"
- "version" "4.0.0"
-
-"strip-eof@^1.0.0":
- "integrity" "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q=="
- "resolved" "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz"
- "version" "1.0.0"
-
-"strip-final-newline@^2.0.0":
- "integrity" "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
- "resolved" "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz"
- "version" "2.0.0"
-
-"strip-indent@^3.0.0":
- "integrity" "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="
- "resolved" "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz"
- "version" "3.0.0"
- dependencies:
- "min-indent" "^1.0.0"
-
-"strip-json-comments@^3.0.1":
- "integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
- "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
- "version" "3.1.1"
-
-"style-loader@^0.23.1":
- "integrity" "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg=="
- "resolved" "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz"
- "version" "0.23.1"
- dependencies:
- "loader-utils" "^1.1.0"
- "schema-utils" "^1.0.0"
-
-"stylis@4.0.13":
- "integrity" "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag=="
- "resolved" "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz"
- "version" "4.0.13"
-
-"supports-color@^5.3.0", "supports-color@^5.5.0":
- "integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="
- "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
- "version" "5.5.0"
- dependencies:
- "has-flag" "^3.0.0"
-
-"supports-color@^6.1.0":
- "integrity" "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ=="
- "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz"
- "version" "6.1.0"
- dependencies:
- "has-flag" "^3.0.0"
-
-"supports-color@^7.0.0":
- "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="
- "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
- "version" "7.2.0"
- dependencies:
- "has-flag" "^4.0.0"
-
-"supports-color@^7.1.0":
- "integrity" "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g=="
- "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz"
- "version" "7.1.0"
- dependencies:
- "has-flag" "^4.0.0"
-
-"supports-hyperlinks@^2.0.0":
- "integrity" "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ=="
- "resolved" "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz"
- "version" "2.2.0"
- dependencies:
- "has-flag" "^4.0.0"
- "supports-color" "^7.0.0"
-
-"svg.draggable.js@^2.2.2":
- "integrity" "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw=="
- "resolved" "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz"
- "version" "2.2.2"
- dependencies:
- "svg.js" "^2.0.1"
-
-"svg.easing.js@^2.0.0":
- "integrity" "sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI=sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA== sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA=="
- "resolved" "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "svg.js" ">=2.3.x"
-
-"svg.filter.js@^2.0.2":
- "integrity" "sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw== sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw=="
- "resolved" "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "svg.js" "^2.2.5"
-
-"svg.js@^2.0.1", "svg.js@^2.2.5", "svg.js@^2.4.0", "svg.js@^2.6.5", "svg.js@>=2.3.x":
- "integrity" "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
- "resolved" "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz"
- "version" "2.7.1"
-
-"svg.pathmorphing.js@^0.1.3":
- "integrity" "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww=="
- "resolved" "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz"
- "version" "0.1.3"
- dependencies:
- "svg.js" "^2.4.0"
-
-"svg.resize.js@^1.4.3":
- "integrity" "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw=="
- "resolved" "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz"
- "version" "1.4.3"
- dependencies:
- "svg.js" "^2.6.5"
- "svg.select.js" "^2.1.2"
-
-"svg.select.js@^2.1.2":
- "integrity" "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ=="
- "resolved" "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz"
- "version" "2.1.2"
- dependencies:
- "svg.js" "^2.2.5"
-
-"svg.select.js@^3.0.1":
- "integrity" "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw=="
- "resolved" "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz"
- "version" "3.0.1"
- dependencies:
- "svg.js" "^2.6.5"
-
-"symbol-observable@1.2.0":
- "integrity" "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
- "resolved" "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz"
- "version" "1.2.0"
-
-"symbol-tree@^3.2.4":
- "integrity" "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
- "resolved" "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz"
- "version" "3.2.4"
-
-"table@^5.2.3":
- "integrity" "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug=="
- "resolved" "https://registry.npmjs.org/table/-/table-5.4.6.tgz"
- "version" "5.4.6"
- dependencies:
- "ajv" "^6.10.2"
- "lodash" "^4.17.14"
- "slice-ansi" "^2.1.0"
- "string-width" "^3.0.0"
-
-"tapable@^1.0.0", "tapable@^1.1.3":
- "integrity" "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
- "resolved" "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz"
- "version" "1.1.3"
-
-"tar-fs@2.1.1":
- "integrity" "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng=="
- "resolved" "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "chownr" "^1.1.1"
- "mkdirp-classic" "^0.5.2"
- "pump" "^3.0.0"
- "tar-stream" "^2.1.4"
-
-"tar-stream@^2.1.4":
- "integrity" "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="
- "resolved" "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz"
- "version" "2.2.0"
- dependencies:
- "bl" "^4.0.3"
- "end-of-stream" "^1.4.1"
- "fs-constants" "^1.0.0"
- "inherits" "^2.0.3"
- "readable-stream" "^3.1.1"
-
-"terminal-link@^2.0.0":
- "integrity" "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ=="
- "resolved" "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "ansi-escapes" "^4.2.1"
- "supports-hyperlinks" "^2.0.0"
-
-"terser-webpack-plugin@^1.4.3":
- "integrity" "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA=="
- "resolved" "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz"
- "version" "1.4.4"
- dependencies:
- "cacache" "^12.0.2"
- "find-cache-dir" "^2.1.0"
- "is-wsl" "^1.1.0"
- "schema-utils" "^1.0.0"
- "serialize-javascript" "^3.1.0"
- "source-map" "^0.6.1"
- "terser" "^4.1.2"
- "webpack-sources" "^1.4.0"
- "worker-farm" "^1.7.0"
-
-"terser@^4.1.2":
- "integrity" "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw=="
- "resolved" "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz"
- "version" "4.8.1"
- dependencies:
- "commander" "^2.20.0"
- "source-map" "~0.6.1"
- "source-map-support" "~0.5.12"
-
-"test-exclude@^6.0.0":
- "integrity" "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w=="
- "resolved" "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz"
- "version" "6.0.0"
- dependencies:
- "@istanbuljs/schema" "^0.1.2"
- "glob" "^7.1.4"
- "minimatch" "^3.0.4"
-
-"text-table@^0.2.0":
- "integrity" "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
- "resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
- "version" "0.2.0"
-
-"throat@^4.1.0":
- "integrity" "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA== sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA=="
- "resolved" "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz"
- "version" "4.1.0"
-
-"throat@^5.0.0":
- "integrity" "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA=="
- "resolved" "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz"
- "version" "5.0.0"
-
-"through@^2.3.6", "through@^2.3.8":
- "integrity" "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
- "resolved" "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
- "version" "2.3.8"
-
-"through2@^2.0.0":
- "integrity" "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="
- "resolved" "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"
- "version" "2.0.5"
- dependencies:
- "readable-stream" "~2.3.6"
- "xtend" "~4.0.1"
-
-"timers-browserify@^2.0.4":
- "integrity" "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ=="
- "resolved" "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz"
- "version" "2.0.11"
- dependencies:
- "setimmediate" "^1.0.4"
-
-"tiny-invariant@^1.0.2":
- "integrity" "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
- "resolved" "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz"
- "version" "1.1.0"
-
-"tiny-warning@^1.0.0", "tiny-warning@^1.0.2", "tiny-warning@^1.0.3":
- "integrity" "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
- "resolved" "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
- "version" "1.0.3"
-
-"tmp@^0.0.33":
- "integrity" "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw=="
- "resolved" "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz"
- "version" "0.0.33"
- dependencies:
- "os-tmpdir" "~1.0.2"
-
-"tmpl@1.0.x":
- "integrity" "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="
- "resolved" "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz"
- "version" "1.0.5"
-
-"to-arraybuffer@^1.0.0":
- "integrity" "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA=="
- "resolved" "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz"
- "version" "1.0.1"
-
-"to-fast-properties@^2.0.0":
- "integrity" "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="
- "resolved" "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
- "version" "2.0.0"
-
-"to-object-path@^0.3.0":
- "integrity" "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg=="
- "resolved" "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz"
- "version" "0.3.0"
- dependencies:
- "kind-of" "^3.0.2"
-
-"to-regex-range@^2.1.0":
- "integrity" "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg=="
- "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz"
- "version" "2.1.1"
- dependencies:
- "is-number" "^3.0.0"
- "repeat-string" "^1.6.1"
-
-"to-regex-range@^5.0.1":
- "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="
- "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
- "version" "5.0.1"
- dependencies:
- "is-number" "^7.0.0"
-
-"to-regex@^3.0.1", "to-regex@^3.0.2":
- "integrity" "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw=="
- "resolved" "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz"
- "version" "3.0.2"
- dependencies:
- "define-property" "^2.0.2"
- "extend-shallow" "^3.0.2"
- "regex-not" "^1.0.2"
- "safe-regex" "^1.1.0"
-
-"toidentifier@1.0.1":
- "integrity" "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
- "resolved" "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz"
- "version" "1.0.1"
-
-"tough-cookie@^4.0.0":
- "integrity" "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg=="
- "resolved" "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz"
- "version" "4.0.0"
- dependencies:
- "psl" "^1.1.33"
- "punycode" "^2.1.1"
- "universalify" "^0.1.2"
-
-"tr46@^2.1.0":
- "integrity" "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw=="
- "resolved" "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz"
- "version" "2.1.0"
- dependencies:
- "punycode" "^2.1.1"
-
-"tr46@~0.0.3":
- "integrity" "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
- "resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
- "version" "0.0.3"
-
-"ts-jest@^26.1.2":
- "integrity" "sha512-I5Qsddo+VTm94SukBJ4cPimOoFZsYTeElR2xy6H2TOVs+NsvgYglW8KuQgKoApOKuaU/Ix/vrF9ebFZlb5D2Pg=="
- "resolved" "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.4.tgz"
- "version" "26.5.4"
- dependencies:
- "bs-logger" "0.x"
- "buffer-from" "1.x"
- "fast-json-stable-stringify" "2.x"
- "jest-util" "^26.1.0"
- "json5" "2.x"
- "lodash" "4.x"
- "make-error" "1.x"
- "mkdirp" "1.x"
- "semver" "7.x"
- "yargs-parser" "20.x"
-
-"ts-loader@^7.0.5":
- "integrity" "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig=="
- "resolved" "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz"
- "version" "7.0.5"
- dependencies:
- "chalk" "^2.3.0"
- "enhanced-resolve" "^4.0.0"
- "loader-utils" "^1.0.2"
- "micromatch" "^4.0.0"
- "semver" "^6.0.0"
-
-"ts-node@^9.1.1", "ts-node@>=9.0.0":
- "integrity" "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg=="
- "resolved" "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz"
- "version" "9.1.1"
- dependencies:
- "arg" "^4.1.0"
- "create-require" "^1.1.0"
- "diff" "^4.0.1"
- "make-error" "^1.1.1"
- "source-map-support" "^0.5.17"
- "yn" "3.1.1"
-
-"tsconfig-paths@^3.9.0":
- "integrity" "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw=="
- "resolved" "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz"
- "version" "3.9.0"
- dependencies:
- "@types/json5" "^0.0.29"
- "json5" "^1.0.1"
- "minimist" "^1.2.0"
- "strip-bom" "^3.0.0"
-
-"tslib@^1.8.1", "tslib@^1.9.0":
- "integrity" "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
- "resolved" "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz"
- "version" "1.13.0"
-
-"tsutils@^3.17.1":
- "integrity" "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g=="
- "resolved" "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz"
- "version" "3.17.1"
- dependencies:
- "tslib" "^1.8.1"
-
-"tty-browserify@0.0.0":
- "integrity" "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw=="
- "resolved" "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz"
- "version" "0.0.0"
-
-"type-check@~0.3.2":
- "integrity" "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg=="
- "resolved" "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz"
- "version" "0.3.2"
- dependencies:
- "prelude-ls" "~1.1.2"
-
-"type-detect@^4.0.0", "type-detect@^4.0.5", "type-detect@4.0.8":
- "integrity" "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
- "resolved" "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz"
- "version" "4.0.8"
-
-"type-fest@^0.11.0":
- "integrity" "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ=="
- "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz"
- "version" "0.11.0"
-
-"type-fest@^0.6.0":
- "integrity" "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg=="
- "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz"
- "version" "0.6.0"
-
-"type-fest@^0.8.1":
- "integrity" "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
- "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz"
- "version" "0.8.1"
-
-"type-is@~1.6.18":
- "integrity" "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="
- "resolved" "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz"
- "version" "1.6.18"
- dependencies:
- "media-typer" "0.3.0"
- "mime-types" "~2.1.24"
-
-"typedarray-to-buffer@^3.1.5":
- "integrity" "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q=="
- "resolved" "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz"
- "version" "3.1.5"
- dependencies:
- "is-typedarray" "^1.0.0"
-
-"typedarray@^0.0.6":
- "integrity" "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
- "resolved" "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
- "version" "0.0.6"
-
-"typedoc-default-themes@^0.10.2":
- "integrity" "sha512-zo09yRj+xwLFE3hyhJeVHWRSPuKEIAsFK5r2u47KL/HBKqpwdUSanoaz5L34IKiSATFrjG5ywmIu98hPVMfxZg=="
- "resolved" "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.10.2.tgz"
- "version" "0.10.2"
- dependencies:
- "lunr" "^2.3.8"
-
-"typedoc-webpack-plugin@^1.1.4":
- "integrity" "sha512-MjcXbum38/JMW+AgVyJH5OOReLnKxZ1YXDDJv8jqFpT5SyhyS+lYouO7FGtuiypSFvRGfOnIA36p3Ee9O9yX9A=="
- "resolved" "https://registry.npmjs.org/typedoc-webpack-plugin/-/typedoc-webpack-plugin-1.1.4.tgz"
- "version" "1.1.4"
- dependencies:
- "lodash.clone" "^4.5.0"
- "lodash.merge" "^4.6.0"
-
-"typedoc@^0.17.8", "typedoc@^0.5.0":
- "integrity" "sha512-/OyrHCJ8jtzu+QZ+771YaxQ9s4g5Z3XsQE3Ma7q+BL392xxBn4UMvvCdVnqKC2T/dz03/VXSLVKOP3lHmDdc/w=="
- "resolved" "https://registry.npmjs.org/typedoc/-/typedoc-0.17.8.tgz"
- "version" "0.17.8"
- dependencies:
- "fs-extra" "^8.1.0"
- "handlebars" "^4.7.6"
- "highlight.js" "^10.0.0"
- "lodash" "^4.17.15"
- "lunr" "^2.3.8"
- "marked" "1.0.0"
- "minimatch" "^3.0.0"
- "progress" "^2.0.3"
- "shelljs" "^0.8.4"
- "typedoc-default-themes" "^0.10.2"
-
-"typescript@*", "typescript@^3.9.6", "typescript@>=2.7", "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", "typescript@>=3.8 <5.0", "typescript@>=3.8.3":
- "integrity" "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw=="
- "resolved" "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz"
- "version" "3.9.6"
-
-"uglify-js@^3.1.4":
- "integrity" "sha512-SbMu4D2Vo95LMC/MetNaso1194M1htEA+JrqE9Hk+G2DhI+itfS9TRu9ZKeCahLDNa/J3n4MqUJ/fOHMzQpRWw=="
- "resolved" "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.2.tgz"
- "version" "3.13.2"
-
-"unbox-primitive@^1.0.1":
- "integrity" "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw=="
- "resolved" "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "function-bind" "^1.1.1"
- "has-bigints" "^1.0.1"
- "has-symbols" "^1.0.2"
- "which-boxed-primitive" "^1.0.2"
-
-"unbzip2-stream@1.4.3":
- "integrity" "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg=="
- "resolved" "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz"
- "version" "1.4.3"
- dependencies:
- "buffer" "^5.2.1"
- "through" "^2.3.8"
-
-"unicode-canonical-property-names-ecmascript@^1.0.4":
- "integrity" "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ=="
- "resolved" "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz"
- "version" "1.0.4"
-
-"unicode-match-property-ecmascript@^1.0.4":
- "integrity" "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg=="
- "resolved" "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz"
- "version" "1.0.4"
- dependencies:
- "unicode-canonical-property-names-ecmascript" "^1.0.4"
- "unicode-property-aliases-ecmascript" "^1.0.4"
-
-"unicode-match-property-value-ecmascript@^1.2.0":
- "integrity" "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ=="
- "resolved" "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz"
- "version" "1.2.0"
-
-"unicode-property-aliases-ecmascript@^1.0.4":
- "integrity" "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg=="
- "resolved" "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz"
- "version" "1.1.0"
-
-"union-value@^1.0.0":
- "integrity" "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg=="
- "resolved" "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "arr-union" "^3.1.0"
- "get-value" "^2.0.6"
- "is-extendable" "^0.1.1"
- "set-value" "^2.0.1"
-
-"uniq@^1.0.1":
- "integrity" "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA== sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA=="
- "resolved" "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz"
- "version" "1.0.1"
-
-"unique-filename@^1.1.1":
- "integrity" "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ=="
- "resolved" "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz"
- "version" "1.1.1"
- dependencies:
- "unique-slug" "^2.0.0"
-
-"unique-slug@^2.0.0":
- "integrity" "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w=="
- "resolved" "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "imurmurhash" "^0.1.4"
-
-"universalify@^0.1.0", "universalify@^0.1.2":
- "integrity" "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
- "resolved" "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz"
- "version" "0.1.2"
-
-"unpipe@~1.0.0", "unpipe@1.0.0":
- "integrity" "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
- "resolved" "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
- "version" "1.0.0"
-
-"unset-value@^1.0.0":
- "integrity" "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ=="
- "resolved" "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz"
- "version" "1.0.0"
- dependencies:
- "has-value" "^0.3.1"
- "isobject" "^3.0.0"
-
-"upath@^1.1.1":
- "integrity" "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
- "resolved" "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz"
- "version" "1.2.0"
-
-"update-browserslist-db@^1.0.9":
- "integrity" "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg=="
- "resolved" "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz"
- "version" "1.0.9"
- dependencies:
- "escalade" "^3.1.1"
- "picocolors" "^1.0.0"
-
-"uri-js@^4.2.2":
- "integrity" "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ=="
- "resolved" "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz"
- "version" "4.2.2"
- dependencies:
- "punycode" "^2.1.0"
-
-"urijs@^1.18.2":
- "integrity" "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ=="
- "resolved" "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz"
- "version" "1.19.11"
-
-"urix@^0.1.0":
- "integrity" "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg=="
- "resolved" "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz"
- "version" "0.1.0"
-
-"url@^0.11.0":
- "integrity" "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ=="
- "resolved" "https://registry.npmjs.org/url/-/url-0.11.0.tgz"
- "version" "0.11.0"
- dependencies:
- "punycode" "1.3.2"
- "querystring" "0.2.0"
-
-"use@^3.1.0":
- "integrity" "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
- "resolved" "https://registry.npmjs.org/use/-/use-3.1.1.tgz"
- "version" "3.1.1"
-
-"util-deprecate@^1.0.1", "util-deprecate@~1.0.1":
- "integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
- "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
- "version" "1.0.2"
-
-"util@^0.11.0":
- "integrity" "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ=="
- "resolved" "https://registry.npmjs.org/util/-/util-0.11.1.tgz"
- "version" "0.11.1"
- dependencies:
- "inherits" "2.0.3"
-
-"util@^0.12.4":
- "integrity" "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw=="
- "resolved" "https://registry.npmjs.org/util/-/util-0.12.4.tgz"
- "version" "0.12.4"
- dependencies:
- "inherits" "^2.0.3"
- "is-arguments" "^1.0.4"
- "is-generator-function" "^1.0.7"
- "is-typed-array" "^1.1.3"
- "safe-buffer" "^5.1.2"
- "which-typed-array" "^1.1.2"
-
-"util@0.10.3":
- "integrity" "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ== sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ=="
- "resolved" "https://registry.npmjs.org/util/-/util-0.10.3.tgz"
- "version" "0.10.3"
- dependencies:
- "inherits" "2.0.1"
-
-"utils-merge@1.0.1":
- "integrity" "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
- "resolved" "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz"
- "version" "1.0.1"
-
-"uuid@^8.3.0":
- "integrity" "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
- "resolved" "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
- "version" "8.3.2"
-
-"v8-compile-cache@^2.0.3", "v8-compile-cache@^2.1.1":
- "integrity" "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ=="
- "resolved" "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz"
- "version" "2.1.1"
-
-"v8-to-istanbul@^7.0.0":
- "integrity" "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow=="
- "resolved" "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz"
- "version" "7.1.2"
- dependencies:
- "@types/istanbul-lib-coverage" "^2.0.1"
- "convert-source-map" "^1.6.0"
- "source-map" "^0.7.3"
-
-"validate-npm-package-license@^3.0.1":
- "integrity" "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="
- "resolved" "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz"
- "version" "3.0.4"
- dependencies:
- "spdx-correct" "^3.0.0"
- "spdx-expression-parse" "^3.0.0"
-
-"value-equal@^1.0.1":
- "integrity" "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
- "resolved" "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz"
- "version" "1.0.1"
-
-"vary@~1.1.2":
- "integrity" "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
- "resolved" "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
- "version" "1.1.2"
-
-"vm-browserify@^1.0.1":
- "integrity" "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
- "resolved" "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz"
- "version" "1.1.2"
-
-"w3c-hr-time@^1.0.2":
- "integrity" "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ=="
- "resolved" "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "browser-process-hrtime" "^1.0.0"
-
-"w3c-xmlserializer@^2.0.0":
- "integrity" "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA=="
- "resolved" "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz"
- "version" "2.0.0"
- dependencies:
- "xml-name-validator" "^3.0.0"
-
-"walker@^1.0.7", "walker@~1.0.5":
- "integrity" "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=sha512-cF4je9Fgt6sj1PKfuFt9jpQPeHosM+Ryma/hfY9U7uXGKM7pJCsF0v2r55o+Il54+i77SyYWetB4tD1dEygRkw==sha512-cF4je9Fgt6sj1PKfuFt9jpQPeHosM+Ryma/hfY9U7uXGKM7pJCsF0v2r55o+Il54+i77SyYWetB4tD1dEygRkw==sha512-cF4je9Fgt6sj1PKfuFt9jpQPeHosM+Ryma/hfY9U7uXGKM7pJCsF0v2r55o+Il54+i77SyYWetB4tD1dEygRkw==sha512-cF4je9Fgt6sj1PKfuFt9jpQPeHosM+Ryma/hfY9U7uXGKM7pJCsF0v2r55o+Il54+i77SyYWetB4tD1dEygRkw==sha512-cF4je9Fgt6sj1PKfuFt9jpQPeHosM+Ryma/hfY9U7uXGKM7pJCsF0v2r55o+Il54+i77SyYWetB4tD1dEygRkw==sha512-cF4je9Fgt6sj1PKfuFt9jpQPeHosM+Ryma/hfY9U7uXGKM7pJCsF0v2r55o+Il54+i77SyYWetB4tD1dEygRkw== sha512-cF4je9Fgt6sj1PKfuFt9jpQPeHosM+Ryma/hfY9U7uXGKM7pJCsF0v2r55o+Il54+i77SyYWetB4tD1dEygRkw=="
- "resolved" "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz"
- "version" "1.0.7"
- dependencies:
- "makeerror" "1.0.x"
-
-"warning@^4.0.3":
- "integrity" "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w=="
- "resolved" "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz"
- "version" "4.0.3"
- dependencies:
- "loose-envify" "^1.0.0"
-
-"watchpack-chokidar2@^2.0.0":
- "integrity" "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww=="
- "resolved" "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz"
- "version" "2.0.1"
- dependencies:
- "chokidar" "^2.1.8"
-
-"watchpack@^1.6.1":
- "integrity" "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g=="
- "resolved" "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz"
- "version" "1.7.2"
- dependencies:
- "graceful-fs" "^4.1.2"
- "neo-async" "^2.5.0"
- optionalDependencies:
- "chokidar" "^3.4.0"
- "watchpack-chokidar2" "^2.0.0"
-
-"web-vitals@^1.1.0":
- "integrity" "sha512-jYOaqu01Ny1NvMwJ3dBJDUOJ2PGWknZWH4AUnvFOscvbdHMERIKT2TlgiAey5rVyfOePG7so2JcXXZdSnBvioQ=="
- "resolved" "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.1.tgz"
- "version" "1.1.1"
-
-"webidl-conversions@^3.0.0":
- "integrity" "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz"
- "version" "3.0.1"
-
-"webidl-conversions@^5.0.0":
- "integrity" "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA=="
- "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz"
- "version" "5.0.0"
-
-"webidl-conversions@^6.1.0":
- "integrity" "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w=="
- "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz"
- "version" "6.1.0"
-
-"webpack-chrome-extension-reloader@^1.3.0":
- "integrity" "sha512-Q111eKEAUwltk/fgJPcWaGwJb8yBQ/uu/PtK8q1qlxB/AtFuubYqSAd8hlICciadtQExYefYrYaDSnTjFgZDcg=="
- "resolved" "https://registry.npmjs.org/webpack-chrome-extension-reloader/-/webpack-chrome-extension-reloader-1.3.0.tgz"
- "version" "1.3.0"
- dependencies:
- "colors" "^1.1.2"
- "lodash" "^4.17.4"
- "minimist" "^1.2.0"
- "webpack-sources" "^1.0.1"
- "ws" "^6.1.2"
-
-"webpack-cli@^3.3.12":
- "integrity" "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag=="
- "resolved" "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz"
- "version" "3.3.12"
- dependencies:
- "chalk" "^2.4.2"
- "cross-spawn" "^6.0.5"
- "enhanced-resolve" "^4.1.1"
- "findup-sync" "^3.0.0"
- "global-modules" "^2.0.0"
- "import-local" "^2.0.0"
- "interpret" "^1.4.0"
- "loader-utils" "^1.4.0"
- "supports-color" "^6.1.0"
- "v8-compile-cache" "^2.1.1"
- "yargs" "^13.3.2"
-
-"webpack-sources@^1.0.1", "webpack-sources@^1.4.0", "webpack-sources@^1.4.1":
- "integrity" "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ=="
- "resolved" "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz"
- "version" "1.4.3"
- dependencies:
- "source-list-map" "^2.0.0"
- "source-map" "~0.6.1"
-
-"webpack@^3.0.0 || ^4.0.0", "webpack@^4.0.0", "webpack@^4.0.0 || ^5.0.0", "webpack@^4.43.0", "webpack@>=2", "webpack@>=2 <5", "webpack@4.x.x":
- "integrity" "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g=="
- "resolved" "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz"
- "version" "4.43.0"
- dependencies:
- "@webassemblyjs/ast" "1.9.0"
- "@webassemblyjs/helper-module-context" "1.9.0"
- "@webassemblyjs/wasm-edit" "1.9.0"
- "@webassemblyjs/wasm-parser" "1.9.0"
- "acorn" "^6.4.1"
- "ajv" "^6.10.2"
- "ajv-keywords" "^3.4.1"
- "chrome-trace-event" "^1.0.2"
- "enhanced-resolve" "^4.1.0"
- "eslint-scope" "^4.0.3"
- "json-parse-better-errors" "^1.0.2"
- "loader-runner" "^2.4.0"
- "loader-utils" "^1.2.3"
- "memory-fs" "^0.4.1"
- "micromatch" "^3.1.10"
- "mkdirp" "^0.5.3"
- "neo-async" "^2.6.1"
- "node-libs-browser" "^2.2.1"
- "schema-utils" "^1.0.0"
- "tapable" "^1.1.3"
- "terser-webpack-plugin" "^1.4.3"
- "watchpack" "^1.6.1"
- "webpack-sources" "^1.4.1"
-
-"whatwg-encoding@^1.0.5":
- "integrity" "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw=="
- "resolved" "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz"
- "version" "1.0.5"
- dependencies:
- "iconv-lite" "0.4.24"
-
-"whatwg-mimetype@^2.3.0":
- "integrity" "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g=="
- "resolved" "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz"
- "version" "2.3.0"
-
-"whatwg-url@^5.0.0":
- "integrity" "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="
- "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz"
- "version" "5.0.0"
- dependencies:
- "tr46" "~0.0.3"
- "webidl-conversions" "^3.0.0"
-
-"whatwg-url@^8.0.0", "whatwg-url@^8.5.0":
- "integrity" "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg=="
- "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz"
- "version" "8.7.0"
- dependencies:
- "lodash" "^4.7.0"
- "tr46" "^2.1.0"
- "webidl-conversions" "^6.1.0"
-
-"which-boxed-primitive@^1.0.2":
- "integrity" "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg=="
- "resolved" "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz"
- "version" "1.0.2"
- dependencies:
- "is-bigint" "^1.0.1"
- "is-boolean-object" "^1.1.0"
- "is-number-object" "^1.0.4"
- "is-string" "^1.0.5"
- "is-symbol" "^1.0.3"
-
-"which-collection@^1.0.1":
- "integrity" "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A=="
- "resolved" "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz"
- "version" "1.0.1"
- dependencies:
- "is-map" "^2.0.1"
- "is-set" "^2.0.1"
- "is-weakmap" "^2.0.1"
- "is-weakset" "^2.0.1"
-
-"which-module@^2.0.0":
- "integrity" "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q=="
- "resolved" "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz"
- "version" "2.0.0"
-
-"which-typed-array@^1.1.2", "which-typed-array@^1.1.8":
- "integrity" "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA=="
- "resolved" "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz"
- "version" "1.1.9"
- dependencies:
- "available-typed-arrays" "^1.0.5"
- "call-bind" "^1.0.2"
- "for-each" "^0.3.3"
- "gopd" "^1.0.1"
- "has-tostringtag" "^1.0.0"
- "is-typed-array" "^1.1.10"
-
-"which@^1.2.14", "which@^1.2.9", "which@^1.3.1":
- "integrity" "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="
- "resolved" "https://registry.npmjs.org/which/-/which-1.3.1.tgz"
- "version" "1.3.1"
- dependencies:
- "isexe" "^2.0.0"
-
-"which@^2.0.1":
- "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="
- "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "isexe" "^2.0.0"
-
-"which@^2.0.2":
- "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="
- "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
- "version" "2.0.2"
- dependencies:
- "isexe" "^2.0.0"
-
-"word-wrap@~1.2.3":
- "integrity" "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
- "resolved" "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz"
- "version" "1.2.3"
-
-"wordwrap@^1.0.0":
- "integrity" "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
- "resolved" "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz"
- "version" "1.0.0"
-
-"worker-farm@^1.7.0":
- "integrity" "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw=="
- "resolved" "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz"
- "version" "1.7.0"
- dependencies:
- "errno" "~0.1.7"
-
-"wrap-ansi@^5.1.0":
- "integrity" "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q=="
- "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz"
- "version" "5.1.0"
- dependencies:
- "ansi-styles" "^3.2.0"
- "string-width" "^3.0.0"
- "strip-ansi" "^5.0.0"
-
-"wrap-ansi@^6.2.0":
- "integrity" "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="
- "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz"
- "version" "6.2.0"
- dependencies:
- "ansi-styles" "^4.0.0"
- "string-width" "^4.1.0"
- "strip-ansi" "^6.0.0"
-
-"wrappy@1":
- "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
- "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
- "version" "1.0.2"
-
-"write-file-atomic@^3.0.0":
- "integrity" "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q=="
- "resolved" "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz"
- "version" "3.0.3"
- dependencies:
- "imurmurhash" "^0.1.4"
- "is-typedarray" "^1.0.0"
- "signal-exit" "^3.0.2"
- "typedarray-to-buffer" "^3.1.5"
-
-"write@1.0.3":
- "integrity" "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig=="
- "resolved" "https://registry.npmjs.org/write/-/write-1.0.3.tgz"
- "version" "1.0.3"
- dependencies:
- "mkdirp" "^0.5.1"
-
-"ws@^6.1.2":
- "integrity" "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw=="
- "resolved" "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz"
- "version" "6.2.2"
- dependencies:
- "async-limiter" "~1.0.0"
-
-"ws@^7.4.6":
- "integrity" "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw=="
- "resolved" "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz"
- "version" "7.5.8"
-
-"ws@8.7.0":
- "integrity" "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg=="
- "resolved" "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz"
- "version" "8.7.0"
-
-"xml-name-validator@^3.0.0":
- "integrity" "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
- "resolved" "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz"
- "version" "3.0.0"
-
-"xmlchars@^2.2.0":
- "integrity" "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
- "resolved" "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz"
- "version" "2.2.0"
-
-"xtend@^4.0.0", "xtend@~4.0.1":
- "integrity" "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
- "resolved" "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
- "version" "4.0.2"
-
-"y18n@^4.0.0":
- "integrity" "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
- "resolved" "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz"
- "version" "4.0.3"
-
-"yallist@^3.0.2":
- "integrity" "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
- "resolved" "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"
- "version" "3.1.1"
-
-"yaml@^1.7.2":
- "integrity" "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg=="
- "resolved" "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz"
- "version" "1.10.0"
-
-"yargs-parser@^13.1.2":
- "integrity" "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg=="
- "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz"
- "version" "13.1.2"
- dependencies:
- "camelcase" "^5.0.0"
- "decamelize" "^1.2.0"
-
-"yargs-parser@^18.1.2":
- "integrity" "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="
- "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz"
- "version" "18.1.3"
- dependencies:
- "camelcase" "^5.0.0"
- "decamelize" "^1.2.0"
-
-"yargs-parser@20.x":
- "integrity" "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw=="
- "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz"
- "version" "20.2.7"
-
-"yargs@^13.3.2":
- "integrity" "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw=="
- "resolved" "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz"
- "version" "13.3.2"
- dependencies:
- "cliui" "^5.0.0"
- "find-up" "^3.0.0"
- "get-caller-file" "^2.0.1"
- "require-directory" "^2.1.1"
- "require-main-filename" "^2.0.0"
- "set-blocking" "^2.0.0"
- "string-width" "^3.0.0"
- "which-module" "^2.0.0"
- "y18n" "^4.0.0"
- "yargs-parser" "^13.1.2"
-
-"yargs@^15.4.1":
- "integrity" "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="
- "resolved" "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz"
- "version" "15.4.1"
- dependencies:
- "cliui" "^6.0.0"
- "decamelize" "^1.2.0"
- "find-up" "^4.1.0"
- "get-caller-file" "^2.0.1"
- "require-directory" "^2.1.1"
- "require-main-filename" "^2.0.0"
- "set-blocking" "^2.0.0"
- "string-width" "^4.2.0"
- "which-module" "^2.0.0"
- "y18n" "^4.0.0"
- "yargs-parser" "^18.1.2"
-
-"yarn@^1.22.19":
- "integrity" "sha512-/0V5q0WbslqnwP91tirOvldvYISzaqhClxzyUKXYxs07yUILIs5jx/k6CFe8bvKSkds5w+eiOqta39Wk3WxdcQ=="
- "resolved" "https://registry.npmjs.org/yarn/-/yarn-1.22.19.tgz"
- "version" "1.22.19"
-
-"yauzl@^2.10.0":
- "integrity" "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="
- "resolved" "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz"
- "version" "2.10.0"
- dependencies:
- "buffer-crc32" "~0.2.3"
- "fd-slicer" "~1.1.0"
-
-"yn@3.1.1":
- "integrity" "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
- "resolved" "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz"
- "version" "3.1.1"