Просмотр исходного кода

Merge branch 'dev/5.0.x' into feat/83696-83702-fix-search-result-item

yohei0125 4 лет назад
Родитель
Сommit
d44544f770

+ 1 - 1
packages/app/package.json

@@ -131,7 +131,7 @@
     "passport-saml": "^3.2.0",
     "passport-twitter": "^1.0.4",
     "prom-client": "^13.0.0",
-    "re2": "^1.16.0",
+    "re2": "^1.17.1",
     "react-card-flip": "^1.0.10",
     "react-image-crop": "^8.3.0",
     "react-multiline-clamp": "^2.0.0",

+ 4 - 4
packages/app/src/client/app.jsx

@@ -96,10 +96,6 @@ Object.assign(componentMappings, {
   'trash-page-list': <TrashPageList />,
 
   'not-found-page': <NotFoundPage />,
-  'not-found-alert': <NotFoundAlert
-    isGuestUserMode={appContainer.isGuestUser}
-    isHidden={pageContainer.state.isNotCreatable || pageContainer.state.isTrashPage}
-  />,
 
   'forbidden-page': <ForbiddenPage />,
 
@@ -128,6 +124,10 @@ if (pageContainer.state.pageId != null) {
 
     'recent-created-icon': <RecentlyCreatedIcon />,
     'user-bookmark-icon': <BookmarkIcon />,
+    'not-found-alert': <NotFoundAlert
+      isGuestUserMode={appContainer.isGuestUser}
+      isHidden={pageContainer.state.isNotCreatable || pageContainer.state.isTrashPage}
+    />,
   });
 
   // show the Page accessory modal when query of "compare" is requested

+ 1 - 1
packages/app/src/components/PageDeleteModal.tsx

@@ -154,7 +154,7 @@ const PageDeleteModal: FC<Props> = (props: Props) => {
           {/* Todo: change the way to show path on modal when too many pages are selected */}
           {/* https://redmine.weseek.co.jp/issues/82787 */}
           {pages.map((page) => {
-            return <div><code>{ page.path }</code></div>;
+            return <div key={page.pageId}><code>{ page.path }</code></div>;
           })}
         </div>
         {renderDeleteRecursivelyForm()}

+ 7 - 2
packages/app/src/components/SearchPage/SearchPageLayout.tsx

@@ -49,9 +49,14 @@ const SearchPageLayout: FC<Props> = (props: Props) => {
                 <div className="input-group-prepend">
                   <label className="input-group-text text-secondary" htmlFor="inputGroupSelect01">{t('search_result.number_of_list_to_display')}</label>
                 </div>
-                <select className="custom-select" id="inputGroupSelect01" onChange={(e) => { props.onPagingLimitChanged(Number(e.target.value)) }}>
+                <select
+                  defaultValue={props.pagingLimit}
+                  className="custom-select"
+                  id="inputGroupSelect01"
+                  onChange={(e) => { props.onPagingLimitChanged(Number(e.target.value)) }}
+                >
                   {[20, 50, 100, 200].map((limit) => {
-                    return <option selected={limit === props.pagingLimit} value={limit}>{limit}{t('search_result.page_number_unit')}</option>;
+                    return <option key={limit} value={limit}>{limit}{t('search_result.page_number_unit')}</option>;
                   })}
                 </select>
               </div>

+ 10 - 5
packages/app/src/components/SearchPage/SearchResultListItem.tsx

@@ -3,7 +3,6 @@ import React, { FC } from 'react';
 import Clamp from 'react-multiline-clamp';
 
 import { UserPicture, PageListMeta, PagePathLabel } from '@growi/ui';
-import { DevidedPagePath } from '@growi/core';
 
 import { IPageSearchResultData } from '../../interfaces/search';
 import PageItemControl from '../Common/Dropdown/PageItemControl';
@@ -28,13 +27,19 @@ const SearchResultListItem: FC<Props> = (props:Props) => {
   // Add prefix 'id_' in pageId, because scrollspy of bootstrap doesn't work when the first letter of id attr of target component is numeral.
   const pageId = `#${pageData._id}`;
 
-  const isPathIncludedHtml = pageMeta.elasticSearchResult?.highlightedPath != null || pageData.path != null;
-  const dPagePath = new DevidedPagePath(pageData.path, false, true);
+  const pageTitle = (
+    <PagePathLabel
+      path={pageMeta.elasticSearchResult?.highlightedPath || pageData.path}
+      isLatterOnly
+      isPathIncludedHtml={pageMeta.elasticSearchResult?.isHtmlInPath}
+    >
+    </PagePathLabel>
+  );
   const pagePathElem = (
     <PagePathLabel
       path={pageMeta.elasticSearchResult?.highlightedPath || pageData.path}
       isFormerOnly
-      isPathIncludedHtml={isPathIncludedHtml}
+      isPathIncludedHtml={pageMeta.elasticSearchResult?.isHtmlInPath}
     />
   );
 
@@ -72,7 +77,7 @@ const SearchResultListItem: FC<Props> = (props:Props) => {
                 <UserPicture user={pageData.lastUpdateUser} />
               </span>
               {/* page title */}
-              <span className="item-title h5 mr-2 mb-0">{dPagePath.latter}</span>
+              <span className="item-title h5 mr-2 mb-0">{pageTitle}</span>
               {/* page meta */}
               <div className="d-flex item-meta py-0 px-1">
                 <PageListMeta page={pageData} bookmarkCount={pageMeta.bookmarkCount} />

+ 3 - 2
packages/app/src/components/SearchPage/SortControl.tsx

@@ -26,7 +26,7 @@ const SortControl: FC <Props> = (props: Props) => {
   };
 
   const renderSortItem = (sort, order) => {
-    return <><span className="mr-3">{t(`search_result.sort_axis.${sort}`)}</span>{renderOrderIcon(order)}</>;
+    return <div className="d-flex align-items-center"><span className="mr-3">{t(`search_result.sort_axis.${sort}`)}</span>{renderOrderIcon(order)}</div>;
   };
 
   return (
@@ -43,13 +43,14 @@ const SortControl: FC <Props> = (props: Props) => {
             className="btn border dropdown-toggle"
             data-toggle="dropdown"
           >
-            <span className="mr-4">{t(`search_result.sort_axis.${props.sort}`)}</span>
+            <span className="mr-4 text-secondary">{t(`search_result.sort_axis.${props.sort}`)}</span>
           </button>
           <div className="dropdown-menu dropdown-menu-right">
             {Object.values(SORT_AXIS).map((sortAxis) => {
               const nextOrder = (props.sort !== sortAxis || props.order === ASC) ? DESC : ASC;
               return (
                 <button
+                  key={sortAxis}
                   className="dropdown-item d-flex justify-content-between"
                   type="button"
                   onClick={() => { onClickChangeSort(sortAxis, nextOrder) }}

+ 1 - 1
packages/app/src/components/Sidebar.tsx

@@ -65,7 +65,7 @@ const SidebarContentsWrapper = () => {
         resetKey={resetKey}
       />
 
-      <div id="grw-sidebar-contents-scroll-target">
+      <div id="grw-sidebar-contents-scroll-target" style={{ minHeight: '100%' }}>
         <div id="grw-sidebar-content-container" onLoad={() => setResetKey(Math.random())}>
           <SidebarContents />
         </div>

+ 1 - 1
packages/app/src/components/Sidebar/CustomSidebar.tsx

@@ -34,7 +34,7 @@ const CustomSidebar: FC<Props> = (props: Props) => {
   const { data: page, mutate } = useSWRxPageByPath('/Sidebar');
 
   const isLoading = page === undefined;
-  const markdown = (page?.revision as IRevision)?.body;
+  const markdown = (page?.revision as IRevision | undefined)?.body;
 
   return (
     <>

+ 12 - 10
packages/app/src/components/Sidebar/PageTree/Item.tsx

@@ -177,10 +177,10 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
   const opacityStyle = { opacity: 1.0 };
   if (page.isTarget) opacityStyle.opacity = 0.7;
 
-  const buttonClass = isOpen ? 'rotate' : '';
+  const buttonClass = isOpen ? 'grw-pagetree-open' : '';
 
   return (
-    <div className="grw-pagetree-item-wrapper">
+    <>
       <div style={opacityStyle} className="grw-pagetree-item d-flex align-items-center">
         <button
           type="button"
@@ -218,16 +218,18 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
       )}
       {
         isOpen && hasChildren() && currentChildren.map(node => (
-          <Item
-            key={node.page._id}
-            isEnableActions={isEnableActions}
-            itemNode={node}
-            isOpen={false}
-            onClickDeleteByPage={onClickDeleteByPage}
-          />
+          <div className="ml-3 mt-2">
+            <Item
+              key={node.page._id}
+              isEnableActions={isEnableActions}
+              itemNode={node}
+              isOpen={false}
+              onClickDeleteByPage={onClickDeleteByPage}
+            />
+          </div>
         ))
       }
-    </div>
+    </>
   );
 
 };

+ 8 - 7
packages/app/src/interfaces/search.ts

@@ -7,15 +7,16 @@ export enum CheckboxType {
 }
 
 export type IPageSearchResultData = {
-  pageData: IPageHasId,
+  pageData: IPageHasId;
   pageMeta: {
-    bookmarkCount?: number,
+    bookmarkCount?: number;
     elasticSearchResult?: {
-      snippet: string,
-      highlightedPath: string,
-    },
-  },
-}
+      snippet: string;
+      highlightedPath: string;
+      isHtmlInPath: boolean;
+    };
+  };
+};
 
 export const SORT_AXIS = {
   RELATION_SCORE: 'relationScore',

+ 4 - 0
packages/app/src/server/middlewares/inject-user-ui-settings-to-localvars.ts

@@ -19,6 +19,10 @@ async function getSettings(userId: string): Promise<Partial<IUserUISettings> | n
 
 module.exports = () => {
   return async(req, res, next) => {
+    if (req.user == null) {
+      return next();
+    }
+
     try {
       res.locals.userUISettings = await getSettings(req.user._id);
     }

+ 1 - 1
packages/app/src/server/models/named-query.ts

@@ -6,7 +6,7 @@ import mongoose, {
 
 import { getOrCreateModel } from '@growi/core';
 import loggerFactory from '../../utils/logger';
-import { INamedQuery, SearchDelegatorName } from '../../interfaces/named-query';
+import { INamedQuery, SearchDelegatorName } from '~/interfaces/named-query';
 
 const logger = loggerFactory('growi:models:named-query');
 

+ 7 - 1
packages/app/src/server/service/search.ts

@@ -348,7 +348,7 @@ class SearchService implements SearchQueryParser, SearchResolver {
 
   // TODO: optimize the way to check isFormattable e.g. check data schema of searchResult
   // So far, it determines by delegatorName passed by searchService.searchKeyword
-  checkIsFormattable(searchResult, delegatorName): boolean {
+  checkIsFormattable(searchResult, delegatorName: SearchDelegatorName): boolean {
     return delegatorName === SearchDelegatorName.DEFAULT;
   }
 
@@ -401,16 +401,22 @@ class SearchService implements SearchQueryParser, SearchResolver {
         pageData.lastUpdateUser = serializeUserSecurely(pageData.lastUpdateUser);
       }
 
+      // const data = searchResult.data.find((data) => {
+      //   return pageData.id === data._id;
+      // });
+
       // increment elasticSearchResult
       let elasticSearchResult;
       const highlightData = data._highlight;
       if (highlightData != null) {
         const snippet = highlightData['body.en'] || highlightData['body.ja'] || '';
         const pathMatch = highlightData['path.en'] || highlightData['path.ja'] || '';
+        const isHtmlInPath = highlightData['path.en'] != null || highlightData['path.ja'] != null;
 
         elasticSearchResult = {
           snippet: filterXss.process(snippet),
           highlightedPath: filterXss.process(pathMatch),
+          isHtmlInPath,
         };
       }
 

+ 31 - 19
packages/app/src/styles/_override-bootstrap-variables.scss

@@ -23,9 +23,16 @@ $gray-600: lighten($dark, 10%) !default;
 $gray-700: lighten($dark, 5%) !default;
 $gray-800: $dark !default;
 $gray-900: darken($dark, 5%) !default;
-$grays: ("50": $gray-50) !default;
+$grays: (
+  '50': $gray-50,
+) !default;
 $red: #ff0a54 !default;
 
+// Options
+//
+// Quickly modify global styling by enabling or disabling optional features.
+
+$enable-shadows: true;
 
 // Grid breakpoints
 //
@@ -38,7 +45,7 @@ $grid-breakpoints: (
   md: 768px,
   lg: 992px,
   xl: 1200px,
-  2xl: 1480px
+  2xl: 1480px,
 );
 
 // Grid containers
@@ -50,44 +57,45 @@ $container-max-widths: (
   md: 720px,
   lg: 960px,
   xl: 1140px,
-  2xl: 1320px
+  2xl: 1320px,
 );
 
-
 //== Typography
 //
 //## Font, line-height, and color for body text, headings, and more.
-$font-family-sans-serif:  Lato, -apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
-$font-family-serif:       Georgia, "Times New Roman", Times, serif;
+$font-family-sans-serif: Lato, -apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
+$font-family-serif: Georgia, 'Times New Roman', Times, serif;
 $font-family-monospace: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
-$font-family-base:        $font-family-sans-serif;
+$font-family-base: $font-family-sans-serif;
 
 $font-size-root: 14px;
 $line-height-base: 1.42857;
 
 $blockquote-small-color: $gray-500;
 
-
 //== Components
 //
-$border-radius:               .15rem;
-$border-radius-sm:            .1rem;
-$border-radius-lg:            .25rem;
-$border-radius-xl:            .35rem;
+$border-radius: 4px;
+$border-radius-sm: 0;
+$border-radius-lg: 8px;
+
+// Buttons + Forms
+//
+// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.
+
+$input-btn-focus-box-shadow: none;
 
 // Buttons
 //
 // For each of Bootstrap's buttons, define text, background, and border color.
 $btn-link-disabled-color: $gray-500;
+$btn-focus-box-shadow: none;
+$btn-active-box-shadow: none;
 
 //== Forms
 //
 $input-border-color: $gray-300;
 
-$input-border-radius: $border-radius-sm;
-$input-border-radius-sm: $border-radius-sm;
-$input-border-radius-lg: $border-radius;
-
 $input-placeholder-color: $gray-500;
 
 $custom-control-indicator-border-color: $gray-400;
@@ -106,9 +114,14 @@ $navbar-brand-padding-y: 0;
 $navbar-nav-link-padding-x: 1rem;
 
 //== Dropdowns
-$dropdown-border-radius: $border-radius-sm;
+$dropdown-border-radius: $border-radius-lg;
 $dropdown-link-disabled-color: $gray-500;
 $dropdown-header-color: $gray-500;
+$dropdown-box-shadow: 0 0.5rem 0.7rem rgba(black, 0.1);
+
+//== Popovers
+$popover-border-radius: $border-radius;
+$popover-box-shadow: 0 0.5rem 0.7rem rgba(black, 0.1);
 
 //== Pagination
 $pagination-disabled-color: $gray-500;
@@ -122,6 +135,7 @@ $toast-header-color: $gray-500;
 
 //== Modals
 $modal-content-border-width: 0;
+$modal-content-border-radius: $border-radius-lg;
 $modal-header-padding-y: 0.75rem;
 $modal-header-padding-x: 1rem;
 
@@ -132,7 +146,6 @@ $alert-color-level: -10;
 
 //== Progress bar
 $progress-height: 4px;
-$progress-border-radius: $border-radius-sm;
 $progress-bg: $gray-100;
 $progress-box-shadow: none;
 
@@ -153,4 +166,3 @@ $pre-color: dummyinvalildcolor; // disable pre color specification with invalid
 $custom-checkbox-indicator-border-radius: 0px;
 $custom-control-indicator-focus-box-shadow: none;
 $custom-control-indicator-size: 1.2rem;
-

+ 7 - 6
packages/app/src/styles/_page-tree.scss

@@ -1,9 +1,4 @@
 .grw-pagetree {
-  .grw-pagetree-item-wrapper {
-    margin-top: 10px;
-    margin-left: 10px;
-  }
-
   .grw-pagetree-item {
     &:hover {
       opacity: 0.7;
@@ -19,8 +14,14 @@
 
     .grw-pagetree-button {
       background-color: transparent;
+      transition: all 0.2s ease-out;
+      transform: rotate(0deg);
+
+      &:focus {
+        box-shadow: none;
+      }
 
-      &.rotate {
+      &.grw-pagetree-open {
         transform: rotate(90deg);
       }
     }

+ 4 - 9
packages/app/src/styles/_search.scss

@@ -73,19 +73,17 @@
   .dropdown-toggle {
     min-width: 95px;
     padding-left: 1.5rem;
-    border-top-left-radius: 40px;
-    border-bottom-left-radius: 40px;
   }
 
   .search-typeahead {
     // corner radius
-    border-top-right-radius: 40px;
-    border-bottom-right-radius: 40px;
+    border-top-right-radius: $border-radius;
+    border-bottom-right-radius: $border-radius;
     .rbt-input-main {
       padding-right: 58px;
       // corner radius
-      border-top-right-radius: 40px;
-      border-bottom-right-radius: 40px;
+      border-top-right-radius: $border-radius;
+      border-bottom-right-radius: $border-radius;
     }
     .rbt-menu {
       @extend .dropdown-menu-right;
@@ -163,9 +161,6 @@
       }
     }
   }
-  .search-typeahead {
-    border-radius: 0 25px 25px 0;
-  }
 }
 
 // TODO : keep the selected list in the same positino as other lists

+ 0 - 2
packages/app/src/styles/_subnav.scss

@@ -42,7 +42,6 @@
   .btn-bookmark {
     height: 40px;
     font-size: 20px;
-    border-radius: $border-radius-xl;
   }
 
   .btn-bookmark {
@@ -94,7 +93,6 @@
 
       height: 30px;
       font-size: 15px !important;
-      border-radius: $border-radius-xl;
     }
 
     .total-likes,

+ 1 - 1
packages/app/src/styles/_tag.scss

@@ -8,7 +8,7 @@
   .grw-tag-label {
     font-size: 12px;
     font-weight: normal;
-    border-radius: $border-radius-sm;
+    border-radius: $border-radius;
   }
 }
 

+ 4 - 2
packages/app/src/styles/theme/_apply-colors-dark.scss

@@ -256,8 +256,10 @@ ul.pagination {
   .grw-pagetree {
     .grw-pagetree-item {
       .grw-triangle-icon {
-        svg {
-          fill: $gray-500;
+        &:not(:hover) {
+          svg {
+            fill: $gray-500;
+          }
         }
       }
       &:hover {

+ 4 - 2
packages/app/src/styles/theme/_apply-colors-light.scss

@@ -173,8 +173,10 @@ $border-color: $border-color-global;
   .grw-pagetree {
     .grw-pagetree-item {
       .grw-triangle-icon {
-        svg {
-          fill: $gray-400;
+        &:not(:hover) {
+          svg {
+            fill: $gray-400;
+          }
         }
       }
       &:hover {

+ 4 - 2
packages/ui/src/components/User/UserPicture.jsx

@@ -38,8 +38,10 @@ export class UserPicture extends React.Component {
   RootElmWithLink = (props) => {
     const { user } = this.props;
     const href = userPageRoot(user);
-
-    return <a href={href} {...props}>{props.children}</a>;
+    // Using <span> tag here instead of <a> tag because UserPicture is used in SearchResultList which is essentially a anchor tag.
+    // Nested anchor tags causes a warning.
+    // https://stackoverflow.com/questions/13052598/creating-anchor-tag-inside-anchor-taga
+    return <span onClick={() => { window.location.href = href }} {...props}>{props.children}</span>;
   }
 
   withTooltip = (RootElm) => {

+ 74 - 29
yarn.lock

@@ -1883,9 +1883,9 @@
   integrity sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==
 
 "@npmcli/fs@^1.0.0":
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.0.0.tgz#589612cfad3a6ea0feafcb901d29c63fd52db09f"
-  integrity sha512-8ltnOpRR/oJbOp8vaGUnipOi3bqkcW+sLHFlyXIr08OGHmVJLB1Hn7QtGXbYcpVtH1gAYZTlmDXtE4YV0+AMMQ==
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.0.tgz#bec1d1b89c170d40e1b73ad6c943b0b75e7d2951"
+  integrity sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==
   dependencies:
     "@gar/promisify" "^1.0.1"
     semver "^7.3.5"
@@ -3701,7 +3701,7 @@ aproba@^1.0.3, aproba@^1.1.1:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
 
-aproba@^2.0.0:
+"aproba@^1.0.3 || ^2.0.0", aproba@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc"
   integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==
@@ -3735,6 +3735,14 @@ archiver@^5.3.0:
     tar-stream "^2.2.0"
     zip-stream "^4.1.0"
 
+are-we-there-yet@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c"
+  integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==
+  dependencies:
+    delegates "^1.0.0"
+    readable-stream "^3.6.0"
+
 are-we-there-yet@~1.1.2:
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
@@ -5627,6 +5635,11 @@ color-string@^1.5.2:
     color-name "^1.0.0"
     simple-swizzle "^0.2.2"
 
+color-support@^1.1.2:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
+  integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
+
 color@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a"
@@ -5907,7 +5920,7 @@ console-browserify@1.1.x, console-browserify@^1.1.0:
   dependencies:
     date-now "^0.1.4"
 
-console-control-strings@^1.0.0, console-control-strings@~1.1.0:
+console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
   integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
@@ -8938,6 +8951,21 @@ functional-red-black-tree@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
 
+gauge@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.0.tgz#afba07aa0374a93c6219603b1fb83eaa2264d8f8"
+  integrity sha512-F8sU45yQpjQjxKkm1UOAhf0U/O0aFt//Fl7hsrNVto+patMHjs7dPI9mFOGUKbhrgKm0S3EjW3scMFuQmWSROw==
+  dependencies:
+    ansi-regex "^5.0.1"
+    aproba "^1.0.3 || ^2.0.0"
+    color-support "^1.1.2"
+    console-control-strings "^1.0.0"
+    has-unicode "^2.0.1"
+    signal-exit "^3.0.0"
+    string-width "^4.2.3"
+    strip-ansi "^6.0.1"
+    wide-align "^1.1.2"
+
 gauge@~2.7.3:
   version "2.7.4"
   resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
@@ -13664,7 +13692,7 @@ nan@^2.12.1, nan@^2.14.0:
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
   integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
 
-nan@^2.14.2:
+nan@^2.14.2, nan@^2.15.0:
   version "2.15.0"
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
   integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
@@ -13861,17 +13889,17 @@ node-gyp@^7.1.0:
     tar "^6.0.2"
     which "^2.0.2"
 
-node-gyp@^8.0.0:
-  version "8.4.0"
-  resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.0.tgz#6e1112b10617f0f8559c64b3f737e8109e5a8338"
-  integrity sha512-Bi/oCm5bH6F+FmzfUxJpPaxMEyIhszULGR3TprmTeku8/dMFcdTcypk120NeZqEt54r1BrgEKtm2jJiuIKE28Q==
+node-gyp@^8.4.1:
+  version "8.4.1"
+  resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937"
+  integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==
   dependencies:
     env-paths "^2.2.0"
     glob "^7.1.4"
     graceful-fs "^4.2.6"
     make-fetch-happen "^9.1.0"
     nopt "^5.0.0"
-    npmlog "^4.1.2"
+    npmlog "^6.0.0"
     rimraf "^3.0.2"
     semver "^7.3.5"
     tar "^6.1.2"
@@ -14204,6 +14232,16 @@ npmlog@^4.0.2, npmlog@^4.1.2:
     gauge "~2.7.3"
     set-blocking "~2.0.0"
 
+npmlog@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.0.tgz#ba9ef39413c3d936ea91553db7be49c34ad0520c"
+  integrity sha512-03ppFRGlsyUaQFbGC2C8QWJN/C/K7PsfyD9aQdhVKAQIH4sQBc8WASqFBP7O+Ut4d2oo5LoeoboB3cGdBZSp6Q==
+  dependencies:
+    are-we-there-yet "^2.0.0"
+    console-control-strings "^1.1.0"
+    gauge "^4.0.0"
+    set-blocking "^2.0.0"
+
 nth-check@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
@@ -16355,14 +16393,14 @@ rc@>=1.2.8, rc@^1.0.1, rc@^1.1.6, rc@^1.2.7:
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
 
-re2@^1.16.0:
-  version "1.16.0"
-  resolved "https://registry.yarnpkg.com/re2/-/re2-1.16.0.tgz#f311eb4865b1296123800ea8e013cec8dab25590"
-  integrity sha512-eizTZL2ZO0ZseLqfD4t3Qd0M3b3Nr0MBWpX81EbPMIud/1d/CSfUIx2GQK8fWiAeHoSekO5EOeFib2udTZLwYw==
+re2@^1.17.1:
+  version "1.17.1"
+  resolved "https://registry.yarnpkg.com/re2/-/re2-1.17.1.tgz#0202025aa20dd574a8cdb439811761d88b70ae59"
+  integrity sha512-TrhxVzakyO/WJsErkc01zjlEiDLCuuRuddbVi2I8YasIbh6MEJfkRoajBRj+ggm00gnGI2EMemE9GrlKrgUZ8Q==
   dependencies:
     install-artifact-from-github "^1.2.0"
-    nan "^2.14.2"
-    node-gyp "^8.0.0"
+    nan "^2.15.0"
+    node-gyp "^8.4.1"
 
 react-bootstrap-typeahead@^3.4.7:
   version "3.4.7"
@@ -18257,9 +18295,9 @@ socks-proxy-agent@^5.0.0:
     socks "^2.3.3"
 
 socks-proxy-agent@^6.0.0:
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.0.tgz#869cf2d7bd10fea96c7ad3111e81726855e285c3"
-  integrity sha512-57e7lwCN4Tzt3mXz25VxOErJKXlPfXmkMLnk310v/jwW20jWRVcgsOit+xNkN3eIEdB47GwnfAEBLacZ/wVIKg==
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87"
+  integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==
   dependencies:
     agent-base "^6.0.2"
     debug "^4.3.1"
@@ -18670,6 +18708,15 @@ string-width@^1.0.1, string-width@^1.0.2:
     is-fullwidth-code-point "^2.0.0"
     strip-ansi "^4.0.0"
 
+"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+  version "4.2.3"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+  dependencies:
+    emoji-regex "^8.0.0"
+    is-fullwidth-code-point "^3.0.0"
+    strip-ansi "^6.0.1"
+
 string-width@^3.0.0, string-width@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
@@ -18679,15 +18726,6 @@ string-width@^3.0.0, string-width@^3.1.0:
     is-fullwidth-code-point "^2.0.0"
     strip-ansi "^5.1.0"
 
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
-  version "4.2.3"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
-  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
-  dependencies:
-    emoji-regex "^8.0.0"
-    is-fullwidth-code-point "^3.0.0"
-    strip-ansi "^6.0.1"
-
 string.prototype.matchall@^4.0.5:
   version "4.0.5"
   resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da"
@@ -21189,6 +21227,13 @@ wide-align@^1.1.0:
   dependencies:
     string-width "^1.0.2 || 2"
 
+wide-align@^1.1.2:
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3"
+  integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==
+  dependencies:
+    string-width "^1.0.2 || 2 || 3 || 4"
+
 widest-line@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc"