[DURACOM-303] adapt solution to older version of angular

This commit is contained in:
FrancescoMolinaro
2025-01-24 18:26:28 +01:00
parent 483b97d9c1
commit 990f00b129
22 changed files with 82 additions and 78 deletions

View File

@@ -111,7 +111,7 @@
"ngx-infinite-scroll": "^15.0.0", "ngx-infinite-scroll": "^15.0.0",
"ngx-pagination": "6.0.3", "ngx-pagination": "6.0.3",
"ngx-sortablejs": "^11.1.0", "ngx-sortablejs": "^11.1.0",
"ngx-skeleton-loader": "^9.0.0", "ngx-skeleton-loader": "^7.0.0",
"ngx-ui-switch": "^14.1.0", "ngx-ui-switch": "^14.1.0",
"nouislider": "^15.8.1", "nouislider": "^15.8.1",
"pem": "1.14.8", "pem": "1.14.8",

View File

@@ -24,8 +24,8 @@ import { APP_CONFIG } from '../../../config/app-config.interface';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { SortDirection } from '../../core/cache/models/sort-options.model'; import { SortDirection } from '../../core/cache/models/sort-options.model';
import { cold } from 'jasmine-marbles'; import { cold } from 'jasmine-marbles';
import { Store } from "@ngrx/store"; import { Store } from '@ngrx/store';
import { BrowseEntry } from "../../core/shared/browse-entry.model"; import { BrowseEntry } from '../../core/shared/browse-entry.model';
describe('BrowseByDatePageComponent', () => { describe('BrowseByDatePageComponent', () => {
let comp: BrowseByDatePageComponent; let comp: BrowseByDatePageComponent;

View File

@@ -19,8 +19,8 @@ import { APP_CONFIG, AppConfig } from '../../../config/app-config.interface';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { isPlatformServer } from "@angular/common"; import { isPlatformServer } from '@angular/common';
import { environment } from "../../../environments/environment"; import { environment } from '../../../environments/environment';
@Component({ @Component({
selector: 'ds-browse-by-date-page', selector: 'ds-browse-by-date-page',

View File

@@ -22,8 +22,8 @@ import { Collection } from '../../core/shared/collection.model';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { APP_CONFIG, AppConfig } from '../../../config/app-config.interface'; import { APP_CONFIG, AppConfig } from '../../../config/app-config.interface';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { isPlatformServer } from "@angular/common"; import { isPlatformServer } from '@angular/common';
import { environment } from "../../../environments/environment"; import { environment } from '../../../environments/environment';
export const BBM_PAGINATION_ID = 'bbm'; export const BBM_PAGINATION_ID = 'bbm';

View File

@@ -22,7 +22,7 @@ import { PaginationService } from '../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { APP_CONFIG } from '../../../config/app-config.interface'; import { APP_CONFIG } from '../../../config/app-config.interface';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { BrowseEntry } from "../../core/shared/browse-entry.model"; import { BrowseEntry } from '../../core/shared/browse-entry.model';
describe('BrowseByTitlePageComponent', () => { describe('BrowseByTitlePageComponent', () => {

View File

@@ -15,8 +15,8 @@ import { of as observableOf } from 'rxjs';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface'; import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { isPlatformServer } from "@angular/common"; import { isPlatformServer } from '@angular/common';
import { environment } from "../../../environments/environment"; import { environment } from '../../../environments/environment';
@Component({ @Component({
selector: 'ds-browse-by-title-page', selector: 'ds-browse-by-title-page',

View File

@@ -93,7 +93,9 @@ export class SearchFilterComponent implements OnInit {
*/ */
ngOnInit() { ngOnInit() {
this.selectedValues$ = this.getSelectedValues(); this.selectedValues$ = this.getSelectedValues();
this.active$ = this.isActive(); this.active$ = this.isActive().pipe(
startWith(true)
);
this.collapsed$ = this.isCollapsed(); this.collapsed$ = this.isCollapsed();
this.initializeFilter(); this.initializeFilter();
this.selectedValues$.pipe(take(1)).subscribe((selectedValues) => { this.selectedValues$.pipe(take(1)).subscribe((selectedValues) => {
@@ -101,9 +103,9 @@ export class SearchFilterComponent implements OnInit {
this.filterService.expand(this.filter.name); this.filterService.expand(this.filter.name);
} }
}); });
this.active$.pipe(take(1)).subscribe(() => { this.isActive().pipe(take(1)).subscribe(() => {
this.isVisibilityComputed.emit(true); this.isVisibilityComputed.emit(true);
}) });
} }
/** /**
@@ -192,7 +194,7 @@ export class SearchFilterComponent implements OnInit {
} }
)); ));
} }
}), })
startWith(true)); );
} }
} }

View File

@@ -1,6 +1,7 @@
<h3>{{"search.filters.head" | translate}}</h3> <h3>{{"search.filters.head" | translate}}</h3>
<div *ngIf="(filters | async)?.hasSucceeded"> <div *ngIf="(filters | async)?.hasSucceeded">
<div *ngFor="let filter of (filters | async)?.payload; trackBy: trackUpdate"> <div [class.visually-hidden]="filtersWithComputedVisibility !== (filters | async)?.payload?.length"
*ngFor="let filter of (filters | async)?.payload; trackBy: trackUpdate">
<ds-search-filter (isVisibilityComputed)="countFiltersWithComputedVisibility($event)" [scope]="currentScope" [filter]="filter" [inPlaceSearch]="inPlaceSearch" [refreshFilters]="refreshFilters"></ds-search-filter> <ds-search-filter (isVisibilityComputed)="countFiltersWithComputedVisibility($event)" [scope]="currentScope" [filter]="filter" [inPlaceSearch]="inPlaceSearch" [refreshFilters]="refreshFilters"></ds-search-filter>
</div> </div>
</div> </div>

View File

@@ -9,8 +9,8 @@ import { SearchFiltersComponent } from './search-filters.component';
import { SearchService } from '../../../core/shared/search/search.service'; import { SearchService } from '../../../core/shared/search/search.service';
import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component';
import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub';
import { APP_CONFIG } from "../../../../config/app-config.interface"; import { APP_CONFIG } from '../../../../config/app-config.interface';
import { environment } from "../../../../environments/environment"; import { environment } from '../../../../environments/environment';
describe('SearchFiltersComponent', () => { describe('SearchFiltersComponent', () => {
let comp: SearchFiltersComponent; let comp: SearchFiltersComponent;

View File

@@ -2,7 +2,7 @@ import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map, tap } from 'rxjs/operators';
import { SearchService } from '../../../core/shared/search/search.service'; import { SearchService } from '../../../core/shared/search/search.service';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
@@ -12,7 +12,7 @@ import { SearchFilterService } from '../../../core/shared/search/search-filter.s
import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component';
import { currentPath } from '../../utils/route.utils'; import { currentPath } from '../../utils/route.utils';
import { hasValue } from '../../empty.util'; import { hasValue } from '../../empty.util';
import { APP_CONFIG, AppConfig } from "../../../../config/app-config.interface"; import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface';
@Component({ @Component({
selector: 'ds-search-filters', selector: 'ds-search-filters',
@@ -88,10 +88,13 @@ export class SearchFiltersComponent implements OnInit, OnDestroy {
} }
ngOnInit(): void { ngOnInit(): void {
this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe(map((filters) => { this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe(
tap(() => this.filtersWithComputedVisibility = 0),
map((filters) => {
Object.keys(filters).forEach((f) => filters[f] = null); Object.keys(filters).forEach((f) => filters[f] = null);
return filters; return filters;
})); })
);
this.searchLink = this.getSearchLink(); this.searchLink = this.getSearchLink();
} }

View File

@@ -4,16 +4,14 @@
</div> </div>
</div> </div>
@if((viewMode$ | async) === ViewMode.ListElement) { <ng-container *ngIf="(viewMode$ | async) === ViewMode.ListElement; else grid">
@for (result of loadingResults; track result; let first = $first) { <ng-container *ngFor="let result of loadingResults; let first = $first">
<div [class.my-4]="!first" class="row"> <div [class.my-4]="!first" class="row">
@if(showThumbnails) { <div *ngIf="showThumbnails" class="col-3 col-md-2">
<div class="col-3 col-md-2">
<div class="thumbnail-skeleton position-relative"> <div class="thumbnail-skeleton position-relative">
<ngx-skeleton-loader/> <ngx-skeleton-loader/>
</div> </div>
</div> </div>
}
<div [class.col-9]="showThumbnails" [class.col-md-10]="showThumbnails" [class.col-md-12]="!showThumbnails"> <div [class.col-9]="showThumbnails" [class.col-md-10]="showThumbnails" [class.col-md-12]="!showThumbnails">
<div class="badge-skeleton"> <div class="badge-skeleton">
<ngx-skeleton-loader/> <ngx-skeleton-loader/>
@@ -23,16 +21,18 @@
</div> </div>
</div> </div>
</div> </div>
} </ng-container>
} @else if ((viewMode$ | async) === ViewMode.GridElement) { </ng-container>
<ng-template #grid>
<div class="card-columns row"> <div class="card-columns row">
@for (result of loadingResults; track result) { <ng-container *ngFor="let result of loadingResults">
<div class="card-column col col-sm-6 col-lg-4"> <div class="card-column col col-sm-6 col-lg-4">
<div class="card-skeleton"> <div class="card-skeleton">
<ngx-skeleton-loader/> <ngx-skeleton-loader/>
</div> </div>
</div> </div>
} </ng-container>
</div> </div>
} </ng-template>

View File

@@ -1,13 +1,8 @@
import {
AsyncPipe,
NgForOf,
} from '@angular/common';
import { import {
Component, Component,
Input, Input,
OnInit, OnInit,
} from '@angular/core'; } from '@angular/core';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { SearchService } from '../../../../core/shared/search/search.service'; import { SearchService } from '../../../../core/shared/search/search.service';
@@ -16,14 +11,8 @@ import { hasValue } from '../../../empty.util';
@Component({ @Component({
selector: 'ds-search-results-skeleton', selector: 'ds-search-results-skeleton',
standalone: true,
imports: [
NgxSkeletonLoaderModule,
AsyncPipe,
NgForOf,
],
templateUrl: './search-results-skeleton.component.html', templateUrl: './search-results-skeleton.component.html',
styleUrl: './search-results-skeleton.component.scss', styleUrls: ['./search-results-skeleton.component.scss'],
}) })
/** /**
* Component to show placeholders for search results while loading, to give a loading feedback to the user without layout shifting. * Component to show placeholders for search results while loading, to give a loading feedback to the user without layout shifting.

View File

@@ -1,15 +1,3 @@
@if ((activeFilters$ | async).length > 0 && (appliedFilters$ | async).length === 0) {
<div class="row">
<div class="col-12">
<div class="filters-badge-skeleton-container">
<div class="filter-badge-skeleton">
<ngx-skeleton-loader [count]="(activeFilters$ | async).length" />
</div>
</div>
</div>
</div>
}
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<h1 *ngIf="!disableHeader">{{ (configuration ? configuration + '.search.results.head' : 'search.results.head') | translate }}</h1> <h1 *ngIf="!disableHeader">{{ (configuration ? configuration + '.search.results.head' : 'search.results.head') | translate }}</h1>
<ds-search-export-csv *ngIf="showCsvExport" [searchConfig]="searchConfig"></ds-search-export-csv> <ds-search-export-csv *ngIf="showCsvExport" [searchConfig]="searchConfig"></ds-search-export-csv>

View File

@@ -7,7 +7,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { SearchResultsComponent } from './search-results.component'; import { SearchResultsComponent } from './search-results.component';
import { QueryParamsDirectiveStub } from '../../testing/query-params-directive.stub'; import { QueryParamsDirectiveStub } from '../../testing/query-params-directive.stub';
import { createFailedRemoteDataObject } from '../../remote-data.utils'; import { createFailedRemoteDataObject } from '../../remote-data.utils';
import { SearchResultsSkeletonComponent } from "./search-results-skeleton/search-results-skeleton.component"; import { SearchResultsSkeletonComponent } from './search-results-skeleton/search-results-skeleton.component';
describe('SearchResultsComponent', () => { describe('SearchResultsComponent', () => {
let comp: SearchResultsComponent; let comp: SearchResultsComponent;

View File

@@ -11,10 +11,10 @@ import { CollectionElementLinkType } from '../../object-collection/collection-el
import { ViewMode } from '../../../core/shared/view-mode.model'; import { ViewMode } from '../../../core/shared/view-mode.model';
import { Context } from '../../../core/shared/context.model'; import { Context } from '../../../core/shared/context.model';
import { PaginatedSearchOptions } from '../models/paginated-search-options.model'; import { PaginatedSearchOptions } from '../models/paginated-search-options.model';
import { SearchFilter } from "../models/search-filter.model"; import { SearchFilter } from '../models/search-filter.model';
import { Observable } from "rxjs"; import { Observable } from 'rxjs';
import { SearchConfigurationService } from "../../../core/shared/search/search-configuration.service"; import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
import { SearchService } from "../../../core/shared/search/search.service"; import { SearchService } from '../../../core/shared/search/search.service';
export interface SelectionConfig { export interface SelectionConfig {
repeatable: boolean; repeatable: boolean;

View File

@@ -48,7 +48,7 @@ import { ITEM_MODULE_PATH } from '../../item-page/item-page-routing-paths';
import { COLLECTION_MODULE_PATH } from '../../collection-page/collection-page-routing-paths'; import { COLLECTION_MODULE_PATH } from '../../collection-page/collection-page-routing-paths';
import { COMMUNITY_MODULE_PATH } from '../../community-page/community-page-routing-paths'; import { COMMUNITY_MODULE_PATH } from '../../community-page/community-page-routing-paths';
import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface'; import { AppConfig, APP_CONFIG } from '../../../config/app-config.interface';
import { isPlatformServer } from "@angular/common"; import { isPlatformServer } from '@angular/common';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@Component({ @Component({

View File

@@ -34,6 +34,10 @@ import { ThemedSearchSettingsComponent } from './search-settings/themed-search-s
import { NouisliderModule } from 'ng2-nouislider'; import { NouisliderModule } from 'ng2-nouislider';
import { ThemedSearchFiltersComponent } from './search-filters/themed-search-filters.component'; import { ThemedSearchFiltersComponent } from './search-filters/themed-search-filters.component';
import { ThemedSearchSidebarComponent } from './search-sidebar/themed-search-sidebar.component'; import { ThemedSearchSidebarComponent } from './search-sidebar/themed-search-sidebar.component';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import {
SearchResultsSkeletonComponent
} from './search-results/search-results-skeleton/search-results-skeleton.component';
const COMPONENTS = [ const COMPONENTS = [
SearchComponent, SearchComponent,
@@ -62,6 +66,7 @@ const COMPONENTS = [
ThemedSearchSettingsComponent, ThemedSearchSettingsComponent,
ThemedSearchFiltersComponent, ThemedSearchFiltersComponent,
ThemedSearchSidebarComponent, ThemedSearchSidebarComponent,
SearchResultsSkeletonComponent
]; ];
const ENTRY_COMPONENTS = [ const ENTRY_COMPONENTS = [
@@ -74,6 +79,7 @@ const ENTRY_COMPONENTS = [
SearchFacetSelectedOptionComponent, SearchFacetSelectedOptionComponent,
SearchFacetRangeOptionComponent, SearchFacetRangeOptionComponent,
SearchAuthorityFilterComponent, SearchAuthorityFilterComponent,
SearchResultsSkeletonComponent
]; ];
/** /**
@@ -93,11 +99,12 @@ export const MODELS = [
imports: [ imports: [
CommonModule, CommonModule,
TranslateModule.forChild({ TranslateModule.forChild({
missingTranslationHandler: { provide: MissingTranslationHandler, useClass: MissingTranslationHelper }, missingTranslationHandler: {provide: MissingTranslationHandler, useClass: MissingTranslationHelper},
useDefaultLang: true useDefaultLang: true
}), }),
SharedModule.withEntryComponents(), SharedModule.withEntryComponents(),
NouisliderModule, NouisliderModule,
NgxSkeletonLoaderModule,
], ],
exports: [ exports: [
...COMPONENTS ...COMPONENTS

View File

@@ -23,7 +23,7 @@ import { MarkdownConfig } from './markdown-config.interface';
import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { FilterVocabularyConfig } from './filter-vocabulary-config';
import { DiscoverySortConfig } from './discovery-sort.config'; import { DiscoverySortConfig } from './discovery-sort.config';
import { LiveRegionConfig } from '../app/shared/live-region/live-region.config'; import { LiveRegionConfig } from '../app/shared/live-region/live-region.config';
import { SearchConfig } from "./search-page-config.interface"; import { SearchConfig } from './search-page-config.interface';
interface AppConfig extends Config { interface AppConfig extends Config {
ui: UIServerConfig; ui: UIServerConfig;

View File

@@ -23,7 +23,7 @@ import { MarkdownConfig } from './markdown-config.interface';
import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { FilterVocabularyConfig } from './filter-vocabulary-config';
import { DiscoverySortConfig } from './discovery-sort.config'; import { DiscoverySortConfig } from './discovery-sort.config';
import { LiveRegionConfig } from '../app/shared/live-region/live-region.config'; import { LiveRegionConfig } from '../app/shared/live-region/live-region.config';
import { SearchConfig } from "./search-page-config.interface"; import { SearchConfig } from './search-page-config.interface';
export class DefaultAppConfig implements AppConfig { export class DefaultAppConfig implements AppConfig {
production = false; production = false;
@@ -446,5 +446,5 @@ export class DefaultAppConfig implements AppConfig {
search: SearchConfig = { search: SearchConfig = {
filterPlaceholdersCount: 5 filterPlaceholdersCount: 5
} };
} }

View File

@@ -325,6 +325,6 @@ export const environment: BuildConfig = {
}, },
search: { search: {
defaultFilterCount: 5 filterPlaceholdersCount: 5
} }
}; };

View File

@@ -159,9 +159,8 @@ import { RequestCopyModule } from 'src/app/request-copy/request-copy.module';
import {UserMenuComponent} from './app/shared/auth-nav-menu/user-menu/user-menu.component'; import {UserMenuComponent} from './app/shared/auth-nav-menu/user-menu/user-menu.component';
import { BrowseByComponent } from './app/shared/browse-by/browse-by.component'; import { BrowseByComponent } from './app/shared/browse-by/browse-by.component';
import { RegisterEmailFormComponent } from './app/register-email-form/register-email-form.component'; import { RegisterEmailFormComponent } from './app/register-email-form/register-email-form.component';
import { import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
SearchResultsSkeletonComponent
} from "../../app/shared/search/search-results/search-results-skeleton/search-results-skeleton.component";
const DECLARATIONS = [ const DECLARATIONS = [
FileSectionComponent, FileSectionComponent,
@@ -248,7 +247,6 @@ const DECLARATIONS = [
UserMenuComponent, UserMenuComponent,
BrowseByComponent, BrowseByComponent,
RegisterEmailFormComponent, RegisterEmailFormComponent,
SearchResultsSkeletonComponent,
]; ];
@NgModule({ @NgModule({
@@ -309,6 +307,7 @@ const DECLARATIONS = [
NgxGalleryModule, NgxGalleryModule,
FormModule, FormModule,
RequestCopyModule, RequestCopyModule,
NgxSkeletonLoaderModule
], ],
declarations: DECLARATIONS, declarations: DECLARATIONS,
exports: [ exports: [

View File

@@ -8415,6 +8415,14 @@ ngx-pagination@6.0.3:
dependencies: dependencies:
tslib "^2.3.0" tslib "^2.3.0"
ngx-skeleton-loader@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/ngx-skeleton-loader/-/ngx-skeleton-loader-7.0.0.tgz#3b1325025a7208a20f3a0fdba6e578532a09cfcd"
integrity sha512-myc6GNcNhyksZrimIFkCxeihi0kQ8JhQVZiGbtiIv4gYrnnRk5nXbs3kYitK8E8OstHG+jlsmRofqGBxuIsYTA==
dependencies:
perf-marks "^1.13.4"
tslib "^2.0.0"
ngx-sortablejs@^11.1.0: ngx-sortablejs@^11.1.0:
version "11.1.0" version "11.1.0"
resolved "https://registry.npmjs.org/ngx-sortablejs/-/ngx-sortablejs-11.1.0.tgz" resolved "https://registry.npmjs.org/ngx-sortablejs/-/ngx-sortablejs-11.1.0.tgz"
@@ -9060,6 +9068,13 @@ pend@~1.2.0:
resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
perf-marks@^1.13.4:
version "1.14.2"
resolved "https://registry.yarnpkg.com/perf-marks/-/perf-marks-1.14.2.tgz#7511c24239b9c2071717993a33ec3057f387b8c7"
integrity sha512-N0/bQcuTlETpgox/DsXS1voGjqaoamMoiyhncgeW3rSHy/qw8URVgmPRYfFDQns/+C6yFUHDbeSBGL7ixT6Y4A==
dependencies:
tslib "^2.1.0"
performance-now@^2.1.0: performance-now@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz"