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 @@ +

-
- -
+ + Outil de Performance React
- Outil de Performance pour React -
- Nominé aux React Open Source Awards 2020 + 🏆 Nominé pour les React Open Source Awards 2020

-

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


+

- - GitHub + + Chrome Web Store - - Build Status + + Utilisateurs sur le Chrome Web Store - - npm version + + Évaluation sur le Chrome Web Store - BabelPresetPrefs - LintPrefs

- -

- 🇷🇺   РУССКАЯ ВЕРСИЯ   •   🇺🇸   ENGLISH VERSION + 🇷🇺   РУССКАЯ ВЕРСИЯ   •   🇺🇸   ENGLISH VERSION   •   👩‍💻 README Développeur

- + +

+ +##

✨ 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 + + +
+ +### 💾 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 +

ManuelCaractéristiquesWebsiteEn 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 : + + +
+ +

🎉 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 @@

-
- -
-
+ React Performance Tool
- Nominated for React Open Source Awards 2020 + 🏆 Nominated for React Open Source Awards 2020

-

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!


+

- - GitHub + + Chrome Web Store - - Build Status + + Chrome Web Store Users - - npm version + + Chrome Web Store Rating - BabelPresetPrefs - LintPrefs

- -

- 🇷🇺   РУССКАЯ ВЕРСИЯ   •   🇫🇷   VERSION FRANÇAISE   •   DEVELOPER INSTALL   •   DEVELOPER README + 🇷🇺   РУССКАЯ ВЕРСИЯ   •   🇫🇷   VERSION FRANÇAISE   •   👩‍💻 Developer README

- +

+##

✨ 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 UseFeaturesWebsiteRead 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 + + +
-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: + + +
-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 @@ -

- -

- Отладка стейтов для приложений React - -
Номинирован на премию -
React Open Source Awards 2020 - + + Инструмент для анализа производительности React +
+ 🏆 Номинант на React Open Source Awards 2020 +

-[![GitHub](https://img.shields.io/github/license/oslabs-beta/reactime)](https://github.com/oslabs-beta/reactime) [![Build Status](https://travis-ci.com/oslabs-beta/reactime.svg?branch=master)](https://travis-ci.com/oslabs-beta/reactime) [![npm version](https://badge.fury.io/js/reactime.svg)](http://badge.fury.io/js/reactime) ![BabelPresetPrefs](https://img.shields.io/badge/babel%20preset-airbnb-ff69b4) ![LintPrefs](https://img.shields.io/badge/linted%20with-eslint-blueviolet) +

Мощное расширение Chrome, которое улучшает процесс разработки React за счёт отладки с путешествиями во времени и углублённого мониторинга производительности

+
+ +

+ + Chrome Web Store + + + Chrome Web Store Users + + + Chrome Web Store Rating + +


- 🇺🇸   ENGLISH VERSION   •   🇫🇷   VERSION FRANÇAISE + 🇺🇸   ENGLISH VERSION   •   🇫🇷   VERSION FRANÇAISE   •   👩‍💻 Руководство для разработчиков

- + +

+ +##

✨ Ключевые особенности

+ +### 🔍 Визуализация состояния + +- **Разнообразные представления**: Отображение состояния приложения в виде графов компонентов, JSON-деревьев, графиков производительности и деревьев доступности +- **История изменений**: Отслеживайте изменения состояния во времени с удобной визуализацией истории +- **Метрики веб-приложения**: Отслеживайте важные метрики производительности в реальном времени +- **Аналитика доступности**: Анализируйте дерево доступности вашего приложения на каждом этапе изменения состояния +
+ +

На главном экране доступны два основных выбора из выпадающего списка:

+ +- **Timejump**: Просматривайте и перемещайтесь по истории снимков состояния (snapshot) вашего приложения. Можно переместиться в любую точку во времени, чтобы увидеть, как состояние эволюционировало при изменениях. Также доступна кнопка воспроизведения, чтобы автоматически проиграть каждое изменение состояния. +- **Providers / Consumers**: Глубже понимайте зависимости контекста приложения и его взаимодействия, визуализируя отношения провайдеров и потребителей. +
+ +

+ +

+
+ +### ⏱️ Отладка с путешествиями во времени + +- **Снимки состояния**: Фиксируйте и перемещайтесь по истории состояния приложения +- **Элементы управления воспроизведением**: Автоматически воспроизводите изменения состояния с регулировкой скорости +- **Точки мгновенного перехода**: Мгновенно возвращайтесь к любому предыдущему состоянию +- **Сравнение состояний**: Сравнивайте разницу между снимками состояния +
+ +

+ +

+
+ +### 📊 Анализ производительности + +- **Метрики компонентов**: Отслеживайте время рендера и узкие места в производительности +- **Сравнение серий**: Сопоставляйте производительность при разных наборах изменений состояния +- **Определение перерисовок**: Находите и исправляйте избыточные циклы рендера +- **Web Vitals**: Следите за Core Web Vitals и другими метриками +
+
+ +### 🔄 Поддержка современных фреймворков + + +
+ +### 💾 Сохранение и обмен состоянием + +Reactime упрощает сохранение и обмен историей состояния вашего приложения: + +- **Экспорт истории**: Сохраняйте записанные снимки в JSON-файл для дальнейшего анализа или передачи +- **Импорт предыдущих сессий**: Загружайте ранее сохранённые снимки, чтобы сравнивать изменения состояния между разными сессиями +- **Межсессионный анализ**: Сопоставляйте производительность и изменения состояния между разными этапами разработки +
+ +

+

+
+ +### 📚 Интерактивная документация + +Reactime предлагает обширную документацию, помогающую разработчикам разобраться в архитектуре и API инструмента. После клонирования репозитория достаточно запустить `npm run docs` в корневой директории, а затем открыть сгенерированный файл `/docs/index.html`, в котором представлены: + + +
+ +

🎉 Что нового!

-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

- -[![GitHub](https://img.shields.io/github/license/oslabs-beta/reactime)](https://github.com/oslabs-beta/reactime) [![Build Status](https://travis-ci.com/oslabs-beta/reactime.svg?branch=master)](https://travis-ci.com/oslabs-beta/reactime) [![npm version](https://badge.fury.io/js/reactime.svg)](http://badge.fury.io/js/reactime) [![Dependencies](https://david-dm.org/oslabs-beta/reactime.svg)](https://david-dm.org/oslabs-beta/reactime#info=dependencies) [![DevDependencies](https://david-dm.org/oslabs-beta/reactime/dev-status.svg)](https://david-dm.org/oslabs-beta/reactime?type=dev) [![Vulnerabilities](https://snyk.io/test/github/oslabs-beta/reactime/badge.svg)](https://snyk.io/test/github/oslabs-beta/reactime) - - -![demo](./demo.gif) - - - -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} + +
+ ); + } +} + +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 ( + + ); +}; + +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 ( + + ); +} 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} + +
+ ); + } +} + +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 ( + + ); +}; + +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

+// +//
+// ); +// } 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

+// +//
+// ); +// } 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 ( - ); 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

+// +//
+// ); +// } 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} -
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 ( - + <> + + ); }; 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 ( +
+ +
+ ); } +} - 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 ( +
+
- ) + ); +}; + +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}

+
+ +
+ + + + + +
+ +
+

History:

+
+ {state.history.map((value, index) => ( + + {value} + {index < state.history.length - 1 ? ' → ' : ''} + + ))} +
+
+ +
+

Secondary Counter: {secondaryState.count}

+
+ + + + +
+
+

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}

+
+ +
+ + + + + +
+ +
+

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}!

+ +
+ ) : ( +
+

Please log in:

+ + +
+ )}
); } - 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}

+
+ +
+ + + + + +
+ +
+

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 ( + + ); +}; + +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( - -
- ); -}; - -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 ? ( + + ) : ( + + )} + {isCurrIndex ? ( + + ) : ( + + )} +
+
+ +
+
+
+ ); +}; + +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 ( +
+ - ); -}; - -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. -
-
- -
- ); - 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 ( +
+
+ + +
+ +
+ + +
+ +
+ + +
+ + {linkType === '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 */} - -   - {' '} - {/* This is a non-breaking space - Prevents an automatic line break at this position */} - -    + // 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 */} - -   - -    + return ( +
+
+ + +
- {/* Controls for the link selections. */} - -   - +
+ + +
- {/* Controls for the select selections. */} - -   - +
+ + +
- {/* This is the slider control for the step option */} - {linkType === 'step' && layout !== 'polar' && ( - <> -    - -   + {linkType === '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} - -
- +
+
+ + -
- + + - {!comparison.length ? ( - No series available - ) : ( - comparison.map((tabElem, index) => ( - {tabElem.name} - )) - )} - - -

Compare Actions

- - - -
-
- - - { } - - - - - {barStacks => barStacks.map((barStack, idx) => { - // Uses map method to iterate through all components, - // creating a rect component (from visx) for each iteration. - // height/width/etc. are calculated by visx. - // to set X and Y scale, it will used the p`assed in function and - // will run it on the array thats outputted by data - const bar = barStack.bars[currentIndex]; - if (Number.isNaN(bar.bar[1]) || bar.height < 0) { - bar.height = 0; - } - return ( - { - dispatch( - onHoverExit(data.componentData[bar.key].rtid), - (tooltipTimeout = window.setTimeout(() => { - hideTooltip(); - }, 300)), - ); - }} - // Cursor position in window updates position of the tool tip - onMouseMove={event => { - dispatch(onHover(data.componentData[bar.key].rtid)); - if (tooltipTimeout) clearTimeout(tooltipTimeout); - const top = event.clientY - margin.top - bar.height; - const left = bar.x + bar.width / 2; - showTooltip({ - tooltipData: bar, - tooltipTop: top, - tooltipLeft: left, - }); - }} - /> - ); - })} - - - {barStacks => barStacks.map((barStack, idx) => { - // Uses map method to iterate through all components, - // creating a rect component (from visx) for each iteration. - // height/width/etc. are calculated by visx. - if (!barStack.bars[currentIndex]) { - return

No Comparison

; - } - const bar = barStack.bars[currentIndex]; - if (Number.isNaN(bar.bar[1]) || bar.height < 0) { - bar.height = 0; - } - return ( - { - dispatch( - onHoverExit(data.componentData[bar.key].rtid), - (tooltipTimeout = window.setTimeout(() => { - hideTooltip(); - }, 300)), - ); - }} - // Cursor position in window updates position of the tool tip - onMouseMove={event => { - dispatch(onHover(data.componentData[bar.key].rtid)); - if (tooltipTimeout) clearTimeout(tooltipTimeout); - const top = event.clientY - margin.top - bar.height; - const left = bar.x + bar.width / 2; - showTooltip({ - tooltipData: bar, - tooltipTop: top, - tooltipLeft: left, - }); - }} - /> - ); - })} - - - ({ - fill: 'rgb(231, 231, 231)', - fontSize: 11, - verticalAnchor: 'middle', - textAnchor: 'end', - })} - /> - ({ - fill: 'rgb(231, 231, 231)', - fontSize: 11, - textAnchor: 'middle', - })} - /> - - Rendering Time (ms) - - - Series ID - - - {/* FOR HOVER OVER DISPLAY */} - {tooltipOpen && tooltipData && ( - -
- {' '} - {tooltipData.key} - {' '} -
-
{data.componentData[tooltipData.key].stateType}
-
- {' '} - {formatRenderTime(tooltipData.bar.data[tooltipData.key])} - {' '} -
-
- {' '} - - {formatSnapshotId(getSnapshotId(tooltipData.bar.data))} - -
-
- )} -
- ); -}; - -export default BarGraphComparison; diff --git a/src/app/components/StateRoute/PerformanceVisx/BarGraphComparisonActions.tsx b/src/app/components/StateRoute/PerformanceVisx/BarGraphComparisonActions.tsx deleted file mode 100644 index 3ed79b17f..000000000 --- a/src/app/components/StateRoute/PerformanceVisx/BarGraphComparisonActions.tsx +++ /dev/null @@ -1,331 +0,0 @@ -// @ts-nocheck -import React, { useEffect } from 'react'; -import { BarStack } from '@visx/shape'; -import { Group } from '@visx/group'; -import { Grid } from '@visx/grid'; -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 { makeStyles } from '@material-ui/core/styles'; -import Select from '@material-ui/core/Select'; -import MenuItem from '@material-ui/core/MenuItem'; -import FormControl from '@material-ui/core/FormControl'; -import { deleteSeries, setCurrentTabInApp } from '../../../actions/actions'; -import { useStoreContext } from '../../../store'; -import { TooltipData, Margin, BarGraphComparisonAction, ActionObj, } from '../../FrontendTypes'; - -/* DEFAULTS */ -const margin: Margin = { - top: 30, right: 30, bottom: 0, left: 50, -}; -const axisColor = '#62d6fb'; -const background = '#242529'; -const tooltipStyles = { - ...defaultStyles, - minWidth: 60, - backgroundColor: 'rgba(0,0,0,0.9)', - color: 'white', - fontSize: '14px', - lineHeight: '18px', - fontFamily: 'Roboto', -}; - -const BarGraphComparisonActions = (props: BarGraphComparisonAction) => { - const [dispatch] = useStoreContext(); - const { - width, height, data, comparison, setSeries, series, setAction, action - } = props; - const [snapshots] = React.useState(0); - const [setOpen] = React.useState(false); - const [setPicOpen] = React.useState(false); - useEffect(() => { - dispatch(setCurrentTabInApp('performance-comparison')); - }, []); - - const { - tooltipOpen, - tooltipLeft, - tooltipTop, - tooltipData, - hideTooltip, - showTooltip, - } = useTooltip(); - let tooltipTimeout: number; - - const { containerRef, TooltipInPortal } = useTooltipInPortal(); - const keys = Object.keys(data[0]).filter((componentName) => componentName !== 'name' && componentName !== 'seriesName' && componentName !== 'snapshotId'); - // data accessor (used to generate scales) and formatter (add units for on hover box) - const getSeriesName = (action: ActionObj):string => action.seriesName; - - // create visualization SCALES with cleaned data. - // the domain array/xAxisPoints elements will place the bars along the x-axis - const seriesNameScale = scaleBand({ - domain: data.map(getSeriesName), - padding: 0.2, - }); - // This function will iterate through the snapshots of the series, - // and grab the highest render times (sum of all component times). - // We'll then use it in the renderingScale function and compare - // with the render time of the current tab. - // The max render time will determine the Y-axis's highest number. - const calculateMaxTotalRender = () => { - let currentMax = -Infinity; - for (let i = 0; i < data.length; i += 1) { - let currentSum = 0; - for (const key of keys) if (data[i][key]) currentSum += data[i][key]; - if (currentSum > currentMax) currentMax = currentSum; - } - return currentMax; - }; - - // the domain array on rendering scale will set the coordinates for Y-aix points. - const renderingScale = scaleLinear({ - domain: [0, calculateMaxTotalRender()], - nice: true, - }); - // the domain array will assign each key a different color to make rectangle boxes - // and use range to set the color scheme each bar - const colorScale = scaleOrdinal({ - domain: keys, - range: schemeSet3, - }); - - // setting max dimensions and scale ranges - const xMax = width - margin.left - margin.right; - const yMax = height - margin.top - 200; - seriesNameScale.rangeRound([0, xMax]); - renderingScale.range([yMax, 0]); - - // useStyles will change the styling on save series dropdown feature - const useStyles = makeStyles(theme => ({ - formControl: { - margin: theme.spacing(1), - minWidth: 80, - height: 30, - }, - select: { - minWidth: 80, - fontSize: '.75rem', - fontWeight: '200', - border: '1px solid grey', - borderRadius: 4, - color: 'grey', - height: 30, - }, - })); - - const classes = useStyles(); - - const handleSeriesChange = event => { - if (!event) return; - setSeries(event.target.value); - setAction(false); - }; - - const handleActionChange = event => { - if (!event) return; - setAction(event.target.value); - setSeries(false); - }; - - const animateButton = function (e) { - e.preventDefault(); - e.target.classList.add('animate'); - e.target.innerHTML = 'Deleted!'; - setTimeout(() => { - e.target.innerHTML = 'Clear All Series'; - e.target.classList.remove('animate'); - }, 1000); - }; - const classname = document.getElementsByClassName('delete-button'); - for (let i = 0; i < classname.length; i += 1) { - classname[i].addEventListener('click', animateButton, false); - } - const seriesList = comparison.map(elem => elem.data.barStack); - const actionsList = seriesList.flat(); - const testList = actionsList.map(elem => elem.name); - - const finalList = []; - for (let i = 0; i < testList.length; i += 1) { - if (testList[i] !== '' && !finalList.includes(testList[i])) finalList.push(testList[i]); - } - - return ( -
-
-
- -

Compare Series:

- - - -

Compare Actions

- - - -
-
- - - - - - - {barStacks => barStacks.map(barStack => barStack.bars.map(bar => ( - { - tooltipTimeout = window.setTimeout(() => { - hideTooltip(); - }, 300); - }} - // Cursor position in window updates position of the tool tip. - onMouseMove={event => { - if (tooltipTimeout) clearTimeout(tooltipTimeout); - const top = event.clientY - margin.top - bar.height; - const left = bar.x + bar.width / 2; - showTooltip({ - tooltipData: bar, - tooltipTop: top, - tooltipLeft: left, - }); - }} - /> - )))} - - - ({ - fill: 'rgb(231, 231, 231)', - fontSize: 11, - verticalAnchor: 'middle', - textAnchor: 'end', - })} - /> - ({ - fill: 'rgb(231, 231, 231)', - fontSize: 11, - textAnchor: 'middle', - })} - /> - - Rendering Time (ms) - - - Series Name - - - {/* FOR HOVER OVER DISPLAY */} - {tooltipOpen && tooltipData && ( - -
- {tooltipData.key} -
-
- { - `${tooltipData.bar.data[tooltipData.key]} ms` - } -
-
- - {tooltipData.bar.data.seriesName} - -
-
- )} -
- ); -}; - -export default BarGraphComparisonActions; diff --git a/src/app/components/StateRoute/PerformanceVisx/PerformanceVisx.tsx b/src/app/components/StateRoute/PerformanceVisx/PerformanceVisx.tsx index 83aad258e..e13f649e7 100644 --- a/src/app/components/StateRoute/PerformanceVisx/PerformanceVisx.tsx +++ b/src/app/components/StateRoute/PerformanceVisx/PerformanceVisx.tsx @@ -3,27 +3,17 @@ /* eslint-disable no-restricted-syntax */ /* eslint-disable max-len */ import React, { useState, useEffect } from 'react'; -import { - MemoryRouter as Router, - Route, - NavLink, - Switch, - Redirect, -} from 'react-router-dom'; -import RenderingFrequency from './RenderingFrequency'; +import { MemoryRouter as Router, Route, NavLink, Routes, Navigate } from 'react-router-dom'; import BarGraph from './BarGraph'; -import BarGraphComparison from './BarGraphComparison'; -import BarGraphComparisonActions from './BarGraphComparisonActions'; -import { useStoreContext } from '../../../store'; -import { setCurrentTabInApp } from '../../../actions/actions'; -import { PerfData, Series } from '../../FrontendTypes'; - -interface PerformanceVisxProps { - width: number; - height: number; - snapshots: []; - hierarchy: any; -} +import { useDispatch, useSelector } from 'react-redux'; +import { setCurrentTabInApp } from '../../../slices/mainSlice'; +import { + PerfData, + Series, + PerformanceVisxProps, + RootState, + MainState, +} from '../../../FrontendTypes'; const collectNodes = (snaps, componentName) => { const componentsResult = []; @@ -49,9 +39,13 @@ const collectNodes = (snaps, componentName) => { if (x !== 0 && componentsResult.length !== 0) { // needs to be stringified because values are hard to determine if // true or false if in they're seen as objects - if (JSON.stringify(Object.values(componentsResult[newChange - ? componentsResult.length - 1 : trackChanges])[0]) - !== JSON.stringify(cur.componentData.props)) { + if ( + JSON.stringify( + Object.values( + componentsResult[newChange ? componentsResult.length - 1 : trackChanges], + )[0], + ) !== JSON.stringify(cur.componentData.props) + ) { newChange = true; const props = { [`snapshot${x}`]: { ...cur.componentData.props } }; componentsResult.push(props); @@ -83,7 +77,7 @@ const collectNodes = (snaps, componentName) => { return finalResults; }; -type currNum = number +type currNum = number; /* DATA HANDLING HELPER FUNCTIONS */ const traverse = (snapshot, data, snapshots, currTotalRender: currNum = 0): void => { @@ -94,9 +88,7 @@ const traverse = (snapshot, data, snapshots, currTotalRender: currNum = 0): void const componentName = child.name + -[idx + 1]; // Get component Rendering Time - const renderTime = Number( - Number.parseFloat(child.componentData.actualDuration).toPrecision(5), - ); + const renderTime = Number(Number.parseFloat(child.componentData.actualDuration).toPrecision(5)); // sums render time for all children const childrenRenderTime = currTotalRender + renderTime; // components as keys and set the value to their rendering time @@ -140,7 +132,7 @@ const allStorage = (): Series[] => { const getSnapshotIds = (obj, snapshotIds = []): string[] => { snapshotIds.push(`${obj.name}.${obj.branch}`); if (obj.children) { - obj.children.forEach(child => { + obj.children.forEach((child) => { getSnapshotIds(child, snapshotIds); }); } @@ -161,99 +153,74 @@ const getPerfMetrics = (snapshots, snapshotsIds): PerfData => { return perfData; }; +const getActions = () => { + // Creates the actions array used to populate the compare actions dropdown (WORK IN PROGRESS) + const project = localStorage.getItem('project'); + const seriesArr: Series[] = project === null ? [] : JSON.parse(project); + const actionsArr = []; + + if (seriesArr.length) { + for (let i = 0; i < seriesArr.length; i += 1) { + for (const actionObj of seriesArr[i].data.barStack) { + if (actionObj.name === 'action') { + actionObj.seriesName = seriesArr[i].name; + actionsArr.push(actionObj); + } + } + } + } + return actionsArr; +}; + /* EXPORT COMPONENT */ const PerformanceVisx = (props: PerformanceVisxProps): JSX.Element => { // hook used to dispatch onhover action in react const { - width, height, snapshots, hierarchy, + width, // from ParentSize provided in StateRoute + height, // from ParentSize provided in StateRoute + snapshots, // from 'tabs[currentTab]' object in 'MainContainer' + hierarchy, // from 'tabs[currentTab]' object in 'MainContainer' } = props; - const [{ currentTabInApp }, dispatch] = useStoreContext(); - const NO_STATE_MSG = 'No state change detected. Trigger an event to change state'; + const dispatch = useDispatch(); + const { currentTabInApp }: MainState = useSelector((state: RootState) => state.main); const data = getPerfMetrics(snapshots, getSnapshotIds(hierarchy)); - const [series, setSeries] = useState(true); - const [action, setAction] = useState(false); - const [route, setRoute] = useState('All Routes'); const [snapshot, setSnapshot] = useState('All Snapshots'); - // snapshots = 3.0 - useEffect(() => { - dispatch(setCurrentTabInApp('performance')); - }, [dispatch]); - // Creates the actions array used to populate the compare actions dropdown - const getActions = () => { - const project = localStorage.getItem('project'); - const seriesArr: Series[] = project === null ? [] : JSON.parse(project); - const actionsArr = []; + getActions(); - if (seriesArr.length) { - for (let i = 0; i < seriesArr.length; i += 1) { - for (const actionObj of seriesArr[i].data.barStack) { - if (actionObj.name === action) { - actionObj.seriesName = seriesArr[i].name; - actionsArr.push(actionObj); - } - } - } - } - return actionsArr; - }; + useEffect(() => { + dispatch(setCurrentTabInApp('performance')); // dispatch sent at initial page load allowing changing "immer's" draft.currentTabInApp to 'performance' to facilitate render. + renderForTutorial(); + }, []); - const renderComparisonBargraph = () => { - if (hierarchy && series !== false) { - return ( - - ); - } - return ( - - ); - }; - // create allRoutes variable to hold urls - const allRoutes = []; + const allRoutes = []; // create allRoutes variable to hold urls const filteredSnapshots = []; - // loop through data.barStack + for (let i = 0; i < data.barStack.length; i += 1) { - // set url variable to new route url - const url = new URL(data.barStack[i].route); - // if all the routes do not have the pathname property on url then push it onto all routes array + // loop through data.barStack + const url = new URL(data.barStack[i].route); // set url variable to new route url if (!allRoutes.includes(url.pathname)) { + // if all the routes do not have the pathname property on url then push it onto all routes array allRoutes.push(url.pathname); } - // if the route exists and it is equal to url.pathname then push data.barstack at i into filteredSnapshots array if (route && route === url.pathname) { + // if the route exists and it is equal to url.pathname then push data.barstack at i into filteredSnapshots array filteredSnapshots.push(data.barStack[i]); } } - // if route does not equal to All Routes, set data.barstack to filteredSnapshots array if (route !== 'All Routes') { + // if route does not equal to All Routes, set data.barstack to filteredSnapshots array data.barStack = filteredSnapshots; } - // maxheight is referring to the max height in render time to choose the scaling size for graph - let maxHeight = 0; + let maxHeight = 0; // maxheight is referring to the max height in render time to choose the scaling size for graph if (snapshot !== 'All Snapshots') { - // filter barStack to make it equal to an array of length 1 with object matching snapshot ID to mirror the data.barStack object's shape - const checkData = [data.barStack.find(comp => comp.snapshotId === snapshot)]; + const checkData = [data.barStack.find((comp) => comp.snapshotId === snapshot)]; // filter barStack to make it equal to an array of length 1 with object matching snapshot ID to mirror the data.barStack object's shape const holdData = []; - // looping through checkData which is composed of a single snapshot while pushing key/values to a new object and setting maxHeight + for (const key in checkData[0]) { + // looping through checkData which is composed of a single snapshot while pushing key/values to a new object and setting maxHeight if (key !== 'route' && key !== 'snapshotId') { if (maxHeight < checkData[0][key]) maxHeight = checkData[0][key]; const name = {}; @@ -263,84 +230,45 @@ const PerformanceVisx = (props: PerformanceVisxProps): JSX.Element => { holdData[holdData.length - 1].snapshotId = key; } } - // maxTotalRender height of bar is aligned to y-axis - // 1.15 adjusts the numbers on the y-axis so the max bar's true height never reaches the max of the y-axis - data.maxTotalRender = maxHeight * 1.15; - // assign holdData to data.barStack to be used later to create graph - if (holdData) data.barStack = holdData; - } - const renderBargraph = (): JSX.Element | null => { - if (hierarchy) { - return ( -
- -
- ); - } - return null; - }; - - const renderComponentDetailsView = () => { - if (hierarchy) { - return ; - } - return
{NO_STATE_MSG}
; - }; + data.maxTotalRender = maxHeight * 1.15; // maxTotalRender height of bar is aligned to y-axis. 1.15 adjusts the numbers on the y-axis so the max bar's true height never reaches the max of the y-axis + if (holdData) data.barStack = holdData; // assign holdData to data.barStack to be used later to create graph + } - // This will redirect to the proper tabs during the tutorial const renderForTutorial = () => { - if (currentTabInApp === 'performance') return ; - if (currentTabInApp === 'performance-comparison') return ; + // This will redirect to the proper tabs during the tutorial + // Updated redirect to Navigate v23 redirect no longer supported in react router dom after v6 + if (currentTabInApp === 'performance') return ; + if (currentTabInApp === '/performance-comparison') + return ; return null; }; return ( - -
- - Snapshots View - - - Comparison View - - - Component Details - -
- - {renderForTutorial()} - - - - - - -
+ <> + + + +
+ ) : 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. +

+
+ )} +
+ + +
+
+ ) + } + /> + + {({ 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 ( - + ); +}; + +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)} - /> - - - ); - } -} 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 ( -
-
-
- - +
+
+ { + toggleRecord(); + setRecordingActions(!recordingActions); + }} + /> + +
+
- - - {recordingActions ? ( - - ) : ( - + - {actionView ? ( -
- -
- -
- {/* Rendering of route description components */} - {Object.keys(routes).map((route, i) => ( - ))} + {dropdownSelection === 'Time Jump' && + Object.keys(routes).map((route, i) => ( + + ))} + {/* Add ref for scrolling */} +
- ) : null} +
); } 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 ( -
- - - + 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)', + }, + }); + }; - - - {/* The component below renders a button for the tutorial walkthrough of Reactime */} - + return ( +
+
+ + + + + +
); } 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 ( -
- Reactime Logo + 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 ( +
+ Reactime Logo -

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. +

+ + -
- -
- - 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 ( -
+
- - -
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

- -

- You are {age} years old!

- -
-
); - }`; - - 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

- -

- You are {age} years old!

- -
-
); - }`; - - 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

- -

- You are {age} years old!

- -
-
); - }`; - - 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

- -

- You are {age} years old!

- -
-
); - }`; - - 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!

- -
) - }`; - - 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 ( +
+ +
+ ); + } +} 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 ( +
+ +
+ ); +} + +export default IncrementFunc; + +export function IncrementFuncMultiStates() { + const [count, setCount] = useState(0); + const [count1, setCount1] = useState(1); + return ( +
+ +
+ ); +} 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) => ( -
-
- -
-
- -
- -
-

- - {post.author.name} - -

-
- - - {post.readingTime} read -
-
-
-
-
- ))} -
-
-
- ) -} \ 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 */} -
-
-
-
- Reactime -
-
- -
-

- 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. -

-
- -
- - {setName(e.target.value)}} - /> - - {setEmail(e.target.value)}} - /> -
-
- -
- -
-
-
- {/*
-
-
-
-
-
-
-
- -
-
-
-
- - - - - - - - -
-
- -
-
-
-
- -
- - - -
-
- {/* Footer section */} -
-
-

- © 2022 Reactime, All rights reserved. -

-
-
-
- - ) -} 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 }) => ( - <> -
-
-
-
- Your Company - Your Company -
-

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" - /> -
-
-

{name}

- {profile} -
-
-
- ) -} - - - 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"> - - -
} - {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"